feature: collapsible

This commit is contained in:
Benno Tielen 2026-04-16 14:25:00 +02:00
parent 2efcb5f672
commit 891da86f08
15 changed files with 48454 additions and 1 deletions

View file

@ -9,6 +9,8 @@ import { ButtonBlock } from '@/collections/blocks/Button'
import { YoutubePlayerBlock } from '@/collections/blocks/YoutubePlayer' import { YoutubePlayerBlock } from '@/collections/blocks/YoutubePlayer'
import { isPublishedPublic } from '@/collections/access/public' import { isPublishedPublic } from '@/collections/access/public'
import { ImageCardsBlock } from '@/collections/blocks/ImageCards' import { ImageCardsBlock } from '@/collections/blocks/ImageCards'
import { CollapsiblesBlock } from '@/collections/blocks/Collapsibles'
import { TitleBlock } from '@/collections/blocks/Title'
export const Groups: CollectionConfig = { export const Groups: CollectionConfig = {
slug: 'group', slug: 'group',
@ -79,6 +81,7 @@ export const Groups: CollectionConfig = {
name: 'content', name: 'content',
type: 'blocks', type: 'blocks',
blocks: [ blocks: [
TitleBlock,
ParagraphBlock, ParagraphBlock,
GalleryBlock, GalleryBlock,
DocumentBlock, DocumentBlock,
@ -87,6 +90,7 @@ export const Groups: CollectionConfig = {
ContactformBlock, ContactformBlock,
ButtonBlock, ButtonBlock,
ImageCardsBlock, ImageCardsBlock,
CollapsiblesBlock,
] ]
} }
], ],

View file

