feat: live preview blog
This commit is contained in:
parent
294a5392c0
commit
d5eca3f876
11 changed files with 12547 additions and 11 deletions
20
package-lock.json
generated
20
package-lock.json
generated
|
|
@ -11,6 +11,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nyariv/sandboxjs": "0.8.28",
|
"@nyariv/sandboxjs": "0.8.28",
|
||||||
"@payloadcms/db-postgres": "^3.74.0",
|
"@payloadcms/db-postgres": "^3.74.0",
|
||||||
|
"@payloadcms/live-preview-react": "^3.79.0",
|
||||||
"@payloadcms/next": "^3.74.0",
|
"@payloadcms/next": "^3.74.0",
|
||||||
"@payloadcms/richtext-lexical": "^3.74.0",
|
"@payloadcms/richtext-lexical": "^3.74.0",
|
||||||
"@payloadcms/storage-gcs": "^3.74.0",
|
"@payloadcms/storage-gcs": "^3.74.0",
|
||||||
|
|
@ -2141,6 +2142,25 @@
|
||||||
"payload": "3.74.0"
|
"payload": "3.74.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@payloadcms/live-preview": {
|
||||||
|
"version": "3.79.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@payloadcms/live-preview/-/live-preview-3.79.0.tgz",
|
||||||
|
"integrity": "sha512-Y2t6NACgeC4gZV/mwzD1L+OhJHematK0RQ8xK4P/m+8fhO+sgS4gtjpA/m6yqAkhruRTni5izZJK6SWTB9pXPw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@payloadcms/live-preview-react": {
|
||||||
|
"version": "3.79.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@payloadcms/live-preview-react/-/live-preview-react-3.79.0.tgz",
|
||||||
|
"integrity": "sha512-1JY/QzfIy6iOijpbdRdnV+TuK0B0vo8nTgH+WkfCWxayXf30FlykWW8sdBc44wn4CxmLry36cEeneqAbrasiWQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@payloadcms/live-preview": "3.79.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.1 || ^19.1.2 || ^19.2.1",
|
||||||
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.1 || ^19.1.2 || ^19.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@payloadcms/next": {
|
"node_modules/@payloadcms/next": {
|
||||||
"version": "3.74.0",
|
"version": "3.74.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nyariv/sandboxjs": "0.8.28",
|
"@nyariv/sandboxjs": "0.8.28",
|
||||||
"@payloadcms/db-postgres": "^3.74.0",
|
"@payloadcms/db-postgres": "^3.74.0",
|
||||||
|
"@payloadcms/live-preview-react": "^3.79.0",
|
||||||
"@payloadcms/next": "^3.74.0",
|
"@payloadcms/next": "^3.74.0",
|
||||||
"@payloadcms/richtext-lexical": "^3.74.0",
|
"@payloadcms/richtext-lexical": "^3.74.0",
|
||||||
"@payloadcms/storage-gcs": "^3.74.0",
|
"@payloadcms/storage-gcs": "^3.74.0",
|
||||||
|
|
@ -38,6 +39,7 @@
|
||||||
"zod": "^4.3.6"
|
"zod": "^4.3.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@storybook/nextjs-vite": "^10.2.7",
|
||||||
"@swc/cli": "^0.7.10",
|
"@swc/cli": "^0.7.10",
|
||||||
"@swc/core": "^1.15.11",
|
"@swc/core": "^1.15.11",
|
||||||
"@types/node": "^20.19.32",
|
"@types/node": "^20.19.32",
|
||||||
|
|
@ -46,12 +48,11 @@
|
||||||
"eslint": "9.26.0",
|
"eslint": "9.26.0",
|
||||||
"eslint-config-next": "16.1.6",
|
"eslint-config-next": "16.1.6",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"typescript": "5.9.3",
|
"eslint-plugin-storybook": "^10.2.7",
|
||||||
"vitest": "^4.0.18",
|
|
||||||
"storybook": "^10.2.7",
|
"storybook": "^10.2.7",
|
||||||
"@storybook/nextjs-vite": "^10.2.7",
|
"typescript": "5.9.3",
|
||||||
"vite": "^7.3.1",
|
"vite": "^7.3.1",
|
||||||
"eslint-plugin-storybook": "^10.2.7"
|
"vitest": "^4.0.18"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.0.0"
|
"node": ">=22.0.0"
|
||||||
|
|
|
||||||
42
src/app/(home)/api/draft/route.ts
Normal file
42
src/app/(home)/api/draft/route.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Draft Mode API Route
|
||||||
|
//
|
||||||
|
// Enables Next.js draft mode so that pages can fetch unpublished
|
||||||
|
// Payload CMS content. This route is called by Payload's live preview
|
||||||
|
// iframe (configured in each collection's admin.livePreview.url) to
|
||||||
|
// set the draft mode cookie before redirecting to the actual page.
|
||||||
|
//
|
||||||
|
// Only authenticated Payload users can activate draft mode, ensuring
|
||||||
|
// public visitors never see draft content.
|
||||||
|
//
|
||||||
|
// See: https://nextjs.org/docs/app/guides/draft-mode
|
||||||
|
|
||||||
|
import { draftMode } from 'next/headers'
|
||||||
|
import { redirect } from 'next/navigation'
|
||||||
|
import { getPayload } from 'payload'
|
||||||
|
import config from '@/payload.config'
|
||||||
|
import { headers } from 'next/headers'
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url)
|
||||||
|
const url = searchParams.get('url')
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
return new Response('Missing url parameter', { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the request comes from an authenticated Payload CMS user
|
||||||
|
const payload = await getPayload({ config })
|
||||||
|
const allHeaders = await headers()
|
||||||
|
const { user } = await payload.auth({ headers: allHeaders })
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return new Response('Unauthorized', { status: 401 })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable draft mode cookie — subsequent page renders will see
|
||||||
|
// draftMode().isEnabled === true and can fetch draft content
|
||||||
|
const draft = await draftMode()
|
||||||
|
draft.enable()
|
||||||
|
|
||||||
|
redirect(url)
|
||||||
|
}
|
||||||
|
|
@ -11,17 +11,27 @@ import styles from "./styles.module.scss"
|
||||||
import { Blocks } from '@/compositions/Blocks/Blocks'
|
import { Blocks } from '@/compositions/Blocks/Blocks'
|
||||||
import { isAuthenticated } from '@/utils/auth'
|
import { isAuthenticated } from '@/utils/auth'
|
||||||
import { AdminMenu } from '@/components/AdminMenu/AdminMenu'
|
import { AdminMenu } from '@/components/AdminMenu/AdminMenu'
|
||||||
|
import { RefreshRouteOnSave } from '@/components/RefreshRouteOnSave/RefreshRouteOnSave'
|
||||||
|
import { getPayload } from 'payload'
|
||||||
|
import config from '@/payload.config'
|
||||||
|
import { draftMode } from 'next/headers'
|
||||||
|
|
||||||
async function fetchBlog(id: string) {
|
async function fetchBlog(id: string, draft: boolean) {
|
||||||
const res = await fetch(`http://localhost:3000/api/blog/${id}`)
|
const payload = await getPayload({ config })
|
||||||
if (!res.ok) return undefined
|
const blog = await payload.findByID({
|
||||||
return res.json();
|
collection: 'blog',
|
||||||
|
id: id,
|
||||||
|
draft,
|
||||||
|
})
|
||||||
|
|
||||||
|
return blog
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function BlogPage({ params }: { params: Promise<{id: string}>}){
|
export default async function BlogPage({ params }: { params: Promise<{id: string}>}){
|
||||||
|
|
||||||
const id = (await params).id;
|
const id = (await params).id;
|
||||||
const data = await fetchBlog(id) as Blog;
|
const { isEnabled: isDraft } = await draftMode()
|
||||||
|
const data = await fetchBlog(id, isDraft) as Blog;
|
||||||
const url = typeof data.photo === 'object' && data.photo?.sizes?.banner?.url;
|
const url = typeof data.photo === 'object' && data.photo?.sizes?.banner?.url;
|
||||||
const authenticated = await isAuthenticated();
|
const authenticated = await isAuthenticated();
|
||||||
|
|
||||||
|
|
@ -35,6 +45,7 @@ export default async function BlogPage({ params }: { params: Promise<{id: string
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{isDraft && <RefreshRouteOnSave />}
|
||||||
<Section paddingBottom={"small"}>
|
<Section paddingBottom={"small"}>
|
||||||
<Container>
|
<Container>
|
||||||
<Title title={data.title} color={"contrast"}></Title>
|
<Title title={data.title} color={"contrast"}></Title>
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,12 @@ export const Blog: CollectionConfig = {
|
||||||
admin: {
|
admin: {
|
||||||
useAsTitle: 'title',
|
useAsTitle: 'title',
|
||||||
hidden: hide,
|
hidden: hide,
|
||||||
|
livePreview: {
|
||||||
|
url: ({ data }) => `/api/draft?url=/blog/${data.id}`,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
versions: {
|
||||||
|
drafts: true
|
||||||
},
|
},
|
||||||
access: {
|
access: {
|
||||||
read: () => true,
|
read: () => true,
|
||||||
|
|
|
||||||
15
src/components/RefreshRouteOnSave/RefreshRouteOnSave.tsx
Normal file
15
src/components/RefreshRouteOnSave/RefreshRouteOnSave.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
'use client'
|
||||||
|
import { RefreshRouteOnSave as PayloadLivePreview } from '@payloadcms/live-preview-react'
|
||||||
|
import { useRouter } from 'next/navigation.js'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export const RefreshRouteOnSave: React.FC = () => {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PayloadLivePreview
|
||||||
|
refresh={() => router.refresh()}
|
||||||
|
serverURL={process.env.PUBLIC_URL || "http://localhost:3000"}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
12191
src/migrations/20260310_143800.json
Normal file
12191
src/migrations/20260310_143800.json
Normal file
File diff suppressed because it is too large
Load diff
238
src/migrations/20260310_143800.ts
Normal file
238
src/migrations/20260310_143800.ts
Normal file
|
|
@ -0,0 +1,238 @@
|
||||||
|
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
|
||||||
|
|
||||||
|
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE TYPE "public"."enum_blog_status" AS ENUM('draft', 'published');
|
||||||
|
CREATE TYPE "public"."enum__blog_v_blocks_text_width" AS ENUM('1/2', '3/4');
|
||||||
|
CREATE TYPE "public"."enum__blog_v_version_status" AS ENUM('draft', 'published');
|
||||||
|
CREATE TABLE "_blog_v_blocks_text" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" uuid NOT NULL,
|
||||||
|
"_path" text NOT NULL,
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"content" jsonb,
|
||||||
|
"width" "enum__blog_v_blocks_text_width" DEFAULT '1/2',
|
||||||
|
"_uuid" varchar,
|
||||||
|
"block_name" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "_blog_v_blocks_document" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" uuid NOT NULL,
|
||||||
|
"_path" text NOT NULL,
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"file_id" uuid,
|
||||||
|
"button" varchar DEFAULT 'Download Flyer',
|
||||||
|
"_uuid" varchar,
|
||||||
|
"block_name" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "_blog_v_blocks_donation" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" uuid NOT NULL,
|
||||||
|
"_path" text NOT NULL,
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"_uuid" varchar,
|
||||||
|
"block_name" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "_blog_v_blocks_contactform" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" uuid NOT NULL,
|
||||||
|
"_path" text NOT NULL,
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"title" varchar DEFAULT 'Ich bin dabei!',
|
||||||
|
"description" varchar DEFAULT 'Um dich anzumelden oder uns zu unterstützen, fülle bitte das Kontaktformular aus. Wir freuen uns sehr, dass du Teil unserer Gemeinschaft bist und mit deinem Engagement dazu beiträgst, unsere Ziele zu erreichen. Solltest du Fragen haben oder weitere Informationen benötigen, zögere nicht, uns zu kontaktieren – wir sind gerne für dich da!',
|
||||||
|
"email" varchar DEFAULT 'kontakt@mutter-teresa-chemnitz.de',
|
||||||
|
"_uuid" varchar,
|
||||||
|
"block_name" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "_blog_v_blocks_gallery_items" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" uuid NOT NULL,
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"photo_id" uuid,
|
||||||
|
"_uuid" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "_blog_v_blocks_gallery" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" uuid NOT NULL,
|
||||||
|
"_path" text NOT NULL,
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"_uuid" varchar,
|
||||||
|
"block_name" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "_blog_v_blocks_youtube" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" uuid NOT NULL,
|
||||||
|
"_path" text NOT NULL,
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"youtube_id" varchar,
|
||||||
|
"_uuid" varchar,
|
||||||
|
"block_name" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "_blog_v_blocks_button" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" uuid NOT NULL,
|
||||||
|
"_path" text NOT NULL,
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"text" varchar,
|
||||||
|
"url" varchar,
|
||||||
|
"_uuid" varchar,
|
||||||
|
"block_name" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "_blog_v" (
|
||||||
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
"parent_id" uuid,
|
||||||
|
"version_photo_id" uuid,
|
||||||
|
"version_title" varchar,
|
||||||
|
"version_content_excerpt" varchar,
|
||||||
|
"version_configuration_show_on_frontpage" boolean DEFAULT true,
|
||||||
|
"version_configuration_display_from_date" timestamp(3) with time zone,
|
||||||
|
"version_configuration_display_till_date" timestamp(3) with time zone,
|
||||||
|
"version_updated_at" timestamp(3) with time zone,
|
||||||
|
"version_created_at" timestamp(3) with time zone,
|
||||||
|
"version__status" "enum__blog_v_version_status" DEFAULT 'draft',
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"latest" boolean,
|
||||||
|
"autosave" boolean
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "_blog_v_rels" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"order" integer,
|
||||||
|
"parent_id" uuid NOT NULL,
|
||||||
|
"path" varchar NOT NULL,
|
||||||
|
"parish_id" uuid
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE "announcement" ALTER COLUMN "date" SET DEFAULT '2026-03-15T14:38:00.254Z';
|
||||||
|
ALTER TABLE "calendar" ALTER COLUMN "date" SET DEFAULT '2026-03-15T14:38:00.534Z';
|
||||||
|
ALTER TABLE "blog_blocks_text" ALTER COLUMN "content" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_text" ALTER COLUMN "width" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_document" ALTER COLUMN "file_id" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_document" ALTER COLUMN "button" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_contactform" ALTER COLUMN "title" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_contactform" ALTER COLUMN "description" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_contactform" ALTER COLUMN "email" SET DEFAULT 'kontakt@mutter-teresa-chemnitz.de';
|
||||||
|
ALTER TABLE "blog_blocks_contactform" ALTER COLUMN "email" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_gallery_items" ALTER COLUMN "photo_id" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_youtube" ALTER COLUMN "youtube_id" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_button" ALTER COLUMN "text" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_button" ALTER COLUMN "url" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog" ALTER COLUMN "title" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog" ALTER COLUMN "content_excerpt" DROP NOT NULL;
|
||||||
|
ALTER TABLE "blog" ALTER COLUMN "configuration_show_on_frontpage" DROP NOT NULL;
|
||||||
|
ALTER TABLE "classifieds" ALTER COLUMN "until" SET DEFAULT '2026-04-09T13:38:00.592Z';
|
||||||
|
ALTER TABLE "group_blocks_contactform" ALTER COLUMN "email" SET DEFAULT 'kontakt@mutter-teresa-chemnitz.de';
|
||||||
|
ALTER TABLE "pages_blocks_contactform" ALTER COLUMN "email" SET DEFAULT 'kontakt@mutter-teresa-chemnitz.de';
|
||||||
|
ALTER TABLE "blog" ADD COLUMN "_status" "enum_blog_status" DEFAULT 'draft';
|
||||||
|
ALTER TABLE "_blog_v_blocks_text" ADD CONSTRAINT "_blog_v_blocks_text_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_blog_v"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_blocks_document" ADD CONSTRAINT "_blog_v_blocks_document_file_id_documents_id_fk" FOREIGN KEY ("file_id") REFERENCES "public"."documents"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_blocks_document" ADD CONSTRAINT "_blog_v_blocks_document_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_blog_v"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_blocks_donation" ADD CONSTRAINT "_blog_v_blocks_donation_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_blog_v"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_blocks_contactform" ADD CONSTRAINT "_blog_v_blocks_contactform_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_blog_v"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_blocks_gallery_items" ADD CONSTRAINT "_blog_v_blocks_gallery_items_photo_id_media_id_fk" FOREIGN KEY ("photo_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_blocks_gallery_items" ADD CONSTRAINT "_blog_v_blocks_gallery_items_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_blog_v_blocks_gallery"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_blocks_gallery" ADD CONSTRAINT "_blog_v_blocks_gallery_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_blog_v"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_blocks_youtube" ADD CONSTRAINT "_blog_v_blocks_youtube_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_blog_v"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_blocks_button" ADD CONSTRAINT "_blog_v_blocks_button_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_blog_v"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v" ADD CONSTRAINT "_blog_v_parent_id_blog_id_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."blog"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v" ADD CONSTRAINT "_blog_v_version_photo_id_media_id_fk" FOREIGN KEY ("version_photo_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_rels" ADD CONSTRAINT "_blog_v_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."_blog_v"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "_blog_v_rels" ADD CONSTRAINT "_blog_v_rels_parish_fk" FOREIGN KEY ("parish_id") REFERENCES "public"."parish"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
CREATE INDEX "_blog_v_blocks_text_order_idx" ON "_blog_v_blocks_text" USING btree ("_order");
|
||||||
|
CREATE INDEX "_blog_v_blocks_text_parent_id_idx" ON "_blog_v_blocks_text" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_text_path_idx" ON "_blog_v_blocks_text" USING btree ("_path");
|
||||||
|
CREATE INDEX "_blog_v_blocks_document_order_idx" ON "_blog_v_blocks_document" USING btree ("_order");
|
||||||
|
CREATE INDEX "_blog_v_blocks_document_parent_id_idx" ON "_blog_v_blocks_document" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_document_path_idx" ON "_blog_v_blocks_document" USING btree ("_path");
|
||||||
|
CREATE INDEX "_blog_v_blocks_document_file_idx" ON "_blog_v_blocks_document" USING btree ("file_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_donation_order_idx" ON "_blog_v_blocks_donation" USING btree ("_order");
|
||||||
|
CREATE INDEX "_blog_v_blocks_donation_parent_id_idx" ON "_blog_v_blocks_donation" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_donation_path_idx" ON "_blog_v_blocks_donation" USING btree ("_path");
|
||||||
|
CREATE INDEX "_blog_v_blocks_contactform_order_idx" ON "_blog_v_blocks_contactform" USING btree ("_order");
|
||||||
|
CREATE INDEX "_blog_v_blocks_contactform_parent_id_idx" ON "_blog_v_blocks_contactform" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_contactform_path_idx" ON "_blog_v_blocks_contactform" USING btree ("_path");
|
||||||
|
CREATE INDEX "_blog_v_blocks_gallery_items_order_idx" ON "_blog_v_blocks_gallery_items" USING btree ("_order");
|
||||||
|
CREATE INDEX "_blog_v_blocks_gallery_items_parent_id_idx" ON "_blog_v_blocks_gallery_items" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_gallery_items_photo_idx" ON "_blog_v_blocks_gallery_items" USING btree ("photo_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_gallery_order_idx" ON "_blog_v_blocks_gallery" USING btree ("_order");
|
||||||
|
CREATE INDEX "_blog_v_blocks_gallery_parent_id_idx" ON "_blog_v_blocks_gallery" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_gallery_path_idx" ON "_blog_v_blocks_gallery" USING btree ("_path");
|
||||||
|
CREATE INDEX "_blog_v_blocks_youtube_order_idx" ON "_blog_v_blocks_youtube" USING btree ("_order");
|
||||||
|
CREATE INDEX "_blog_v_blocks_youtube_parent_id_idx" ON "_blog_v_blocks_youtube" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_youtube_path_idx" ON "_blog_v_blocks_youtube" USING btree ("_path");
|
||||||
|
CREATE INDEX "_blog_v_blocks_button_order_idx" ON "_blog_v_blocks_button" USING btree ("_order");
|
||||||
|
CREATE INDEX "_blog_v_blocks_button_parent_id_idx" ON "_blog_v_blocks_button" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX "_blog_v_blocks_button_path_idx" ON "_blog_v_blocks_button" USING btree ("_path");
|
||||||
|
CREATE INDEX "_blog_v_parent_idx" ON "_blog_v" USING btree ("parent_id");
|
||||||
|
CREATE INDEX "_blog_v_version_version_photo_idx" ON "_blog_v" USING btree ("version_photo_id");
|
||||||
|
CREATE INDEX "_blog_v_version_version_updated_at_idx" ON "_blog_v" USING btree ("version_updated_at");
|
||||||
|
CREATE INDEX "_blog_v_version_version_created_at_idx" ON "_blog_v" USING btree ("version_created_at");
|
||||||
|
CREATE INDEX "_blog_v_version_version__status_idx" ON "_blog_v" USING btree ("version__status");
|
||||||
|
CREATE INDEX "_blog_v_created_at_idx" ON "_blog_v" USING btree ("created_at");
|
||||||
|
CREATE INDEX "_blog_v_updated_at_idx" ON "_blog_v" USING btree ("updated_at");
|
||||||
|
CREATE INDEX "_blog_v_latest_idx" ON "_blog_v" USING btree ("latest");
|
||||||
|
CREATE INDEX "_blog_v_autosave_idx" ON "_blog_v" USING btree ("autosave");
|
||||||
|
CREATE INDEX "_blog_v_rels_order_idx" ON "_blog_v_rels" USING btree ("order");
|
||||||
|
CREATE INDEX "_blog_v_rels_parent_idx" ON "_blog_v_rels" USING btree ("parent_id");
|
||||||
|
CREATE INDEX "_blog_v_rels_path_idx" ON "_blog_v_rels" USING btree ("path");
|
||||||
|
CREATE INDEX "_blog_v_rels_parish_id_idx" ON "_blog_v_rels" USING btree ("parish_id");
|
||||||
|
CREATE INDEX "blog__status_idx" ON "blog" USING btree ("_status");`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "_blog_v_blocks_text" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "_blog_v_blocks_document" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "_blog_v_blocks_donation" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "_blog_v_blocks_contactform" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "_blog_v_blocks_gallery_items" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "_blog_v_blocks_gallery" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "_blog_v_blocks_youtube" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "_blog_v_blocks_button" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "_blog_v" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "_blog_v_rels" DISABLE ROW LEVEL SECURITY;
|
||||||
|
DROP TABLE "_blog_v_blocks_text" CASCADE;
|
||||||
|
DROP TABLE "_blog_v_blocks_document" CASCADE;
|
||||||
|
DROP TABLE "_blog_v_blocks_donation" CASCADE;
|
||||||
|
DROP TABLE "_blog_v_blocks_contactform" CASCADE;
|
||||||
|
DROP TABLE "_blog_v_blocks_gallery_items" CASCADE;
|
||||||
|
DROP TABLE "_blog_v_blocks_gallery" CASCADE;
|
||||||
|
DROP TABLE "_blog_v_blocks_youtube" CASCADE;
|
||||||
|
DROP TABLE "_blog_v_blocks_button" CASCADE;
|
||||||
|
DROP TABLE "_blog_v" CASCADE;
|
||||||
|
DROP TABLE "_blog_v_rels" CASCADE;
|
||||||
|
DROP INDEX "blog__status_idx";
|
||||||
|
ALTER TABLE "announcement" ALTER COLUMN "date" SET DEFAULT '2026-03-15T10:58:14.115Z';
|
||||||
|
ALTER TABLE "calendar" ALTER COLUMN "date" SET DEFAULT '2026-03-15T10:58:14.432Z';
|
||||||
|
ALTER TABLE "blog_blocks_text" ALTER COLUMN "content" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_text" ALTER COLUMN "width" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_document" ALTER COLUMN "file_id" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_document" ALTER COLUMN "button" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_contactform" ALTER COLUMN "title" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_contactform" ALTER COLUMN "description" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_contactform" ALTER COLUMN "email" DROP DEFAULT;
|
||||||
|
ALTER TABLE "blog_blocks_contactform" ALTER COLUMN "email" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_gallery_items" ALTER COLUMN "photo_id" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_youtube" ALTER COLUMN "youtube_id" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_button" ALTER COLUMN "text" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog_blocks_button" ALTER COLUMN "url" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog" ALTER COLUMN "title" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog" ALTER COLUMN "content_excerpt" SET NOT NULL;
|
||||||
|
ALTER TABLE "blog" ALTER COLUMN "configuration_show_on_frontpage" SET NOT NULL;
|
||||||
|
ALTER TABLE "classifieds" ALTER COLUMN "until" SET DEFAULT '2026-04-09T09:58:14.493Z';
|
||||||
|
ALTER TABLE "group_blocks_contactform" ALTER COLUMN "email" DROP DEFAULT;
|
||||||
|
ALTER TABLE "pages_blocks_contactform" ALTER COLUMN "email" DROP DEFAULT;
|
||||||
|
ALTER TABLE "blog" DROP COLUMN "_status";
|
||||||
|
DROP TYPE "public"."enum_blog_status";
|
||||||
|
DROP TYPE "public"."enum__blog_v_blocks_text_width";
|
||||||
|
DROP TYPE "public"."enum__blog_v_version_status";`)
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ import * as migration_20260106_103529_donation_appeal from './20260106_103529_do
|
||||||
import * as migration_20260205_155735_version_bump from './20260205_155735_version_bump';
|
import * as migration_20260205_155735_version_bump from './20260205_155735_version_bump';
|
||||||
import * as migration_20260309_111617_many_new_features from './20260309_111617_many_new_features';
|
import * as migration_20260309_111617_many_new_features from './20260309_111617_many_new_features';
|
||||||
import * as migration_20260310_105814 from './20260310_105814';
|
import * as migration_20260310_105814 from './20260310_105814';
|
||||||
|
import * as migration_20260310_143800 from './20260310_143800';
|
||||||
|
|
||||||
export const migrations = [
|
export const migrations = [
|
||||||
{
|
{
|
||||||
|
|
@ -118,6 +119,11 @@ export const migrations = [
|
||||||
{
|
{
|
||||||
up: migration_20260310_105814.up,
|
up: migration_20260310_105814.up,
|
||||||
down: migration_20260310_105814.down,
|
down: migration_20260310_105814.down,
|
||||||
name: '20260310_105814'
|
name: '20260310_105814',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
up: migration_20260310_143800.up,
|
||||||
|
down: migration_20260310_143800.down,
|
||||||
|
name: '20260310_143800'
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -468,6 +468,7 @@ export interface Blog {
|
||||||
};
|
};
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
|
_status?: ('draft' | 'published') | null;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
|
@ -1298,6 +1299,7 @@ export interface BlogSelect<T extends boolean = true> {
|
||||||
};
|
};
|
||||||
updatedAt?: T;
|
updatedAt?: T;
|
||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
|
_status?: T;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,11 @@ export default buildConfig({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
livePreview: {
|
||||||
|
url: 'http://localhost:3000',
|
||||||
|
collections: ['blog'],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
collections: [
|
collections: [
|
||||||
Parish,
|
Parish,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue