diff --git a/src/lib/block-types.ts b/src/lib/block-types.ts index 0845fca..26a1750 100644 --- a/src/lib/block-types.ts +++ b/src/lib/block-types.ts @@ -140,6 +140,25 @@ export interface QuoteBlockData { layout?: BlockLayout; } +/** Zitat-Karussell (_type: "quote_carousel"). Rotiert durch aufgelöste quote-Einträge. */ +export interface QuoteCarouselBlockData { + _type?: "quote_carousel"; + _slug?: string; + headline?: string; + quotes?: Array< + | string + | { + _slug?: string; + quote?: string; + author?: string; + variant?: "left" | "right"; + } + >; + autoRotate?: boolean; + intervalSeconds?: number; + layout?: BlockLayout; +} + /** Link-Liste (_type: "link_list"). links können Slugs oder aufgelöste link-Objekte sein. */ export interface LinkListBlockData { _type?: "link_list"; diff --git a/src/lib/blog-utils.ts b/src/lib/blog-utils.ts index fe158d2..896e302 100644 --- a/src/lib/blog-utils.ts +++ b/src/lib/blog-utils.ts @@ -378,7 +378,19 @@ export async function resolvePostOverviewBlocks( if (!Array.isArray(content)) continue; for (const item of content) { if (!isPostOverviewBlock(item)) continue; - if (item.allPosts) { + const rawFilter = item.filterByTag ?? []; + const tagSlugs = Array.isArray(rawFilter) + ? rawFilter + .map((t) => + typeof t === "string" + ? t + : ((t as { _slug?: string })?._slug ?? ""), + ) + .filter(Boolean) + : []; + const hasExplicitPosts = Array.isArray(item.posts) && item.posts.length > 0; + const useAllPosts = item.allPosts || (tagSlugs.length > 0 && !hasExplicitPosts); + if (useAllPosts) { if (allPosts === null) allPosts = await getPosts({ _sort: "created", @@ -386,21 +398,11 @@ export async function resolvePostOverviewBlocks( resolve: "all", }); let list = filterHiddenPosts(sortPostsByDate(allPosts)); - const rawFilter = item.filterByTag ?? []; - const tagSlugs = Array.isArray(rawFilter) - ? rawFilter - .map((t) => - typeof t === "string" - ? t - : ((t as { _slug?: string })?._slug ?? ""), - ) - .filter(Boolean) - : []; if (tagSlugs.length) list = filterPostsByTagSlugs(list, tagSlugs); const limit = typeof item.numberItems === "number" ? item.numberItems : 9999; item.postsResolved = list.slice(0, limit); - } else if (Array.isArray(item.posts) && item.posts.length > 0) { + } else if (hasExplicitPosts && Array.isArray(item.posts)) { const first = item.posts[0]; const isResolved = typeof first === "object" && diff --git a/src/lib/components/ContentRows.svelte b/src/lib/components/ContentRows.svelte index abab0ff..1fb34f2 100644 --- a/src/lib/components/ContentRows.svelte +++ b/src/lib/components/ContentRows.svelte @@ -7,6 +7,7 @@ import ImageGalleryBlock from "./blocks/ImageGalleryBlock.svelte"; import YoutubeVideoBlock from "./blocks/YoutubeVideoBlock.svelte"; import QuoteBlock from "./blocks/QuoteBlock.svelte"; + import QuoteCarouselBlock from "./blocks/QuoteCarouselBlock.svelte"; import LinkListBlock from "./blocks/LinkListBlock.svelte"; import PostOverviewBlock from "./blocks/PostOverviewBlock.svelte"; import SearchableTextBlock from "./blocks/SearchableTextBlock.svelte"; @@ -27,6 +28,7 @@ ImageGalleryBlockData, YoutubeVideoBlockData, QuoteBlockData, + QuoteCarouselBlockData, LinkListBlockData, PostOverviewBlockData, SearchableTextBlockData, @@ -112,6 +114,8 @@ {:else if blockType(item) === "quote"} + {:else if blockType(item) === "quote_carousel"} + {:else if blockType(item) === "link_list"} {:else if blockType(item) === "post_overview"} diff --git a/src/lib/components/Footer.svelte b/src/lib/components/Footer.svelte index 11acc97..9220664 100644 --- a/src/lib/components/Footer.svelte +++ b/src/lib/components/Footer.svelte @@ -14,20 +14,6 @@ return tStatic(translations ?? null, key); } - const justifyClass = $derived( - footer?.row1JustifyContent === "end" - ? "justify-end" - : footer?.row1JustifyContent === "between" - ? "justify-between" - : footer?.row1JustifyContent === "around" - ? "justify-around" - : footer?.row1JustifyContent === "evenly" - ? "justify-evenly" - : footer?.row1JustifyContent === "start" - ? "justify-start" - : "justify-center", - ); - const hasRowContent = $derived( !!footer && ((footer.row1Content?.length ?? 0) > 0 || @@ -38,16 +24,16 @@ {#if footer}
-
+
{#if hasRowContent} -
{/if} + + diff --git a/src/lib/components/PostCard.svelte b/src/lib/components/PostCard.svelte index be3666d..5cbb84f 100644 --- a/src/lib/components/PostCard.svelte +++ b/src/lib/components/PostCard.svelte @@ -33,11 +33,21 @@ const eventDate = $derived(p.isEvent && p.eventDate ? p.eventDate : null); const locationText = $derived(p.eventLocation?.text ?? null); + + const tagSlugs = $derived( + (post.postTag ?? []).map((t) => + typeof t === "string" ? t : ((t as { _slug?: string })?._slug ?? ""), + ), + ); + const hasTerminTag = $derived(tagSlugs.includes("tag-termin")); + const isPastEvent = $derived( + hasTerminTag && !!p.eventDate && new Date(p.eventDate).getTime() < Date.now(), + );
{#if rawImg} @@ -70,6 +80,13 @@
{/if} + {#if isPastEvent} +
+ + Vergangen + +
+ {/if}
+ import Icon from "@iconify/svelte"; + import "$lib/iconify-offline"; import { getBlockLayoutClasses } from "$lib/block-layout"; import type { LinkListBlockData } from "$lib/block-types"; + type LinkEntry = { + _slug?: string; + url?: string; + linkName?: string; + icon?: string; + showText?: boolean; + newTab?: boolean; + alt?: string; + }; + let { block }: { block: LinkListBlockData } = $props(); const layoutClasses = $derived( block.layout ? getBlockLayoutClasses(block.layout) : "col-span-12 mb-4", ); - const links = $derived(block.links ?? []); + const links = $derived(((block.links ?? []) as unknown[]).filter( + (l): l is LinkEntry => typeof l === "object" && l !== null && "url" in l, + )); + const iconOnlyAll = $derived( + links.length > 0 && + links.every((l) => l.icon && l.showText === false), + ); -
+ diff --git a/src/lib/components/blocks/QuoteCarouselBlock.svelte b/src/lib/components/blocks/QuoteCarouselBlock.svelte new file mode 100644 index 0000000..174b98f --- /dev/null +++ b/src/lib/components/blocks/QuoteCarouselBlock.svelte @@ -0,0 +1,147 @@ + + + diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index 4fa772f..b2e16e6 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -154,7 +154,7 @@ export const load: LayoutServerLoad = async ({ locals }) => { try { footerData = await getFooterBySlug('footer-main', { locale: 'de', - resolve: ROW_RESOLVE, + resolve: ['all'], }); } catch { // CMS nicht erreichbar