@ -17,6 +17,7 @@ import { HorizontalRuleBlock } from '@/collections/blocks/HorizontalRule'
import { BlogSliderBlock } from '@/collections/blocks/BlogSlider' import { BlogSliderBlock } from '@/collections/blocks/BlogSlider'
import { MassTimesBlock } from '@/collections/blocks/MassTimes' import { MassTimesBlock } from '@/collections/blocks/MassTimes'
import { CollapsibleImageWithTextBlock } from '@/collections/blocks/CollapsibleImageWithText' import { CollapsibleImageWithTextBlock } from '@/collections/blocks/CollapsibleImageWithText'
import { CollapsiblesBlock } from '@/collections/blocks/Collapsibles'
import { EventsBlock } from '@/collections/blocks/Events' import { EventsBlock } from '@/collections/blocks/Events'
import { PublicationAndNewsletterBlock } from '@/collections/blocks/PublicationAndNewsletter' import { PublicationAndNewsletterBlock } from '@/collections/blocks/PublicationAndNewsletter'
import { ContactPersonBlock } from '@/collections/blocks/ContactPersonBlock' import { ContactPersonBlock } from '@/collections/blocks/ContactPersonBlock'
@ -99,6 +100,7 @@ export const Pages: CollectionConfig = {
HorizontalRuleBlock, HorizontalRuleBlock,
BlogSliderBlock, BlogSliderBlock,
CollapsibleImageWithTextBlock, CollapsibleImageWithTextBlock,
CollapsiblesBlock,
MassTimesBlock, MassTimesBlock,
EventsBlock, EventsBlock,
ContactPersonBlock, ContactPersonBlock,

View file

@ -7,6 +7,7 @@ import { YoutubePlayerBlock } from '@/collections/blocks/YoutubePlayer'
import { DonationAppeal } from '@/collections/blocks/DonationAppeal' import { DonationAppeal } from '@/collections/blocks/DonationAppeal'
import { ImageCardsBlock } from '@/collections/blocks/ImageCards' import { ImageCardsBlock } from '@/collections/blocks/ImageCards'
import { TitleBlock } from '@/collections/blocks/Title' import { TitleBlock } from '@/collections/blocks/Title'
import { CollapsiblesBlock } from '@/collections/blocks/Collapsibles'
import { isPublishedPublic } from '@/collections/access/public' import { isPublishedPublic } from '@/collections/access/public'
export const Parish: CollectionConfig = { export const Parish: CollectionConfig = {
@ -123,6 +124,7 @@ export const Parish: CollectionConfig = {
DonationAppeal, DonationAppeal,
ImageCardsBlock, ImageCardsBlock,
TitleBlock, TitleBlock,
CollapsiblesBlock,
] ]
}, },
{ {

View file

@ -0,0 +1,47 @@
import { Block } from 'payload'
export const CollapsiblesBlock: Block = {
slug: 'collapsibles',
labels: {
singular: {
de: 'Aufklappbare Liste',
},
plural: {
de: 'Aufklappbare Listen',
},
},
fields: [
{
name: 'items',
type: 'array',
required: true,
minRows: 1,
labels: {
singular: {
de: 'Eintrag',
},
plural: {
de: 'Einträge',
},
},
fields: [
{
name: 'title',
type: 'text',
required: true,
label: {
de: 'Titel',
},
},
{
name: 'content',
type: 'richText',
required: true,
label: {
de: 'Inhalt',
},
},
],
},
],
}

View file

@ -0,0 +1,66 @@
import { Meta, StoryObj } from '@storybook/react'
import { Collapsible } from './Collapsible'
const meta: Meta<typeof Collapsible> = {
component: Collapsible,
}
type Story = StoryObj<typeof Collapsible>
export default meta
export const Default: Story = {
args: {
title: 'Wann finden die Gottesdienste statt?',
children: 'Unsere Gottesdienste finden jeden Sonntag um 10:00 Uhr statt.',
},
}
export const OpenByDefault: Story = {
args: {
title: 'Wo kann ich parken?',
defaultOpen: true,
children:
'Direkt vor der Kirche stehen Parkplätze zur Verfügung. Weitere Parkplätze finden Sie in den umliegenden Straßen.',
},
}
export const LongContent: Story = {
args: {
title: 'Wie kann ich Mitglied werden?',
children: (
<>
<p>
Um Mitglied unserer Gemeinde zu werden, können Sie sich direkt an das
Pfarrbüro wenden. Dort erhalten Sie alle notwendigen Informationen und
Formulare.
</p>
<p>
Wir freuen uns über jedes neue Mitglied und laden Sie herzlich ein,
unsere Gemeinschaft kennenzulernen. Neben den regelmäßigen
Gottesdiensten gibt es zahlreiche Gruppen und Veranstaltungen, an
denen Sie teilnehmen können.
</p>
<p>
Bei Fragen stehen Ihnen unsere Mitarbeiter gerne telefonisch, per
E-Mail oder persönlich zur Verfügung.
</p>
</>
),
},
}
export const ListOfThree: Story = {
render: () => (
<div>
<Collapsible title="Wann finden die Gottesdienste statt?">
Unsere Gottesdienste finden jeden Sonntag um 10:00 Uhr statt.
</Collapsible>
<Collapsible title="Wo kann ich parken?">
Direkt vor der Kirche stehen Parkplätze zur Verfügung.
</Collapsible>
<Collapsible title="Wie erreiche ich das Pfarrbüro?">
Das Pfarrbüro ist montags bis freitags von 9:00 bis 12:00 Uhr geöffnet.
</Collapsible>
</div>
),
}

View file

@ -0,0 +1,73 @@
'use client'
import React, { useEffect, useId, useRef, useState } from 'react'
import classNames from 'classnames'
import { CollapsibleArrow } from '@/components/CollapsibleArrow/CollapsibleArrow'
import styles from './styles.module.scss'
type CollapsibleProps = {
title: string
children: React.ReactNode
defaultOpen?: boolean
id?: string
}
export const Collapsible = ({
title,
children,
defaultOpen = false,
id,
}: CollapsibleProps) => {
const reactId = useId()
const baseId = id ?? reactId
const headerId = `${baseId}-header`
const panelId = `${baseId}-panel`
const [isOpen, setIsOpen] = useState(defaultOpen)
const [contentHeight, setContentHeight] = useState(0)
const contentRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const measure = () => {
if (contentRef.current) {
setContentHeight(contentRef.current.scrollHeight)
}
}
measure()
window.addEventListener('resize', measure)
return () => window.removeEventListener('resize', measure)
}, [children])
const toggle = () => setIsOpen(v => !v)
return (
<div className={styles.collapsible}>
<button
type="button"
id={headerId}
className={styles.header}
aria-expanded={isOpen}
aria-controls={panelId}
onClick={toggle}
>
<span className={styles.title}>{title}</span>
<span aria-hidden="true" className={styles.arrow}>
<CollapsibleArrow direction={isOpen ? 'UP' : 'DOWN'} />
</span>
</button>
<div
id={panelId}
role="region"
aria-labelledby={headerId}
aria-hidden={!isOpen}
inert={!isOpen}
ref={contentRef}
className={classNames(styles.content, { [styles.open]: isOpen })}
style={{ maxHeight: isOpen ? contentHeight : 0 }}
>
<div className={styles.inner}>{children}</div>
</div>
</div>
)
}

