Initial SvelteKit frontend port of windwiderstand.de
Deploy / verify (push) Failing after 32s
Deploy / deploy (push) Has been skipped

Full parity with Astro site: content rows, post/tag routes, pagination,
event badges + OSM map, comments, Live-Search via /api/search-index,
CMS image proxy, RSS, sitemap.

Deploy: Dockerfile + docker-compose.prod.yml + Gitea Actions workflow
to build + push to git.pm86.de registry and ssh-deploy to Contabo.
This commit is contained in:
Peter Meier
2026-04-17 22:01:30 +02:00
parent 852cef0980
commit 2fef91a548
137 changed files with 28585 additions and 0 deletions
@@ -0,0 +1,77 @@
<script lang="ts">
import { getBlockLayoutClasses } from "$lib/block-layout";
import type { ImageBlockData } from "$lib/block-types";
import CmsImage from "$lib/components/CmsImage.svelte";
let { block }: { block: ImageBlockData } = $props();
/** Rohe Bild-Quelle für /cms-images (URL, //-URL oder Asset-Dateiname/Slug). */
function getRawSrc(b: ImageBlockData): string | null {
const img = b.img ?? b.image;
if (typeof img === "string") {
const s = img.trim();
if (!s) return null;
return s.startsWith("//") ? `https:${s}` : s;
}
if (img && typeof img === "object") {
const src =
(img as { src?: string }).src ?? (img as { file?: { url?: string } }).file?.url;
if (typeof src === "string" && src)
return src.startsWith("//") ? `https:${src}` : src;
}
return null;
}
const layoutClasses = $derived(getBlockLayoutClasses(block.layout));
const imageSource = $derived(block.image ?? block.img);
const rawSrc = $derived(getRawSrc(block));
$effect(() => {
if (!rawSrc && block._slug) {
console.warn("[ImageBlock] Bild nicht verfügbar:", block._slug, {
hasImage: !!block.image,
hasImg: !!block.img,
imageType: typeof block.image,
imgType: typeof block.img,
imgSrc:
block.img && typeof block.img === "object"
? (block.img as { src?: string }).src
: undefined,
imageSrc:
block.image && typeof block.image === "object"
? (block.image as { src?: string }).src
: undefined,
});
}
});
const title = $derived(
typeof imageSource === "object" && imageSource
? "description" in imageSource && imageSource.description
? imageSource.description
: "title" in imageSource
? (imageSource as { title?: string }).title
: undefined
: undefined,
);
</script>
<div class={layoutClasses} data-block-type="image" data-block-slug={block._slug}>
{#if rawSrc}
<figure class="max-w-[400px]">
<CmsImage
src={rawSrc}
width={800}
format="webp"
quality={85}
fit="contain"
alt={block.caption ?? title ?? ""}
class="w-full rounded-sm"
loading="lazy"
/>
{#if block.caption}
<figcaption class="mt-1 text-sm text-zinc-600">{block.caption}</figcaption>
{/if}
</figure>
{:else}
<p class="text-sm text-zinc-500">Bild nicht verfügbar.</p>
{/if}
</div>