feat: payload cms
This commit is contained in:
285
src/migrations/20260225_175000_native_localization.ts
Normal file
285
src/migrations/20260225_175000_native_localization.ts
Normal file
@@ -0,0 +1,285 @@
|
||||
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres';
|
||||
|
||||
/**
|
||||
* Migration: native_localization
|
||||
*
|
||||
* Transforms the existing schema (manual `locale` select column on each row)
|
||||
* into Payload's native localization join-table structure.
|
||||
*
|
||||
* Each statement is a separate db.execute call to avoid Drizzle multi-statement issues.
|
||||
*/
|
||||
export async function up({ db }: MigrateUpArgs): Promise<void> {
|
||||
// ── 1. Global locale enum ────────────────────────────────────────────────────
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."enum__locales" AS ENUM('de', 'en');
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."enum__posts_v_published_locale" AS ENUM('de', 'en');
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."enum__products_v_published_locale" AS ENUM('de', 'en');
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."enum__pages_v_published_locale" AS ENUM('de', 'en');
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."enum_pages_layout" AS ENUM('default', 'fullBleed');
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."enum__pages_v_version_layout" AS ENUM('default', 'fullBleed');
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."enum__pages_v_version_status" AS ENUM('draft', 'published');
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."enum__posts_v_version_status" AS ENUM('draft', 'published');
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."enum__products_v_version_status" AS ENUM('draft', 'published');
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
|
||||
// ── 2. Alter pages table ─────────────────────────────────────────────────────
|
||||
await db.execute(sql`ALTER TABLE "pages" ADD COLUMN IF NOT EXISTS "layout" "enum_pages_layout" DEFAULT 'default'`);
|
||||
await db.execute(sql`ALTER TABLE "pages" ADD COLUMN IF NOT EXISTS "_status" "enum_pages_status" DEFAULT 'draft'`);
|
||||
|
||||
// ── 3. Create pages_locales join table ───────────────────────────────────────
|
||||
await db.execute(sql`
|
||||
CREATE TABLE IF NOT EXISTS "pages_locales" (
|
||||
"title" varchar,
|
||||
"slug" varchar,
|
||||
"excerpt" varchar,
|
||||
"content" jsonb,
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"_locale" "enum__locales" NOT NULL,
|
||||
"_parent_id" integer NOT NULL
|
||||
)
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "pages_locales" ADD CONSTRAINT "pages_locales_locale_parent_id_unique" UNIQUE("_locale", "_parent_id");
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "pages_locales" ADD CONSTRAINT "pages_locales_parent_id_fk"
|
||||
FOREIGN KEY ("_parent_id") REFERENCES "pages"("id") ON DELETE cascade;
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
|
||||
// ── 4. Backfill pages_locales from old pages rows ────────────────────────────
|
||||
await db.execute(sql`
|
||||
INSERT INTO "pages_locales" ("title", "slug", "excerpt", "content", "_locale", "_parent_id")
|
||||
SELECT
|
||||
p.title, p.slug, p.excerpt, p.content,
|
||||
CASE WHEN p.locale::text = 'de' THEN 'de'::"enum__locales" ELSE 'en'::"enum__locales" END,
|
||||
p.id
|
||||
FROM "pages" p
|
||||
WHERE p.locale IS NOT NULL
|
||||
ON CONFLICT ("_locale", "_parent_id") DO UPDATE
|
||||
SET "title" = EXCLUDED."title",
|
||||
"slug" = EXCLUDED."slug",
|
||||
"excerpt" = EXCLUDED."excerpt",
|
||||
"content" = EXCLUDED."content"
|
||||
`);
|
||||
|
||||
// ── 5. Drop old columns from pages ───────────────────────────────────────────
|
||||
await db.execute(sql`ALTER TABLE "pages" DROP COLUMN IF EXISTS "title"`);
|
||||
await db.execute(sql`ALTER TABLE "pages" DROP COLUMN IF EXISTS "slug"`);
|
||||
await db.execute(sql`ALTER TABLE "pages" DROP COLUMN IF EXISTS "excerpt"`);
|
||||
await db.execute(sql`ALTER TABLE "pages" DROP COLUMN IF EXISTS "content"`);
|
||||
await db.execute(sql`ALTER TABLE "pages" DROP COLUMN IF EXISTS "locale"`);
|
||||
|
||||
// ── 6. Create posts_locales join table ───────────────────────────────────────
|
||||
await db.execute(sql`
|
||||
CREATE TABLE IF NOT EXISTS "posts_locales" (
|
||||
"title" varchar,
|
||||
"slug" varchar,
|
||||
"excerpt" varchar,
|
||||
"category" varchar,
|
||||
"content" jsonb,
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"_locale" "enum__locales" NOT NULL,
|
||||
"_parent_id" integer NOT NULL
|
||||
)
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "posts_locales" ADD CONSTRAINT "posts_locales_locale_parent_id_unique" UNIQUE("_locale", "_parent_id");
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "posts_locales" ADD CONSTRAINT "posts_locales_parent_id_fk"
|
||||
FOREIGN KEY ("_parent_id") REFERENCES "posts"("id") ON DELETE cascade;
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
|
||||
// ── 7. Backfill posts_locales ────────────────────────────────────────────────
|
||||
await db.execute(sql`
|
||||
INSERT INTO "posts_locales" ("title", "slug", "excerpt", "category", "content", "_locale", "_parent_id")
|
||||
SELECT
|
||||
p.title, p.slug, p.excerpt, p.category, p.content,
|
||||
CASE WHEN p.locale::text = 'de' THEN 'de'::"enum__locales" ELSE 'en'::"enum__locales" END,
|
||||
p.id
|
||||
FROM "posts" p
|
||||
WHERE p.locale IS NOT NULL
|
||||
ON CONFLICT ("_locale", "_parent_id") DO UPDATE
|
||||
SET "title" = EXCLUDED."title",
|
||||
"slug" = EXCLUDED."slug",
|
||||
"excerpt" = EXCLUDED."excerpt",
|
||||
"category" = EXCLUDED."category",
|
||||
"content" = EXCLUDED."content"
|
||||
`);
|
||||
|
||||
// ── 8. Drop old columns from posts ───────────────────────────────────────────
|
||||
await db.execute(sql`ALTER TABLE "posts" DROP COLUMN IF EXISTS "title"`);
|
||||
await db.execute(sql`ALTER TABLE "posts" DROP COLUMN IF EXISTS "slug"`);
|
||||
await db.execute(sql`ALTER TABLE "posts" DROP COLUMN IF EXISTS "excerpt"`);
|
||||
await db.execute(sql`ALTER TABLE "posts" DROP COLUMN IF EXISTS "category"`);
|
||||
await db.execute(sql`ALTER TABLE "posts" DROP COLUMN IF EXISTS "content"`);
|
||||
await db.execute(sql`ALTER TABLE "posts" DROP COLUMN IF EXISTS "locale"`);
|
||||
|
||||
// ── 9. Create products_locales join table ────────────────────────────────────
|
||||
await db.execute(sql`
|
||||
CREATE TABLE IF NOT EXISTS "products_locales" (
|
||||
"title" varchar,
|
||||
"description" varchar,
|
||||
"application" jsonb,
|
||||
"content" jsonb,
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"_locale" "enum__locales" NOT NULL,
|
||||
"_parent_id" integer NOT NULL
|
||||
)
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "products_locales" ADD CONSTRAINT "products_locales_locale_parent_id_unique" UNIQUE("_locale", "_parent_id");
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "products_locales" ADD CONSTRAINT "products_locales_parent_id_fk"
|
||||
FOREIGN KEY ("_parent_id") REFERENCES "products"("id") ON DELETE cascade;
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
|
||||
// ── 10. Backfill products_locales ────────────────────────────────────────────
|
||||
// Products were separate DE/EN rows — each becomes a locale entry on its own id
|
||||
await db.execute(sql`
|
||||
INSERT INTO "products_locales" ("title", "description", "application", "content", "_locale", "_parent_id")
|
||||
SELECT
|
||||
p.title, p.description, p.application, p.content,
|
||||
CASE WHEN p.locale::text = 'de' THEN 'de'::"enum__locales" ELSE 'en'::"enum__locales" END,
|
||||
p.id
|
||||
FROM "products" p
|
||||
WHERE p.locale IS NOT NULL
|
||||
ON CONFLICT ("_locale", "_parent_id") DO NOTHING
|
||||
`);
|
||||
|
||||
// ── 11. Drop old columns from products ───────────────────────────────────────
|
||||
await db.execute(sql`ALTER TABLE "products" DROP COLUMN IF EXISTS "title"`);
|
||||
await db.execute(sql`ALTER TABLE "products" DROP COLUMN IF EXISTS "description"`);
|
||||
await db.execute(sql`ALTER TABLE "products" DROP COLUMN IF EXISTS "application"`);
|
||||
await db.execute(sql`ALTER TABLE "products" DROP COLUMN IF EXISTS "content"`);
|
||||
await db.execute(sql`ALTER TABLE "products" DROP COLUMN IF EXISTS "locale"`);
|
||||
|
||||
// ── 12. Version tables (_posts_v, _products_v, _pages_v) locale columns ──────
|
||||
await db.execute(sql`ALTER TABLE "_posts_v" ADD COLUMN IF NOT EXISTS "published_locale" "enum__posts_v_published_locale"`);
|
||||
await db.execute(sql`ALTER TABLE "_products_v" ADD COLUMN IF NOT EXISTS "published_locale" "enum__products_v_published_locale"`);
|
||||
await db.execute(sql`ALTER TABLE "_pages_v" ADD COLUMN IF NOT EXISTS "published_locale" "enum__pages_v_published_locale"`);
|
||||
|
||||
// ── 13. Create _posts_v_locales ──────────────────────────────────────────────
|
||||
await db.execute(sql`
|
||||
CREATE TABLE IF NOT EXISTS "_posts_v_locales" (
|
||||
"version_title" varchar, "version_slug" varchar, "version_excerpt" varchar,
|
||||
"version_category" varchar, "version_content" jsonb,
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"_locale" "enum__locales" NOT NULL, "_parent_id" integer NOT NULL
|
||||
)
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_posts_v_locales" ADD CONSTRAINT "_posts_v_locales_locale_parent_id_unique" UNIQUE("_locale", "_parent_id");
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_posts_v_locales" ADD CONSTRAINT "_posts_v_locales_parent_id_fk"
|
||||
FOREIGN KEY ("_parent_id") REFERENCES "_posts_v"("id") ON DELETE cascade;
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
|
||||
// ── 14. Create _products_v_locales ───────────────────────────────────────────
|
||||
await db.execute(sql`
|
||||
CREATE TABLE IF NOT EXISTS "_products_v_locales" (
|
||||
"version_title" varchar, "version_description" varchar,
|
||||
"version_application" jsonb, "version_content" jsonb,
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"_locale" "enum__locales" NOT NULL, "_parent_id" integer NOT NULL
|
||||
)
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_products_v_locales" ADD CONSTRAINT "_products_v_locales_locale_parent_id_unique" UNIQUE("_locale", "_parent_id");
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_products_v_locales" ADD CONSTRAINT "_products_v_locales_parent_id_fk"
|
||||
FOREIGN KEY ("_parent_id") REFERENCES "_products_v"("id") ON DELETE cascade;
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
|
||||
// ── 15. Create _pages_v_locales ──────────────────────────────────────────────
|
||||
await db.execute(sql`
|
||||
CREATE TABLE IF NOT EXISTS "_pages_v_locales" (
|
||||
"version_title" varchar, "version_slug" varchar,
|
||||
"version_excerpt" varchar, "version_content" jsonb,
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"_locale" "enum__locales" NOT NULL, "_parent_id" integer NOT NULL
|
||||
)
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_pages_v_locales" ADD CONSTRAINT "_pages_v_locales_locale_parent_id_unique" UNIQUE("_locale", "_parent_id");
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
await db.execute(sql`
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_pages_v_locales" ADD CONSTRAINT "_pages_v_locales_parent_id_fk"
|
||||
FOREIGN KEY ("_parent_id") REFERENCES "_pages_v"("id") ON DELETE cascade;
|
||||
EXCEPTION WHEN duplicate_object THEN null; END $$
|
||||
`);
|
||||
|
||||
// ── 16. Drop the now-redundant old locale enum ───────────────────────────────
|
||||
await db.execute(sql`DROP TYPE IF EXISTS "public"."enum_pages_locale"`);
|
||||
await db.execute(sql`DROP TYPE IF EXISTS "public"."enum_posts_locale"`);
|
||||
await db.execute(sql`DROP TYPE IF EXISTS "public"."enum_products_locale"`);
|
||||
}
|
||||
|
||||
export async function down({ db }: MigrateDownArgs): Promise<void> {
|
||||
await db.execute(sql`DROP TABLE IF EXISTS "pages_locales" CASCADE`);
|
||||
await db.execute(sql`DROP TABLE IF EXISTS "_pages_v_locales" CASCADE`);
|
||||
await db.execute(sql`DROP TABLE IF EXISTS "posts_locales" CASCADE`);
|
||||
await db.execute(sql`DROP TABLE IF EXISTS "_posts_v_locales" CASCADE`);
|
||||
await db.execute(sql`DROP TABLE IF EXISTS "products_locales" CASCADE`);
|
||||
await db.execute(sql`DROP TABLE IF EXISTS "_products_v_locales" CASCADE`);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as migration_20260223_195005_products_collection from './20260223_195005_products_collection';
|
||||
import * as migration_20260223_195151_remove_sku_unique from './20260223_195151_remove_sku_unique';
|
||||
import * as migration_20260225_003500_add_pages_collection from './20260225_003500_add_pages_collection';
|
||||
import * as migration_20260225_175000_native_localization from './20260225_175000_native_localization';
|
||||
|
||||
export const migrations = [
|
||||
{
|
||||
@@ -18,4 +19,9 @@ export const migrations = [
|
||||
down: migration_20260225_003500_add_pages_collection.down,
|
||||
name: '20260225_003500_add_pages_collection',
|
||||
},
|
||||
{
|
||||
up: migration_20260225_175000_native_localization.up,
|
||||
down: migration_20260225_175000_native_localization.down,
|
||||
name: '20260225_175000_native_localization',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -22,27 +22,43 @@ import {
|
||||
pgEnum,
|
||||
} from '@payloadcms/db-postgres/drizzle/pg-core';
|
||||
import { sql, relations } from '@payloadcms/db-postgres/drizzle';
|
||||
export const enum_posts_locale = pgEnum('enum_posts_locale', ['en', 'de']);
|
||||
export const enum__locales = pgEnum('enum__locales', ['de', 'en']);
|
||||
export const enum_posts_status = pgEnum('enum_posts_status', ['draft', 'published']);
|
||||
export const enum__posts_v_version_locale = pgEnum('enum__posts_v_version_locale', ['en', 'de']);
|
||||
export const enum__posts_v_version_status = pgEnum('enum__posts_v_version_status', [
|
||||
'draft',
|
||||
'published',
|
||||
]);
|
||||
export const enum__posts_v_published_locale = pgEnum('enum__posts_v_published_locale', [
|
||||
'de',
|
||||
'en',
|
||||
]);
|
||||
export const enum_form_submissions_type = pgEnum('enum_form_submissions_type', [
|
||||
'contact',
|
||||
'product_quote',
|
||||
]);
|
||||
export const enum_products_locale = pgEnum('enum_products_locale', ['en', 'de']);
|
||||
export const enum_products_status = pgEnum('enum_products_status', ['draft', 'published']);
|
||||
export const enum__products_v_version_locale = pgEnum('enum__products_v_version_locale', [
|
||||
'en',
|
||||
'de',
|
||||
]);
|
||||
export const enum__products_v_version_status = pgEnum('enum__products_v_version_status', [
|
||||
'draft',
|
||||
'published',
|
||||
]);
|
||||
export const enum__products_v_published_locale = pgEnum('enum__products_v_published_locale', [
|
||||
'de',
|
||||
'en',
|
||||
]);
|
||||
export const enum_pages_layout = pgEnum('enum_pages_layout', ['default', 'fullBleed']);
|
||||
export const enum_pages_status = pgEnum('enum_pages_status', ['draft', 'published']);
|
||||
export const enum__pages_v_version_layout = pgEnum('enum__pages_v_version_layout', [
|
||||
'default',
|
||||
'fullBleed',
|
||||
]);
|
||||
export const enum__pages_v_version_status = pgEnum('enum__pages_v_version_status', [
|
||||
'draft',
|
||||
'published',
|
||||
]);
|
||||
export const enum__pages_v_published_locale = pgEnum('enum__pages_v_published_locale', [
|
||||
'de',
|
||||
'en',
|
||||
]);
|
||||
|
||||
export const users_sessions = pgTable(
|
||||
'users_sessions',
|
||||
@@ -130,18 +146,12 @@ export const media = pgTable(
|
||||
sizes_card_mimeType: varchar('sizes_card_mime_type'),
|
||||
sizes_card_filesize: numeric('sizes_card_filesize', { mode: 'number' }),
|
||||
sizes_card_filename: varchar('sizes_card_filename'),
|
||||
sizes_hero_url: varchar('sizes_hero_url'),
|
||||
sizes_hero_width: numeric('sizes_hero_width', { mode: 'number' }),
|
||||
sizes_hero_height: numeric('sizes_hero_height', { mode: 'number' }),
|
||||
sizes_hero_mimeType: varchar('sizes_hero_mime_type'),
|
||||
sizes_hero_filesize: numeric('sizes_hero_filesize', { mode: 'number' }),
|
||||
sizes_hero_filename: varchar('sizes_hero_filename'),
|
||||
sizes_hero_mobile_url: varchar('sizes_hero_mobile_url'),
|
||||
sizes_hero_mobile_width: numeric('sizes_hero_mobile_width', { mode: 'number' }),
|
||||
sizes_hero_mobile_height: numeric('sizes_hero_mobile_height', { mode: 'number' }),
|
||||
sizes_hero_mobile_mimeType: varchar('sizes_hero_mobile_mime_type'),
|
||||
sizes_hero_mobile_filesize: numeric('sizes_hero_mobile_filesize', { mode: 'number' }),
|
||||
sizes_hero_mobile_filename: varchar('sizes_hero_mobile_filename'),
|
||||
sizes_tablet_url: varchar('sizes_tablet_url'),
|
||||
sizes_tablet_width: numeric('sizes_tablet_width', { mode: 'number' }),
|
||||
sizes_tablet_height: numeric('sizes_tablet_height', { mode: 'number' }),
|
||||
sizes_tablet_mimeType: varchar('sizes_tablet_mime_type'),
|
||||
sizes_tablet_filesize: numeric('sizes_tablet_filesize', { mode: 'number' }),
|
||||
sizes_tablet_filename: varchar('sizes_tablet_filename'),
|
||||
},
|
||||
(columns) => [
|
||||
index('media_updated_at_idx').on(columns.updatedAt),
|
||||
@@ -151,10 +161,7 @@ export const media = pgTable(
|
||||
columns.sizes_thumbnail_filename,
|
||||
),
|
||||
index('media_sizes_card_sizes_card_filename_idx').on(columns.sizes_card_filename),
|
||||
index('media_sizes_hero_sizes_hero_filename_idx').on(columns.sizes_hero_filename),
|
||||
index('media_sizes_hero_mobile_sizes_hero_mobile_filename_idx').on(
|
||||
columns.sizes_hero_mobile_filename,
|
||||
),
|
||||
index('media_sizes_tablet_sizes_tablet_filename_idx').on(columns.sizes_tablet_filename),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -162,16 +169,10 @@ export const posts = pgTable(
|
||||
'posts',
|
||||
{
|
||||
id: serial('id').primaryKey(),
|
||||
title: varchar('title'),
|
||||
slug: varchar('slug'),
|
||||
excerpt: varchar('excerpt'),
|
||||
date: timestamp('date', { mode: 'string', withTimezone: true, precision: 3 }),
|
||||
featuredImage: integer('featured_image_id').references(() => media.id, {
|
||||
onDelete: 'set null',
|
||||
}),
|
||||
locale: enum_posts_locale('locale').default('en'),
|
||||
category: varchar('category'),
|
||||
content: jsonb('content'),
|
||||
updatedAt: timestamp('updated_at', { mode: 'string', withTimezone: true, precision: 3 })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
@@ -181,7 +182,6 @@ export const posts = pgTable(
|
||||
_status: enum_posts_status('_status').default('draft'),
|
||||
},
|
||||
(columns) => [
|
||||
uniqueIndex('posts_slug_idx').on(columns.slug),
|
||||
index('posts_featured_image_idx').on(columns.featuredImage),
|
||||
index('posts_updated_at_idx').on(columns.updatedAt),
|
||||
index('posts_created_at_idx').on(columns.createdAt),
|
||||
@@ -189,6 +189,28 @@ export const posts = pgTable(
|
||||
],
|
||||
);
|
||||
|
||||
export const posts_locales = pgTable(
|
||||
'posts_locales',
|
||||
{
|
||||
title: varchar('title'),
|
||||
slug: varchar('slug'),
|
||||
excerpt: varchar('excerpt'),
|
||||
category: varchar('category'),
|
||||
content: jsonb('content'),
|
||||
id: serial('id').primaryKey(),
|
||||
_locale: enum__locales('_locale').notNull(),
|
||||
_parentID: integer('_parent_id').notNull(),
|
||||
},
|
||||
(columns) => [
|
||||
uniqueIndex('posts_locales_locale_parent_id_unique').on(columns._locale, columns._parentID),
|
||||
foreignKey({
|
||||
columns: [columns['_parentID']],
|
||||
foreignColumns: [posts.id],
|
||||
name: 'posts_locales_parent_id_fk',
|
||||
}).onDelete('cascade'),
|
||||
],
|
||||
);
|
||||
|
||||
export const _posts_v = pgTable(
|
||||
'_posts_v',
|
||||
{
|
||||
@@ -196,16 +218,10 @@ export const _posts_v = pgTable(
|
||||
parent: integer('parent_id').references(() => posts.id, {
|
||||
onDelete: 'set null',
|
||||
}),
|
||||
version_title: varchar('version_title'),
|
||||
version_slug: varchar('version_slug'),
|
||||
version_excerpt: varchar('version_excerpt'),
|
||||
version_date: timestamp('version_date', { mode: 'string', withTimezone: true, precision: 3 }),
|
||||
version_featuredImage: integer('version_featured_image_id').references(() => media.id, {
|
||||
onDelete: 'set null',
|
||||
}),
|
||||
version_locale: enum__posts_v_version_locale('version_locale').default('en'),
|
||||
version_category: varchar('version_category'),
|
||||
version_content: jsonb('version_content'),
|
||||
version_updatedAt: timestamp('version_updated_at', {
|
||||
mode: 'string',
|
||||
withTimezone: true,
|
||||
@@ -223,21 +239,46 @@ export const _posts_v = pgTable(
|
||||
updatedAt: timestamp('updated_at', { mode: 'string', withTimezone: true, precision: 3 })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
snapshot: boolean('snapshot'),
|
||||
publishedLocale: enum__posts_v_published_locale('published_locale'),
|
||||
latest: boolean('latest'),
|
||||
},
|
||||
(columns) => [
|
||||
index('_posts_v_parent_idx').on(columns.parent),
|
||||
index('_posts_v_version_version_slug_idx').on(columns.version_slug),
|
||||
index('_posts_v_version_version_featured_image_idx').on(columns.version_featuredImage),
|
||||
index('_posts_v_version_version_updated_at_idx').on(columns.version_updatedAt),
|
||||
index('_posts_v_version_version_created_at_idx').on(columns.version_createdAt),
|
||||
index('_posts_v_version_version__status_idx').on(columns.version__status),
|
||||
index('_posts_v_created_at_idx').on(columns.createdAt),
|
||||
index('_posts_v_updated_at_idx').on(columns.updatedAt),
|
||||
index('_posts_v_snapshot_idx').on(columns.snapshot),
|
||||
index('_posts_v_published_locale_idx').on(columns.publishedLocale),
|
||||
index('_posts_v_latest_idx').on(columns.latest),
|
||||
],
|
||||
);
|
||||
|
||||
export const _posts_v_locales = pgTable(
|
||||
'_posts_v_locales',
|
||||
{
|
||||
version_title: varchar('version_title'),
|
||||
version_slug: varchar('version_slug'),
|
||||
version_excerpt: varchar('version_excerpt'),
|
||||
version_category: varchar('version_category'),
|
||||
version_content: jsonb('version_content'),
|
||||
id: serial('id').primaryKey(),
|
||||
_locale: enum__locales('_locale').notNull(),
|
||||
_parentID: integer('_parent_id').notNull(),
|
||||
},
|
||||
(columns) => [
|
||||
uniqueIndex('_posts_v_locales_locale_parent_id_unique').on(columns._locale, columns._parentID),
|
||||
foreignKey({
|
||||
columns: [columns['_parentID']],
|
||||
foreignColumns: [_posts_v.id],
|
||||
name: '_posts_v_locales_parent_id_fk',
|
||||
}).onDelete('cascade'),
|
||||
],
|
||||
);
|
||||
|
||||
export const form_submissions = pgTable(
|
||||
'form_submissions',
|
||||
{
|
||||
@@ -283,13 +324,11 @@ export const products = pgTable(
|
||||
'products',
|
||||
{
|
||||
id: serial('id').primaryKey(),
|
||||
title: varchar('title'),
|
||||
sku: varchar('sku'),
|
||||
slug: varchar('slug'),
|
||||
description: varchar('description'),
|
||||
locale: enum_products_locale('locale').default('de'),
|
||||
application: jsonb('application'),
|
||||
content: jsonb('content'),
|
||||
featuredImage: integer('featured_image_id').references(() => media.id, {
|
||||
onDelete: 'set null',
|
||||
}),
|
||||
updatedAt: timestamp('updated_at', { mode: 'string', withTimezone: true, precision: 3 })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
@@ -299,13 +338,34 @@ export const products = pgTable(
|
||||
_status: enum_products_status('_status').default('draft'),
|
||||
},
|
||||
(columns) => [
|
||||
uniqueIndex('products_sku_idx').on(columns.sku),
|
||||
index('products_featured_image_idx').on(columns.featuredImage),
|
||||
index('products_updated_at_idx').on(columns.updatedAt),
|
||||
index('products_created_at_idx').on(columns.createdAt),
|
||||
index('products__status_idx').on(columns._status),
|
||||
],
|
||||
);
|
||||
|
||||
export const products_locales = pgTable(
|
||||
'products_locales',
|
||||
{
|
||||
title: varchar('title'),
|
||||
description: varchar('description'),
|
||||
application: jsonb('application'),
|
||||
content: jsonb('content'),
|
||||
id: serial('id').primaryKey(),
|
||||
_locale: enum__locales('_locale').notNull(),
|
||||
_parentID: integer('_parent_id').notNull(),
|
||||
},
|
||||
(columns) => [
|
||||
uniqueIndex('products_locales_locale_parent_id_unique').on(columns._locale, columns._parentID),
|
||||
foreignKey({
|
||||
columns: [columns['_parentID']],
|
||||
foreignColumns: [products.id],
|
||||
name: 'products_locales_parent_id_fk',
|
||||
}).onDelete('cascade'),
|
||||
],
|
||||
);
|
||||
|
||||
export const products_rels = pgTable(
|
||||
'products_rels',
|
||||
{
|
||||
@@ -360,13 +420,11 @@ export const _products_v = pgTable(
|
||||
parent: integer('parent_id').references(() => products.id, {
|
||||
onDelete: 'set null',
|
||||
}),
|
||||
version_title: varchar('version_title'),
|
||||
version_sku: varchar('version_sku'),
|
||||
version_slug: varchar('version_slug'),
|
||||
version_description: varchar('version_description'),
|
||||
version_locale: enum__products_v_version_locale('version_locale').default('de'),
|
||||
version_application: jsonb('version_application'),
|
||||
version_content: jsonb('version_content'),
|
||||
version_featuredImage: integer('version_featured_image_id').references(() => media.id, {
|
||||
onDelete: 'set null',
|
||||
}),
|
||||
version_updatedAt: timestamp('version_updated_at', {
|
||||
mode: 'string',
|
||||
withTimezone: true,
|
||||
@@ -384,20 +442,48 @@ export const _products_v = pgTable(
|
||||
updatedAt: timestamp('updated_at', { mode: 'string', withTimezone: true, precision: 3 })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
snapshot: boolean('snapshot'),
|
||||
publishedLocale: enum__products_v_published_locale('published_locale'),
|
||||
latest: boolean('latest'),
|
||||
},
|
||||
(columns) => [
|
||||
index('_products_v_parent_idx').on(columns.parent),
|
||||
index('_products_v_version_version_sku_idx').on(columns.version_sku),
|
||||
index('_products_v_version_version_featured_image_idx').on(columns.version_featuredImage),
|
||||
index('_products_v_version_version_updated_at_idx').on(columns.version_updatedAt),
|
||||
index('_products_v_version_version_created_at_idx').on(columns.version_createdAt),
|
||||
index('_products_v_version_version__status_idx').on(columns.version__status),
|
||||
index('_products_v_created_at_idx').on(columns.createdAt),
|
||||
index('_products_v_updated_at_idx').on(columns.updatedAt),
|
||||
index('_products_v_snapshot_idx').on(columns.snapshot),
|
||||
index('_products_v_published_locale_idx').on(columns.publishedLocale),
|
||||
index('_products_v_latest_idx').on(columns.latest),
|
||||
],
|
||||
);
|
||||
|
||||
export const _products_v_locales = pgTable(
|
||||
'_products_v_locales',
|
||||
{
|
||||
version_title: varchar('version_title'),
|
||||
version_description: varchar('version_description'),
|
||||
version_application: jsonb('version_application'),
|
||||
version_content: jsonb('version_content'),
|
||||
id: serial('id').primaryKey(),
|
||||
_locale: enum__locales('_locale').notNull(),
|
||||
_parentID: integer('_parent_id').notNull(),
|
||||
},
|
||||
(columns) => [
|
||||
uniqueIndex('_products_v_locales_locale_parent_id_unique').on(
|
||||
columns._locale,
|
||||
columns._parentID,
|
||||
),
|
||||
foreignKey({
|
||||
columns: [columns['_parentID']],
|
||||
foreignColumns: [_products_v.id],
|
||||
name: '_products_v_locales_parent_id_fk',
|
||||
}).onDelete('cascade'),
|
||||
],
|
||||
);
|
||||
|
||||
export const _products_v_rels = pgTable(
|
||||
'_products_v_rels',
|
||||
{
|
||||
@@ -425,6 +511,118 @@ export const _products_v_rels = pgTable(
|
||||
],
|
||||
);
|
||||
|
||||
export const pages = pgTable(
|
||||
'pages',
|
||||
{
|
||||
id: serial('id').primaryKey(),
|
||||
layout: enum_pages_layout('layout').default('default'),
|
||||
featuredImage: integer('featured_image_id').references(() => media.id, {
|
||||
onDelete: 'set null',
|
||||
}),
|
||||
updatedAt: timestamp('updated_at', { mode: 'string', withTimezone: true, precision: 3 })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
createdAt: timestamp('created_at', { mode: 'string', withTimezone: true, precision: 3 })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
_status: enum_pages_status('_status').default('draft'),
|
||||
},
|
||||
(columns) => [
|
||||
index('pages_featured_image_idx').on(columns.featuredImage),
|
||||
index('pages_updated_at_idx').on(columns.updatedAt),
|
||||
index('pages_created_at_idx').on(columns.createdAt),
|
||||
index('pages__status_idx').on(columns._status),
|
||||
],
|
||||
);
|
||||
|
||||
export const pages_locales = pgTable(
|
||||
'pages_locales',
|
||||
{
|
||||
title: varchar('title'),
|
||||
slug: varchar('slug'),
|
||||
excerpt: varchar('excerpt'),
|
||||
content: jsonb('content'),
|
||||
id: serial('id').primaryKey(),
|
||||
_locale: enum__locales('_locale').notNull(),
|
||||
_parentID: integer('_parent_id').notNull(),
|
||||
},
|
||||
(columns) => [
|
||||
uniqueIndex('pages_locales_locale_parent_id_unique').on(columns._locale, columns._parentID),
|
||||
foreignKey({
|
||||
columns: [columns['_parentID']],
|
||||
foreignColumns: [pages.id],
|
||||
name: 'pages_locales_parent_id_fk',
|
||||
}).onDelete('cascade'),
|
||||
],
|
||||
);
|
||||
|
||||
export const _pages_v = pgTable(
|
||||
'_pages_v',
|
||||
{
|
||||
id: serial('id').primaryKey(),
|
||||
parent: integer('parent_id').references(() => pages.id, {
|
||||
onDelete: 'set null',
|
||||
}),
|
||||
version_layout: enum__pages_v_version_layout('version_layout').default('default'),
|
||||
version_featuredImage: integer('version_featured_image_id').references(() => media.id, {
|
||||
onDelete: 'set null',
|
||||
}),
|
||||
version_updatedAt: timestamp('version_updated_at', {
|
||||
mode: 'string',
|
||||
withTimezone: true,
|
||||
precision: 3,
|
||||
}),
|
||||
version_createdAt: timestamp('version_created_at', {
|
||||
mode: 'string',
|
||||
withTimezone: true,
|
||||
precision: 3,
|
||||
}),
|
||||
version__status: enum__pages_v_version_status('version__status').default('draft'),
|
||||
createdAt: timestamp('created_at', { mode: 'string', withTimezone: true, precision: 3 })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
updatedAt: timestamp('updated_at', { mode: 'string', withTimezone: true, precision: 3 })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
snapshot: boolean('snapshot'),
|
||||
publishedLocale: enum__pages_v_published_locale('published_locale'),
|
||||
latest: boolean('latest'),
|
||||
},
|
||||
(columns) => [
|
||||
index('_pages_v_parent_idx').on(columns.parent),
|
||||
index('_pages_v_version_version_featured_image_idx').on(columns.version_featuredImage),
|
||||
index('_pages_v_version_version_updated_at_idx').on(columns.version_updatedAt),
|
||||
index('_pages_v_version_version_created_at_idx').on(columns.version_createdAt),
|
||||
index('_pages_v_version_version__status_idx').on(columns.version__status),
|
||||
index('_pages_v_created_at_idx').on(columns.createdAt),
|
||||
index('_pages_v_updated_at_idx').on(columns.updatedAt),
|
||||
index('_pages_v_snapshot_idx').on(columns.snapshot),
|
||||
index('_pages_v_published_locale_idx').on(columns.publishedLocale),
|
||||
index('_pages_v_latest_idx').on(columns.latest),
|
||||
],
|
||||
);
|
||||
|
||||
export const _pages_v_locales = pgTable(
|
||||
'_pages_v_locales',
|
||||
{
|
||||
version_title: varchar('version_title'),
|
||||
version_slug: varchar('version_slug'),
|
||||
version_excerpt: varchar('version_excerpt'),
|
||||
version_content: jsonb('version_content'),
|
||||
id: serial('id').primaryKey(),
|
||||
_locale: enum__locales('_locale').notNull(),
|
||||
_parentID: integer('_parent_id').notNull(),
|
||||
},
|
||||
(columns) => [
|
||||
uniqueIndex('_pages_v_locales_locale_parent_id_unique').on(columns._locale, columns._parentID),
|
||||
foreignKey({
|
||||
columns: [columns['_parentID']],
|
||||
foreignColumns: [_pages_v.id],
|
||||
name: '_pages_v_locales_parent_id_fk',
|
||||
}).onDelete('cascade'),
|
||||
],
|
||||
);
|
||||
|
||||
export const payload_kv = pgTable(
|
||||
'payload_kv',
|
||||
{
|
||||
@@ -466,6 +664,7 @@ export const payload_locked_documents_rels = pgTable(
|
||||
postsID: integer('posts_id'),
|
||||
'form-submissionsID': integer('form_submissions_id'),
|
||||
productsID: integer('products_id'),
|
||||
pagesID: integer('pages_id'),
|
||||
},
|
||||
(columns) => [
|
||||
index('payload_locked_documents_rels_order_idx').on(columns.order),
|
||||
@@ -478,6 +677,7 @@ export const payload_locked_documents_rels = pgTable(
|
||||
columns['form-submissionsID'],
|
||||
),
|
||||
index('payload_locked_documents_rels_products_id_idx').on(columns.productsID),
|
||||
index('payload_locked_documents_rels_pages_id_idx').on(columns.pagesID),
|
||||
foreignKey({
|
||||
columns: [columns['parent']],
|
||||
foreignColumns: [payload_locked_documents.id],
|
||||
@@ -508,6 +708,11 @@ export const payload_locked_documents_rels = pgTable(
|
||||
foreignColumns: [products.id],
|
||||
name: 'payload_locked_documents_rels_products_fk',
|
||||
}).onDelete('cascade'),
|
||||
foreignKey({
|
||||
columns: [columns['pagesID']],
|
||||
foreignColumns: [pages.id],
|
||||
name: 'payload_locked_documents_rels_pages_fk',
|
||||
}).onDelete('cascade'),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -590,14 +795,31 @@ export const relations_users = relations(users, ({ many }) => ({
|
||||
}),
|
||||
}));
|
||||
export const relations_media = relations(media, () => ({}));
|
||||
export const relations_posts = relations(posts, ({ one }) => ({
|
||||
export const relations_posts_locales = relations(posts_locales, ({ one }) => ({
|
||||
_parentID: one(posts, {
|
||||
fields: [posts_locales._parentID],
|
||||
references: [posts.id],
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations_posts = relations(posts, ({ one, many }) => ({
|
||||
featuredImage: one(media, {
|
||||
fields: [posts.featuredImage],
|
||||
references: [media.id],
|
||||
relationName: 'featuredImage',
|
||||
}),
|
||||
_locales: many(posts_locales, {
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations__posts_v = relations(_posts_v, ({ one }) => ({
|
||||
export const relations__posts_v_locales = relations(_posts_v_locales, ({ one }) => ({
|
||||
_parentID: one(_posts_v, {
|
||||
fields: [_posts_v_locales._parentID],
|
||||
references: [_posts_v.id],
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations__posts_v = relations(_posts_v, ({ one, many }) => ({
|
||||
parent: one(posts, {
|
||||
fields: [_posts_v.parent],
|
||||
references: [posts.id],
|
||||
@@ -608,6 +830,9 @@ export const relations__posts_v = relations(_posts_v, ({ one }) => ({
|
||||
references: [media.id],
|
||||
relationName: 'version_featuredImage',
|
||||
}),
|
||||
_locales: many(_posts_v_locales, {
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations_form_submissions = relations(form_submissions, () => ({}));
|
||||
export const relations_products_categories = relations(products_categories, ({ one }) => ({
|
||||
@@ -617,6 +842,13 @@ export const relations_products_categories = relations(products_categories, ({ o
|
||||
relationName: 'categories',
|
||||
}),
|
||||
}));
|
||||
export const relations_products_locales = relations(products_locales, ({ one }) => ({
|
||||
_parentID: one(products, {
|
||||
fields: [products_locales._parentID],
|
||||
references: [products.id],
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations_products_rels = relations(products_rels, ({ one }) => ({
|
||||
parent: one(products, {
|
||||
fields: [products_rels.parent],
|
||||
@@ -629,10 +861,18 @@ export const relations_products_rels = relations(products_rels, ({ one }) => ({
|
||||
relationName: 'media',
|
||||
}),
|
||||
}));
|
||||
export const relations_products = relations(products, ({ many }) => ({
|
||||
export const relations_products = relations(products, ({ one, many }) => ({
|
||||
categories: many(products_categories, {
|
||||
relationName: 'categories',
|
||||
}),
|
||||
featuredImage: one(media, {
|
||||
fields: [products.featuredImage],
|
||||
references: [media.id],
|
||||
relationName: 'featuredImage',
|
||||
}),
|
||||
_locales: many(products_locales, {
|
||||
relationName: '_locales',
|
||||
}),
|
||||
_rels: many(products_rels, {
|
||||
relationName: '_rels',
|
||||
}),
|
||||
@@ -647,6 +887,13 @@ export const relations__products_v_version_categories = relations(
|
||||
}),
|
||||
}),
|
||||
);
|
||||
export const relations__products_v_locales = relations(_products_v_locales, ({ one }) => ({
|
||||
_parentID: one(_products_v, {
|
||||
fields: [_products_v_locales._parentID],
|
||||
references: [_products_v.id],
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations__products_v_rels = relations(_products_v_rels, ({ one }) => ({
|
||||
parent: one(_products_v, {
|
||||
fields: [_products_v_rels.parent],
|
||||
@@ -668,10 +915,57 @@ export const relations__products_v = relations(_products_v, ({ one, many }) => (
|
||||
version_categories: many(_products_v_version_categories, {
|
||||
relationName: 'version_categories',
|
||||
}),
|
||||
version_featuredImage: one(media, {
|
||||
fields: [_products_v.version_featuredImage],
|
||||
references: [media.id],
|
||||
relationName: 'version_featuredImage',
|
||||
}),
|
||||
_locales: many(_products_v_locales, {
|
||||
relationName: '_locales',
|
||||
}),
|
||||
_rels: many(_products_v_rels, {
|
||||
relationName: '_rels',
|
||||
}),
|
||||
}));
|
||||
export const relations_pages_locales = relations(pages_locales, ({ one }) => ({
|
||||
_parentID: one(pages, {
|
||||
fields: [pages_locales._parentID],
|
||||
references: [pages.id],
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations_pages = relations(pages, ({ one, many }) => ({
|
||||
featuredImage: one(media, {
|
||||
fields: [pages.featuredImage],
|
||||
references: [media.id],
|
||||
relationName: 'featuredImage',
|
||||
}),
|
||||
_locales: many(pages_locales, {
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations__pages_v_locales = relations(_pages_v_locales, ({ one }) => ({
|
||||
_parentID: one(_pages_v, {
|
||||
fields: [_pages_v_locales._parentID],
|
||||
references: [_pages_v.id],
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations__pages_v = relations(_pages_v, ({ one, many }) => ({
|
||||
parent: one(pages, {
|
||||
fields: [_pages_v.parent],
|
||||
references: [pages.id],
|
||||
relationName: 'parent',
|
||||
}),
|
||||
version_featuredImage: one(media, {
|
||||
fields: [_pages_v.version_featuredImage],
|
||||
references: [media.id],
|
||||
relationName: 'version_featuredImage',
|
||||
}),
|
||||
_locales: many(_pages_v_locales, {
|
||||
relationName: '_locales',
|
||||
}),
|
||||
}));
|
||||
export const relations_payload_kv = relations(payload_kv, () => ({}));
|
||||
export const relations_payload_locked_documents_rels = relations(
|
||||
payload_locked_documents_rels,
|
||||
@@ -706,6 +1000,11 @@ export const relations_payload_locked_documents_rels = relations(
|
||||
references: [products.id],
|
||||
relationName: 'products',
|
||||
}),
|
||||
pagesID: one(pages, {
|
||||
fields: [payload_locked_documents_rels.pagesID],
|
||||
references: [pages.id],
|
||||
relationName: 'pages',
|
||||
}),
|
||||
}),
|
||||
);
|
||||
export const relations_payload_locked_documents = relations(
|
||||
@@ -739,27 +1038,39 @@ export const relations_payload_preferences = relations(payload_preferences, ({ m
|
||||
export const relations_payload_migrations = relations(payload_migrations, () => ({}));
|
||||
|
||||
type DatabaseSchema = {
|
||||
enum_posts_locale: typeof enum_posts_locale;
|
||||
enum__locales: typeof enum__locales;
|
||||
enum_posts_status: typeof enum_posts_status;
|
||||
enum__posts_v_version_locale: typeof enum__posts_v_version_locale;
|
||||
enum__posts_v_version_status: typeof enum__posts_v_version_status;
|
||||
enum__posts_v_published_locale: typeof enum__posts_v_published_locale;
|
||||
enum_form_submissions_type: typeof enum_form_submissions_type;
|
||||
enum_products_locale: typeof enum_products_locale;
|
||||
enum_products_status: typeof enum_products_status;
|
||||
enum__products_v_version_locale: typeof enum__products_v_version_locale;
|
||||
enum__products_v_version_status: typeof enum__products_v_version_status;
|
||||
enum__products_v_published_locale: typeof enum__products_v_published_locale;
|
||||
enum_pages_layout: typeof enum_pages_layout;
|
||||
enum_pages_status: typeof enum_pages_status;
|
||||
enum__pages_v_version_layout: typeof enum__pages_v_version_layout;
|
||||
enum__pages_v_version_status: typeof enum__pages_v_version_status;
|
||||
enum__pages_v_published_locale: typeof enum__pages_v_published_locale;
|
||||
users_sessions: typeof users_sessions;
|
||||
users: typeof users;
|
||||
media: typeof media;
|
||||
posts: typeof posts;
|
||||
posts_locales: typeof posts_locales;
|
||||
_posts_v: typeof _posts_v;
|
||||
_posts_v_locales: typeof _posts_v_locales;
|
||||
form_submissions: typeof form_submissions;
|
||||
products_categories: typeof products_categories;
|
||||
products: typeof products;
|
||||
products_locales: typeof products_locales;
|
||||
products_rels: typeof products_rels;
|
||||
_products_v_version_categories: typeof _products_v_version_categories;
|
||||
_products_v: typeof _products_v;
|
||||
_products_v_locales: typeof _products_v_locales;
|
||||
_products_v_rels: typeof _products_v_rels;
|
||||
pages: typeof pages;
|
||||
pages_locales: typeof pages_locales;
|
||||
_pages_v: typeof _pages_v;
|
||||
_pages_v_locales: typeof _pages_v_locales;
|
||||
payload_kv: typeof payload_kv;
|
||||
payload_locked_documents: typeof payload_locked_documents;
|
||||
payload_locked_documents_rels: typeof payload_locked_documents_rels;
|
||||
@@ -769,15 +1080,23 @@ type DatabaseSchema = {
|
||||
relations_users_sessions: typeof relations_users_sessions;
|
||||
relations_users: typeof relations_users;
|
||||
relations_media: typeof relations_media;
|
||||
relations_posts_locales: typeof relations_posts_locales;
|
||||
relations_posts: typeof relations_posts;
|
||||
relations__posts_v_locales: typeof relations__posts_v_locales;
|
||||
relations__posts_v: typeof relations__posts_v;
|
||||
relations_form_submissions: typeof relations_form_submissions;
|
||||
relations_products_categories: typeof relations_products_categories;
|
||||
relations_products_locales: typeof relations_products_locales;
|
||||
relations_products_rels: typeof relations_products_rels;
|
||||
relations_products: typeof relations_products;
|
||||
relations__products_v_version_categories: typeof relations__products_v_version_categories;
|
||||
relations__products_v_locales: typeof relations__products_v_locales;
|
||||
relations__products_v_rels: typeof relations__products_v_rels;
|
||||
relations__products_v: typeof relations__products_v;
|
||||
relations_pages_locales: typeof relations_pages_locales;
|
||||
relations_pages: typeof relations_pages;
|
||||
relations__pages_v_locales: typeof relations__pages_v_locales;
|
||||
relations__pages_v: typeof relations__pages_v;
|
||||
relations_payload_kv: typeof relations_payload_kv;
|
||||
relations_payload_locked_documents_rels: typeof relations_payload_locked_documents_rels;
|
||||
relations_payload_locked_documents: typeof relations_payload_locked_documents;
|
||||
|
||||
48
src/payload/blocks/CategoryGrid.ts
Normal file
48
src/payload/blocks/CategoryGrid.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Block } from 'payload';
|
||||
|
||||
export const CategoryGrid: Block = {
|
||||
slug: 'categoryGrid',
|
||||
interfaceName: 'CategoryGridBlock',
|
||||
fields: [
|
||||
{
|
||||
name: 'categories',
|
||||
type: 'array',
|
||||
required: true,
|
||||
minRows: 1,
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'textarea',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'image',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'icon',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'href',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'ctaLabel',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
54
src/payload/blocks/CompanyHeritage.ts
Normal file
54
src/payload/blocks/CompanyHeritage.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Block } from 'payload';
|
||||
|
||||
export const TeamLegacySection: Block = {
|
||||
slug: 'teamLegacySection',
|
||||
interfaceName: 'TeamLegacySectionBlock',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'subtitle',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'paragraph1',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'paragraph2',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'expertiseTitle',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'expertiseDesc',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'networkTitle',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'networkDesc',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'backgroundImage',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
26
src/payload/blocks/ContactSection.ts
Normal file
26
src/payload/blocks/ContactSection.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Block } from 'payload';
|
||||
|
||||
export const ContactSection: Block = {
|
||||
slug: 'contactSection',
|
||||
interfaceName: 'ContactSectionBlock',
|
||||
fields: [
|
||||
{
|
||||
name: 'showForm',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Show Contact Form',
|
||||
},
|
||||
{
|
||||
name: 'showMap',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Show Map',
|
||||
},
|
||||
{
|
||||
name: 'showHours',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Show Opening Hours',
|
||||
},
|
||||
],
|
||||
};
|
||||
48
src/payload/blocks/HeroSection.ts
Normal file
48
src/payload/blocks/HeroSection.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Block } from 'payload';
|
||||
|
||||
export const HeroSection: Block = {
|
||||
slug: 'heroSection',
|
||||
interfaceName: 'HeroSectionBlock',
|
||||
fields: [
|
||||
{
|
||||
name: 'badge',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'subtitle',
|
||||
type: 'textarea',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'backgroundImage',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'ctaLabel',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'ctaHref',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'alignment',
|
||||
type: 'select',
|
||||
defaultValue: 'left',
|
||||
options: [
|
||||
{ label: 'Left', value: 'left' },
|
||||
{ label: 'Center', value: 'center' },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
141
src/payload/blocks/HomeBlocks.ts
Normal file
141
src/payload/blocks/HomeBlocks.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import { Block } from 'payload';
|
||||
|
||||
export const HomeHero: Block = {
|
||||
slug: 'homeHero',
|
||||
interfaceName: 'HomeHeroBlock',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text', localized: true },
|
||||
{ name: 'subtitle', type: 'text', localized: true },
|
||||
{ name: 'ctaLabel', type: 'text', localized: true },
|
||||
{ name: 'secondaryCtaLabel', type: 'text', localized: true },
|
||||
],
|
||||
};
|
||||
|
||||
export const HomeProductCategories: Block = {
|
||||
slug: 'homeProductCategories',
|
||||
interfaceName: 'HomeProductCategoriesBlock',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text', localized: true },
|
||||
{ name: 'subtitle', type: 'text', localized: true },
|
||||
],
|
||||
};
|
||||
|
||||
export const HomeWhatWeDo: Block = {
|
||||
slug: 'homeWhatWeDo',
|
||||
interfaceName: 'HomeWhatWeDoBlock',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text', localized: true },
|
||||
{ name: 'subtitle', type: 'text', localized: true },
|
||||
{ name: 'expertiseLabel', type: 'text', localized: true },
|
||||
{ name: 'quote', type: 'textarea', localized: true },
|
||||
{
|
||||
name: 'items',
|
||||
type: 'array',
|
||||
localized: true,
|
||||
fields: [
|
||||
{ name: 'title', type: 'text' },
|
||||
{ name: 'description', type: 'textarea' },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const HomeRecentPosts: Block = {
|
||||
slug: 'homeRecentPosts',
|
||||
interfaceName: 'HomeRecentPostsBlock',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text', localized: true },
|
||||
{ name: 'subtitle', type: 'text', localized: true },
|
||||
],
|
||||
};
|
||||
|
||||
export const HomeExperience: Block = {
|
||||
slug: 'homeExperience',
|
||||
interfaceName: 'HomeExperienceBlock',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text', localized: true },
|
||||
{ name: 'subtitle', type: 'text', localized: true },
|
||||
{ name: 'paragraph1', type: 'textarea', localized: true },
|
||||
{ name: 'paragraph2', type: 'textarea', localized: true },
|
||||
{ name: 'badge1', type: 'text', localized: true },
|
||||
{ name: 'badge1Text', type: 'text', localized: true },
|
||||
{ name: 'badge2', type: 'text', localized: true },
|
||||
{ name: 'badge2Text', type: 'text', localized: true },
|
||||
],
|
||||
};
|
||||
|
||||
export const HomeWhyChooseUs: Block = {
|
||||
slug: 'homeWhyChooseUs',
|
||||
interfaceName: 'HomeWhyChooseUsBlock',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text', localized: true },
|
||||
{ name: 'subtitle', type: 'text', localized: true },
|
||||
{ name: 'tagline', type: 'text', localized: true },
|
||||
{
|
||||
name: 'features',
|
||||
type: 'array',
|
||||
localized: true,
|
||||
fields: [{ name: 'feature', type: 'text' }],
|
||||
},
|
||||
{
|
||||
name: 'items',
|
||||
type: 'array',
|
||||
localized: true,
|
||||
fields: [
|
||||
{ name: 'title', type: 'text' },
|
||||
{ name: 'description', type: 'textarea' },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const HomeMeetTheTeam: Block = {
|
||||
slug: 'homeMeetTheTeam',
|
||||
interfaceName: 'HomeMeetTheTeamBlock',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text', localized: true },
|
||||
{ name: 'subtitle', type: 'text', localized: true },
|
||||
{ name: 'description', type: 'textarea', localized: true },
|
||||
{ name: 'ctaLabel', type: 'text', localized: true },
|
||||
{ name: 'networkLabel', type: 'text', localized: true },
|
||||
],
|
||||
};
|
||||
|
||||
export const HomeGallery: Block = {
|
||||
slug: 'homeGallery',
|
||||
interfaceName: 'HomeGalleryBlock',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text', localized: true },
|
||||
{ name: 'subtitle', type: 'text', localized: true },
|
||||
],
|
||||
};
|
||||
|
||||
export const HomeVideo: Block = {
|
||||
slug: 'homeVideo',
|
||||
interfaceName: 'HomeVideoBlock',
|
||||
fields: [{ name: 'title', type: 'text', localized: true }],
|
||||
};
|
||||
|
||||
export const HomeCTA: Block = {
|
||||
slug: 'homeCTA',
|
||||
interfaceName: 'HomeCTABlock',
|
||||
fields: [
|
||||
{ name: 'title', type: 'text', localized: true },
|
||||
{ name: 'subtitle', type: 'text', localized: true },
|
||||
{ name: 'description', type: 'textarea', localized: true },
|
||||
{ name: 'buttonLabel', type: 'text', localized: true },
|
||||
],
|
||||
};
|
||||
|
||||
export const homeBlocksArray = [
|
||||
HomeHero,
|
||||
HomeProductCategories,
|
||||
HomeWhatWeDo,
|
||||
HomeRecentPosts,
|
||||
HomeExperience,
|
||||
HomeWhyChooseUs,
|
||||
HomeMeetTheTeam,
|
||||
HomeGallery,
|
||||
HomeVideo,
|
||||
HomeCTA,
|
||||
];
|
||||
27
src/payload/blocks/ImageGallery.ts
Normal file
27
src/payload/blocks/ImageGallery.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Block } from 'payload';
|
||||
|
||||
export const ImageGallery: Block = {
|
||||
slug: 'imageGallery',
|
||||
interfaceName: 'ImageGalleryBlock',
|
||||
fields: [
|
||||
{
|
||||
name: 'images',
|
||||
type: 'array',
|
||||
required: true,
|
||||
minRows: 1,
|
||||
fields: [
|
||||
{
|
||||
name: 'image',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'alt',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
41
src/payload/blocks/ManifestoGrid.ts
Normal file
41
src/payload/blocks/ManifestoGrid.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Block } from 'payload';
|
||||
|
||||
export const ManifestoGrid: Block = {
|
||||
slug: 'manifestoGrid',
|
||||
interfaceName: 'ManifestoGridBlock',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'subtitle',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'tagline',
|
||||
type: 'textarea',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'items',
|
||||
type: 'array',
|
||||
required: true,
|
||||
minRows: 1,
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
28
src/payload/blocks/SupportCTA.ts
Normal file
28
src/payload/blocks/SupportCTA.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Block } from 'payload';
|
||||
|
||||
export const SupportCTA: Block = {
|
||||
slug: 'supportCTA',
|
||||
interfaceName: 'SupportCTABlock',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'buttonLabel',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'buttonHref',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
62
src/payload/blocks/TeamProfile.ts
Normal file
62
src/payload/blocks/TeamProfile.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Block } from 'payload';
|
||||
|
||||
export const TeamProfile: Block = {
|
||||
slug: 'teamProfile',
|
||||
interfaceName: 'TeamProfileBlock',
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'role',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'quote',
|
||||
type: 'textarea',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'textarea',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'image',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'linkedinUrl',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'linkedinLabel',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'layout',
|
||||
type: 'select',
|
||||
defaultValue: 'imageRight',
|
||||
options: [
|
||||
{ label: 'Image Right', value: 'imageRight' },
|
||||
{ label: 'Image Left', value: 'imageLeft' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'colorScheme',
|
||||
type: 'select',
|
||||
defaultValue: 'dark',
|
||||
options: [
|
||||
{ label: 'Dark', value: 'dark' },
|
||||
{ label: 'Light', value: 'light' },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,27 +1,41 @@
|
||||
import { AnimatedImage } from './AnimatedImage';
|
||||
import { Callout } from './Callout';
|
||||
import { CategoryGrid } from './CategoryGrid';
|
||||
import { ChatBubble } from './ChatBubble';
|
||||
import { ComparisonGrid } from './ComparisonGrid';
|
||||
import { ContactSection } from './ContactSection';
|
||||
import { HeroSection } from './HeroSection';
|
||||
import { HighlightBox } from './HighlightBox';
|
||||
import { ImageGallery } from './ImageGallery';
|
||||
import { ManifestoGrid } from './ManifestoGrid';
|
||||
import { PowerCTA } from './PowerCTA';
|
||||
import { ProductTabs } from './ProductTabs';
|
||||
import { SplitHeading } from './SplitHeading';
|
||||
import { Stats } from './Stats';
|
||||
import { StickyNarrative } from './StickyNarrative';
|
||||
import { TeamProfile } from './TeamProfile';
|
||||
import { TechnicalGrid } from './TechnicalGrid';
|
||||
import { VisualLinkPreview } from './VisualLinkPreview';
|
||||
import { homeBlocksArray } from './HomeBlocks';
|
||||
|
||||
export const payloadBlocks = [
|
||||
...homeBlocksArray,
|
||||
AnimatedImage,
|
||||
Callout,
|
||||
CategoryGrid,
|
||||
ChatBubble,
|
||||
ComparisonGrid,
|
||||
ContactSection,
|
||||
HeroSection,
|
||||
HighlightBox,
|
||||
ImageGallery,
|
||||
ManifestoGrid,
|
||||
PowerCTA,
|
||||
ProductTabs,
|
||||
SplitHeading,
|
||||
Stats,
|
||||
StickyNarrative,
|
||||
TeamProfile,
|
||||
TechnicalGrid,
|
||||
VisualLinkPreview,
|
||||
];
|
||||
|
||||
@@ -1,44 +1,65 @@
|
||||
import { CollectionConfig } from 'payload';
|
||||
import { lexicalEditor } from '@payloadcms/richtext-lexical';
|
||||
import { lexicalEditor, BlocksFeature } from '@payloadcms/richtext-lexical';
|
||||
import { payloadBlocks } from '../blocks/allBlocks';
|
||||
|
||||
export const Pages: CollectionConfig = {
|
||||
slug: 'pages',
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
defaultColumns: ['title', 'slug', 'locale', 'updatedAt'],
|
||||
defaultColumns: ['title', 'slug', 'layout', '_status', 'updatedAt'],
|
||||
},
|
||||
versions: {
|
||||
drafts: true,
|
||||
},
|
||||
access: {
|
||||
read: () => true,
|
||||
read: ({ req: { user } }) => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
return true;
|
||||
}
|
||||
if (user) {
|
||||
return true;
|
||||
}
|
||||
return {
|
||||
_status: {
|
||||
equals: 'published',
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'slug',
|
||||
type: 'text',
|
||||
required: true,
|
||||
localized: true,
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
description: 'The URL slug for this locale (e.g. "impressum" for DE, "imprint" for EN).',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'locale',
|
||||
name: 'layout',
|
||||
type: 'select',
|
||||
defaultValue: 'default',
|
||||
options: [
|
||||
{ label: 'English', value: 'en' },
|
||||
{ label: 'German', value: 'de' },
|
||||
{ label: 'Default (Article)', value: 'default' },
|
||||
{ label: 'Full Bleed (Blocks Only)', value: 'fullBleed' },
|
||||
],
|
||||
required: true,
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
description: 'Full Bleed pages render blocks edge-to-edge without a generic hero wrapper.',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'excerpt',
|
||||
type: 'textarea',
|
||||
localized: true,
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
},
|
||||
@@ -54,7 +75,15 @@ export const Pages: CollectionConfig = {
|
||||
{
|
||||
name: 'content',
|
||||
type: 'richText',
|
||||
editor: lexicalEditor({}),
|
||||
localized: true,
|
||||
editor: lexicalEditor({
|
||||
features: ({ defaultFeatures }) => [
|
||||
...defaultFeatures,
|
||||
BlocksFeature({
|
||||
blocks: payloadBlocks,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -19,22 +19,16 @@ export const Posts: CollectionConfig = {
|
||||
defaultColumns: ['featuredImage', 'title', 'date', 'updatedAt', '_status'],
|
||||
},
|
||||
versions: {
|
||||
drafts: true, // Enables Draft/Published workflows
|
||||
drafts: true,
|
||||
},
|
||||
access: {
|
||||
read: ({ req: { user } }) => {
|
||||
// In local development, always show everything (including Drafts and scheduled future posts)
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If an Admin user is logged in, they can view everything
|
||||
if (user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// For public unauthenticated visitors in PROD/STAGING contexts:
|
||||
// Only serve Posts where Status = "published" AND the publish Date is in the past!
|
||||
return {
|
||||
and: [
|
||||
{
|
||||
@@ -56,19 +50,20 @@ export const Posts: CollectionConfig = {
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'slug',
|
||||
type: 'text',
|
||||
required: true,
|
||||
unique: true,
|
||||
localized: true,
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
description: 'Unique slug per locale (e.g. same slug can exist in DE and EN).',
|
||||
},
|
||||
hooks: {
|
||||
beforeValidate: [
|
||||
({ value, data }) => {
|
||||
// Auto-generate slug from title if left blank
|
||||
if (value || !data?.title) return value;
|
||||
return data.title
|
||||
.toLowerCase()
|
||||
@@ -81,6 +76,7 @@ export const Posts: CollectionConfig = {
|
||||
{
|
||||
name: 'excerpt',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
admin: {
|
||||
description: 'A short summary for blog feed cards and SEO.',
|
||||
},
|
||||
@@ -104,22 +100,10 @@ export const Posts: CollectionConfig = {
|
||||
description: 'The primary Hero image used for headers and OpenGraph previews.',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'locale',
|
||||
type: 'select',
|
||||
required: true,
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
},
|
||||
options: [
|
||||
{ label: 'English', value: 'en' },
|
||||
{ label: 'German', value: 'de' },
|
||||
],
|
||||
defaultValue: 'en',
|
||||
},
|
||||
{
|
||||
name: 'category',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
description: 'Used for tag bucketing (e.g. "Kabel Technologie").',
|
||||
@@ -128,6 +112,7 @@ export const Posts: CollectionConfig = {
|
||||
{
|
||||
name: 'content',
|
||||
type: 'richText',
|
||||
localized: true,
|
||||
editor: lexicalEditor({
|
||||
features: ({ defaultFeatures }) => [
|
||||
...defaultFeatures,
|
||||
|
||||
@@ -17,7 +17,7 @@ import { ProductTabs } from '../blocks/ProductTabs';
|
||||
export const Products: CollectionConfig = {
|
||||
slug: 'products',
|
||||
admin: {
|
||||
defaultColumns: ['featuredImage', 'title', 'sku', 'locale', 'updatedAt', '_status'],
|
||||
defaultColumns: ['featuredImage', 'title', 'sku', 'updatedAt', '_status'],
|
||||
},
|
||||
versions: {
|
||||
drafts: true,
|
||||
@@ -42,6 +42,7 @@ export const Products: CollectionConfig = {
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'sku',
|
||||
@@ -52,6 +53,7 @@ export const Products: CollectionConfig = {
|
||||
},
|
||||
},
|
||||
{
|
||||
// slug is shared: the cable name (e.g. "n2xy") is the same in DE and EN
|
||||
name: 'slug',
|
||||
type: 'text',
|
||||
required: true,
|
||||
@@ -63,19 +65,7 @@ export const Products: CollectionConfig = {
|
||||
name: 'description',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'locale',
|
||||
type: 'select',
|
||||
required: true,
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
},
|
||||
options: [
|
||||
{ label: 'English', value: 'en' },
|
||||
{ label: 'German', value: 'de' },
|
||||
],
|
||||
defaultValue: 'de',
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'categories',
|
||||
@@ -112,11 +102,13 @@ export const Products: CollectionConfig = {
|
||||
{
|
||||
name: 'application',
|
||||
type: 'richText',
|
||||
localized: true,
|
||||
editor: lexicalEditor({}),
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'richText',
|
||||
localized: true,
|
||||
editor: lexicalEditor({
|
||||
features: ({ defaultFeatures }) => [
|
||||
...defaultFeatures,
|
||||
|
||||
12
src/payload/components/Icon.tsx
Normal file
12
src/payload/components/Icon.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Icon() {
|
||||
return (
|
||||
<img
|
||||
src="/logo-blue.svg"
|
||||
alt="KLZ"
|
||||
className="klz-admin-icon"
|
||||
style={{ maxWidth: '100%', height: 'auto', maxHeight: '32px', display: 'block' }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
12
src/payload/components/Logo.tsx
Normal file
12
src/payload/components/Logo.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Logo() {
|
||||
return (
|
||||
<img
|
||||
src="/logo-blue.svg"
|
||||
alt="KLZ Cables"
|
||||
className="klz-admin-logo"
|
||||
style={{ maxWidth: '100%', height: 'auto', maxHeight: '40px', display: 'block' }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -29,12 +29,12 @@ export async function seedDatabase(payload: Payload) {
|
||||
payload.logger.info('📦 No products found. Creating smoke test product (NAY2Y)...');
|
||||
await payload.create({
|
||||
collection: 'products',
|
||||
locale: 'de',
|
||||
data: {
|
||||
title: 'NAY2Y Smoke Test',
|
||||
sku: 'SMOKE-TEST-001',
|
||||
slug: 'nay2y',
|
||||
description: 'A dummy product for CI/CD smoke testing and OG image verification.',
|
||||
locale: 'de',
|
||||
categories: [{ category: 'Power Cables' }],
|
||||
_status: 'published',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user