View file

@ -0,0 +1,59 @@
@import 'template.scss';
.collapsible {
border-bottom: 1px solid $border-color-light;
}
.header {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
padding: 20px 0;
min-height: 44px;
background: transparent;
border: 0;
font-family: inherit;
color: $base-color;
cursor: pointer;
text-align: left;
-webkit-tap-highlight-color: transparent;
}
.header:focus {
outline: none;
}
.header:focus-visible {
outline: 2px solid $base-color;
outline-offset: 4px;
}
.title {
font-size: 22px;
font-weight: bold;
line-height: 1.4;
flex: 1 1 auto;
}
.arrow {
display: inline-flex;
flex: 0 0 auto;
}
.content {
max-height: 0;
overflow: hidden;
transition: max-height 400ms ease-in-out;
}
.inner {
padding: 0 0 20px;
}
@media (prefers-reduced-motion: reduce) {
.content {
transition: none;
}
}

View file

@ -14,6 +14,7 @@ import { Banner } from '@/components/Banner/Banner'
import { MainText } from '@/components/MainText/MainText' import { MainText } from '@/components/MainText/MainText'
import { HR } from '@/components/HorizontalRule/HorizontalRule' import { HR } from '@/components/HorizontalRule/HorizontalRule'
import { CollapsibleImageWithText } from '@/compositions/CollapsibleImageWithText/CollapsibleImageWithText' import { CollapsibleImageWithText } from '@/compositions/CollapsibleImageWithText/CollapsibleImageWithText'
import { Collapsible } from '@/components/Collapsible/Collapsible'
import { PublicationAndNewsletter } from '@/compositions/PublicationAndNewsletter/PublicationAndNewsletter' import { PublicationAndNewsletter } from '@/compositions/PublicationAndNewsletter/PublicationAndNewsletter'
import { ContactPersonCard } from '@/components/ContactPersonCard/ContactPersonCard' import { ContactPersonCard } from '@/components/ContactPersonCard/ContactPersonCard'
import { getPhoto } from '@/utils/dto/gallery' import { getPhoto } from '@/utils/dto/gallery'
@ -226,6 +227,20 @@ export function Blocks({ content }: BlocksProps) {
) )
} }
if (item.blockType === 'collapsibles') {
return (
<Section key={item.id} padding={'small'}>
<Container>
{item.items.map(entry => (
<Collapsible key={entry.id} title={entry.title}>
<HTMLText width={'3/4'} data={entry.content} />
</Collapsible>
))}
</Container>
</Section>
)
}
if (item.blockType === 'events') { if (item.blockType === 'events') {
return ( return (
<EventsBlock <EventsBlock

View file

@ -8,6 +8,7 @@ import { YoutubePlayer } from '@/components/YoutubePlayer/YoutubePlayer'
import { DonationAppeal } from '@/components/DonationAppeal/DonationAppeal' import { DonationAppeal } from '@/components/DonationAppeal/DonationAppeal'
import { ImageCardsBlock } from '@/compositions/Blocks/ImageCardsBlock' import { ImageCardsBlock } from '@/compositions/Blocks/ImageCardsBlock'
import { Title } from '@/components/Title/Title' import { Title } from '@/components/Title/Title'
import { Collapsible } from '@/components/Collapsible/Collapsible'
type BlocksProps = { type BlocksProps = {
content: Parish['content'] content: Parish['content']
@ -75,6 +76,20 @@ export function ParishBlocks({ content }: BlocksProps) {
) )
} }
if (item.blockType === "collapsibles") {
return (
<Section key={item.id} padding={"small"}>
<Container>
{item.items.map(entry => (
<Collapsible key={entry.id} title={entry.title}>
<HTMLText width={"3/4"} data={entry.content} />
</Collapsible>
))}
</Container>
</Section>
)
}
if (item.blockType === "donationAppeal") { if (item.blockType === "donationAppeal") {
return <Section key={item.id} padding={"small"}> return <Section key={item.id} padding={"small"}>
<Container> <Container>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,183 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
CREATE TABLE "parish_blocks_collapsibles_items" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"title" varchar,
"content" jsonb
);
CREATE TABLE "parish_blocks_collapsibles" (
"_order" integer NOT NULL,
"_parent_id" uuid NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"block_name" varchar
);
CREATE TABLE "_parish_v_blocks_collapsibles_items" (
"_order" integer NOT NULL,
"_parent_id" uuid NOT NULL,
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"title" varchar,
"content" jsonb,
"_uuid" varchar
);
CREATE TABLE "_parish_v_blocks_collapsibles" (
"_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 "group_blocks_collapsibles_items" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"title" varchar,
"content" jsonb
);
CREATE TABLE "group_blocks_collapsibles" (
"_order" integer NOT NULL,
"_parent_id" uuid NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"block_name" varchar
);
CREATE TABLE "_group_v_blocks_collapsibles_items" (
"_order" integer NOT NULL,
"_parent_id" uuid NOT NULL,
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"title" varchar,
"content" jsonb,
"_uuid" varchar
);
CREATE TABLE "_group_v_blocks_collapsibles" (
"_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 "pages_blocks_collapsibles_items" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"title" varchar,
"content" jsonb
);
CREATE TABLE "pages_blocks_collapsibles" (
"_order" integer NOT NULL,
"_parent_id" uuid NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"block_name" varchar
);
CREATE TABLE "_pages_v_blocks_collapsibles_items" (
"_order" integer NOT NULL,
"_parent_id" uuid NOT NULL,
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"title" varchar,
"content" jsonb,
"_uuid" varchar
);
CREATE TABLE "_pages_v_blocks_collapsibles" (
"_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
);
ALTER TABLE "announcement" ALTER COLUMN "date" SET DEFAULT '2026-04-19T11:54:45.762Z';
ALTER TABLE "calendar" ALTER COLUMN "date" SET DEFAULT '2026-04-19T11:54:46.057Z';
ALTER TABLE "classifieds" ALTER COLUMN "until" SET DEFAULT '2026-05-16T11:54:46.114Z';
ALTER TABLE "parish_blocks_collapsibles_items" ADD CONSTRAINT "parish_blocks_collapsibles_items_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."parish_blocks_collapsibles"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "parish_blocks_collapsibles" ADD CONSTRAINT "parish_blocks_collapsibles_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."parish"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "_parish_v_blocks_collapsibles_items" ADD CONSTRAINT "_parish_v_blocks_collapsibles_items_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_parish_v_blocks_collapsibles"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "_parish_v_blocks_collapsibles" ADD CONSTRAINT "_parish_v_blocks_collapsibles_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_parish_v"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "group_blocks_collapsibles_items" ADD CONSTRAINT "group_blocks_collapsibles_items_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."group_blocks_collapsibles"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "group_blocks_collapsibles" ADD CONSTRAINT "group_blocks_collapsibles_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."group"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "_group_v_blocks_collapsibles_items" ADD CONSTRAINT "_group_v_blocks_collapsibles_items_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_group_v_blocks_collapsibles"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "_group_v_blocks_collapsibles" ADD CONSTRAINT "_group_v_blocks_collapsibles_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_group_v"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_collapsibles_items" ADD CONSTRAINT "pages_blocks_collapsibles_items_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_collapsibles"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_collapsibles" ADD CONSTRAINT "pages_blocks_collapsibles_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "_pages_v_blocks_collapsibles_items" ADD CONSTRAINT "_pages_v_blocks_collapsibles_items_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_pages_v_blocks_collapsibles"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "_pages_v_blocks_collapsibles" ADD CONSTRAINT "_pages_v_blocks_collapsibles_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_pages_v"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "parish_blocks_collapsibles_items_order_idx" ON "parish_blocks_collapsibles_items" USING btree ("_order");
CREATE INDEX "parish_blocks_collapsibles_items_parent_id_idx" ON "parish_blocks_collapsibles_items" USING btree ("_parent_id");
CREATE INDEX "parish_blocks_collapsibles_order_idx" ON "parish_blocks_collapsibles" USING btree ("_order");
CREATE INDEX "parish_blocks_collapsibles_parent_id_idx" ON "parish_blocks_collapsibles" USING btree ("_parent_id");
CREATE INDEX "parish_blocks_collapsibles_path_idx" ON "parish_blocks_collapsibles" USING btree ("_path");
CREATE INDEX "_parish_v_blocks_collapsibles_items_order_idx" ON "_parish_v_blocks_collapsibles_items" USING btree ("_order");
CREATE INDEX "_parish_v_blocks_collapsibles_items_parent_id_idx" ON "_parish_v_blocks_collapsibles_items" USING btree ("_parent_id");
CREATE INDEX "_parish_v_blocks_collapsibles_order_idx" ON "_parish_v_blocks_collapsibles" USING btree ("_order");
CREATE INDEX "_parish_v_blocks_collapsibles_parent_id_idx" ON "_parish_v_blocks_collapsibles" USING btree ("_parent_id");
CREATE INDEX "_parish_v_blocks_collapsibles_path_idx" ON "_parish_v_blocks_collapsibles" USING btree ("_path");
CREATE INDEX "group_blocks_collapsibles_items_order_idx" ON "group_blocks_collapsibles_items" USING btree ("_order");
CREATE INDEX "group_blocks_collapsibles_items_parent_id_idx" ON "group_blocks_collapsibles_items" USING btree ("_parent_id");
CREATE INDEX "group_blocks_collapsibles_order_idx" ON "group_blocks_collapsibles" USING btree ("_order");
CREATE INDEX "group_blocks_collapsibles_parent_id_idx" ON "group_blocks_collapsibles" USING btree ("_parent_id");
CREATE INDEX "group_blocks_collapsibles_path_idx" ON "group_blocks_collapsibles" USING btree ("_path");
CREATE INDEX "_group_v_blocks_collapsibles_items_order_idx" ON "_group_v_blocks_collapsibles_items" USING btree ("_order");
CREATE INDEX "_group_v_blocks_collapsibles_items_parent_id_idx" ON "_group_v_blocks_collapsibles_items" USING btree ("_parent_id");
CREATE INDEX "_group_v_blocks_collapsibles_order_idx" ON "_group_v_blocks_collapsibles" USING btree ("_order");
CREATE INDEX "_group_v_blocks_collapsibles_parent_id_idx" ON "_group_v_blocks_collapsibles" USING btree ("_parent_id");
CREATE INDEX "_group_v_blocks_collapsibles_path_idx" ON "_group_v_blocks_collapsibles" USING btree ("_path");
CREATE INDEX "pages_blocks_collapsibles_items_order_idx" ON "pages_blocks_collapsibles_items" USING btree ("_order");
CREATE INDEX "pages_blocks_collapsibles_items_parent_id_idx" ON "pages_blocks_collapsibles_items" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_collapsibles_order_idx" ON "pages_blocks_collapsibles" USING btree ("_order");
CREATE INDEX "pages_blocks_collapsibles_parent_id_idx" ON "pages_blocks_collapsibles" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_collapsibles_path_idx" ON "pages_blocks_collapsibles" USING btree ("_path");
CREATE INDEX "_pages_v_blocks_collapsibles_items_order_idx" ON "_pages_v_blocks_collapsibles_items" USING btree ("_order");
CREATE INDEX "_pages_v_blocks_collapsibles_items_parent_id_idx" ON "_pages_v_blocks_collapsibles_items" USING btree ("_parent_id");
CREATE INDEX "_pages_v_blocks_collapsibles_order_idx" ON "_pages_v_blocks_collapsibles" USING btree ("_order");
CREATE INDEX "_pages_v_blocks_collapsibles_parent_id_idx" ON "_pages_v_blocks_collapsibles" USING btree ("_parent_id");
CREATE INDEX "_pages_v_blocks_collapsibles_path_idx" ON "_pages_v_blocks_collapsibles" USING btree ("_path");`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
ALTER TABLE "parish_blocks_collapsibles_items" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "parish_blocks_collapsibles" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "_parish_v_blocks_collapsibles_items" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "_parish_v_blocks_collapsibles" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "group_blocks_collapsibles_items" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "group_blocks_collapsibles" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "_group_v_blocks_collapsibles_items" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "_group_v_blocks_collapsibles" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "pages_blocks_collapsibles_items" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "pages_blocks_collapsibles" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "_pages_v_blocks_collapsibles_items" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "_pages_v_blocks_collapsibles" DISABLE ROW LEVEL SECURITY;
DROP TABLE "parish_blocks_collapsibles_items" CASCADE;
DROP TABLE "parish_blocks_collapsibles" CASCADE;
DROP TABLE "_parish_v_blocks_collapsibles_items" CASCADE;
DROP TABLE "_parish_v_blocks_collapsibles" CASCADE;
DROP TABLE "group_blocks_collapsibles_items" CASCADE;
DROP TABLE "group_blocks_collapsibles" CASCADE;
DROP TABLE "_group_v_blocks_collapsibles_items" CASCADE;
DROP TABLE "_group_v_blocks_collapsibles" CASCADE;
DROP TABLE "pages_blocks_collapsibles_items" CASCADE;
DROP TABLE "pages_blocks_collapsibles" CASCADE;
DROP TABLE "_pages_v_blocks_collapsibles_items" CASCADE;
DROP TABLE "_pages_v_blocks_collapsibles" CASCADE;
ALTER TABLE "announcement" ALTER COLUMN "date" SET DEFAULT '2026-04-19T09:09:53.986Z';
ALTER TABLE "calendar" ALTER COLUMN "date" SET DEFAULT '2026-04-19T09:09:54.280Z';
ALTER TABLE "classifieds" ALTER COLUMN "until" SET DEFAULT '2026-05-16T09:09:54.338Z';`)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
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_group_blocks_title_size" AS ENUM('xl', 'lg', 'md', 'sm');
CREATE TYPE "public"."enum_group_blocks_title_align" AS ENUM('left', 'center');
CREATE TYPE "public"."enum_group_blocks_title_color" AS ENUM('base', 'shade1', 'shade2', 'shade3', 'contrast', 'contrastShade1');
CREATE TYPE "public"."enum__group_v_blocks_title_size" AS ENUM('xl', 'lg', 'md', 'sm');
CREATE TYPE "public"."enum__group_v_blocks_title_align" AS ENUM('left', 'center');
CREATE TYPE "public"."enum__group_v_blocks_title_color" AS ENUM('base', 'shade1', 'shade2', 'shade3', 'contrast', 'contrastShade1');
CREATE TABLE "group_blocks_title" (
"_order" integer NOT NULL,
"_parent_id" uuid NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"title" varchar,
"subtitle" varchar,
"size" "enum_group_blocks_title_size" DEFAULT 'lg',
"align" "enum_group_blocks_title_align" DEFAULT 'left',
"color" "enum_group_blocks_title_color" DEFAULT 'base',
"block_name" varchar
);
CREATE TABLE "_group_v_blocks_title" (
"_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,
"subtitle" varchar,
"size" "enum__group_v_blocks_title_size" DEFAULT 'lg',
"align" "enum__group_v_blocks_title_align" DEFAULT 'left',
"color" "enum__group_v_blocks_title_color" DEFAULT 'base',
"_uuid" varchar,
"block_name" varchar
);
ALTER TABLE "announcement" ALTER COLUMN "date" SET DEFAULT '2026-04-19T12:14:50.471Z';
ALTER TABLE "calendar" ALTER COLUMN "date" SET DEFAULT '2026-04-19T12:14:50.803Z';
ALTER TABLE "classifieds" ALTER COLUMN "until" SET DEFAULT '2026-05-16T12:14:50.859Z';
ALTER TABLE "group_blocks_title" ADD CONSTRAINT "group_blocks_title_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."group"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "_group_v_blocks_title" ADD CONSTRAINT "_group_v_blocks_title_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."_group_v"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "group_blocks_title_order_idx" ON "group_blocks_title" USING btree ("_order");
CREATE INDEX "group_blocks_title_parent_id_idx" ON "group_blocks_title" USING btree ("_parent_id");
CREATE INDEX "group_blocks_title_path_idx" ON "group_blocks_title" USING btree ("_path");
CREATE INDEX "_group_v_blocks_title_order_idx" ON "_group_v_blocks_title" USING btree ("_order");
CREATE INDEX "_group_v_blocks_title_parent_id_idx" ON "_group_v_blocks_title" USING btree ("_parent_id");
CREATE INDEX "_group_v_blocks_title_path_idx" ON "_group_v_blocks_title" USING btree ("_path");`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
ALTER TABLE "group_blocks_title" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "_group_v_blocks_title" DISABLE ROW LEVEL SECURITY;
DROP TABLE "group_blocks_title" CASCADE;
DROP TABLE "_group_v_blocks_title" CASCADE;
ALTER TABLE "announcement" ALTER COLUMN "date" SET DEFAULT '2026-04-19T11:54:45.762Z';
ALTER TABLE "calendar" ALTER COLUMN "date" SET DEFAULT '2026-04-19T11:54:46.057Z';
ALTER TABLE "classifieds" ALTER COLUMN "until" SET DEFAULT '2026-05-16T11:54:46.114Z';
DROP TYPE "public"."enum_group_blocks_title_size";
DROP TYPE "public"."enum_group_blocks_title_align";
DROP TYPE "public"."enum_group_blocks_title_color";
DROP TYPE "public"."enum__group_v_blocks_title_size";
DROP TYPE "public"."enum__group_v_blocks_title_align";
DROP TYPE "public"."enum__group_v_blocks_title_color";`)
}

View file

@ -34,6 +34,8 @@ import * as migration_20260413_093410_search from './20260413_093410_search';
import * as migration_20260413_094618_search_pages from './20260413_094618_search_pages'; import * as migration_20260413_094618_search_pages from './20260413_094618_search_pages';
import * as migration_20260413_122020 from './20260413_122020'; import * as migration_20260413_122020 from './20260413_122020';
import * as migration_20260416_090954_group_image_cards from './20260416_090954_group_image_cards'; import * as migration_20260416_090954_group_image_cards from './20260416_090954_group_image_cards';
import * as migration_20260416_115446 from './20260416_115446';
import * as migration_20260416_121451 from './20260416_121451';
export const migrations = [ export const migrations = [
{ {
@ -214,6 +216,16 @@ export const migrations = [
{ {
up: migration_20260416_090954_group_image_cards.up, up: migration_20260416_090954_group_image_cards.up,
down: migration_20260416_090954_group_image_cards.down, down: migration_20260416_090954_group_image_cards.down,
name: '20260416_090954_group_image_cards' name: '20260416_090954_group_image_cards',
},
{
up: migration_20260416_115446.up,
down: migration_20260416_115446.down,
name: '20260416_115446',
},
{
up: migration_20260416_121451.up,
down: migration_20260416_121451.down,
name: '20260416_121451'
}, },
]; ];

View file

@ -270,6 +270,30 @@ export interface Parish {
blockName?: string | null; blockName?: string | null;
blockType: 'title'; blockType: 'title';
} }
| {
items: {
title: string;
content: {
root: {
type: string;
children: {
type: any;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
};
id?: string | null;
}[];
id?: string | null;
blockName?: string | null;
blockType: 'collapsibles';
}
)[] )[]
| null; | null;
contact: string; contact: string;
@ -570,6 +594,30 @@ export interface Page {
blockName?: string | null; blockName?: string | null;
blockType: 'collapsibleImageWithText'; blockType: 'collapsibleImageWithText';
} }
| {
items: {
title: string;
content: {
root: {
type: string;
children: {
type: any;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
};
id?: string | null;
}[];
id?: string | null;
blockName?: string | null;
blockType: 'collapsibles';
}
| { | {
title?: string | null; title?: string | null;
subtitle?: string | null; subtitle?: string | null;
@ -668,6 +716,16 @@ export interface Group {
} | null; } | null;
content?: content?:
| ( | (
| {
title: string;
subtitle?: string | null;
size?: ('xl' | 'lg' | 'md' | 'sm') | null;
align?: ('left' | 'center') | null;
color: 'base' | 'shade1' | 'shade2' | 'shade3' | 'contrast' | 'contrastShade1';
id?: string | null;
blockName?: string | null;
blockType: 'title';
}
| { | {
content: { content: {
root: { root: {
@ -754,6 +812,30 @@ export interface Group {
blockName?: string | null; blockName?: string | null;
blockType: 'imageCards'; blockType: 'imageCards';
} }
| {
items: {
title: string;
content: {
root: {
type: string;
children: {
type: any;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
};
id?: string | null;
}[];
id?: string | null;
blockName?: string | null;
blockType: 'collapsibles';
}
)[] )[]
| null; | null;
updatedAt: string; updatedAt: string;
@ -1464,6 +1546,19 @@ export interface ParishSelect<T extends boolean = true> {
id?: T; id?: T;
blockName?: T; blockName?: T;
}; };
collapsibles?:
| T
| {
items?:
| T
| {
title?: T;
content?: T;
id?: T;
};
id?: T;
blockName?: T;
};
}; };
contact?: T; contact?: T;
photo?: T; photo?: T;
@ -1739,6 +1834,17 @@ export interface GroupSelect<T extends boolean = true> {
content?: content?:
| T | T
| { | {
title?:
| T
| {
title?: T;
subtitle?: T;
size?: T;
align?: T;
color?: T;
id?: T;
blockName?: T;
};
text?: text?:
| T | T
| { | {
@ -1812,6 +1918,19 @@ export interface GroupSelect<T extends boolean = true> {
id?: T; id?: T;
blockName?: T; blockName?: T;
}; };
collapsibles?:
| T
| {
items?:
| T
| {
title?: T;
content?: T;
id?: T;
};
id?: T;
blockName?: T;
};
}; };
updatedAt?: T; updatedAt?: T;
createdAt?: T; createdAt?: T;
@ -1970,6 +2089,19 @@ export interface PagesSelect<T extends boolean = true> {
id?: T; id?: T;
blockName?: T; blockName?: T;
}; };
collapsibles?:
| T
| {
items?:
| T
| {
title?: T;
content?: T;
id?: T;
};
id?: T;
blockName?: T;
};
massTimes?: massTimes?:
| T | T
| { | {