Initial SvelteKit frontend port of windwiderstand.de
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:
@@ -0,0 +1,80 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* TopBanner: Fullwidth-Banner mit Bild (über RustyCMS-Transform-API aufgelöst), optionalem Text
|
||||
* und Titel/Subtitle der aktuellen Page (Markdown).
|
||||
*/
|
||||
import { marked } from "marked";
|
||||
import type { FullwidthBannerEntry } from "$lib/cms";
|
||||
|
||||
marked.setOptions({ gfm: true });
|
||||
|
||||
interface Props {
|
||||
banner: FullwidthBannerEntry | null;
|
||||
resolvedImages?: string[];
|
||||
/** Headline der Page (Markdown). */
|
||||
headline?: string;
|
||||
/** Subheadline der Page (Markdown). */
|
||||
subheadline?: string;
|
||||
}
|
||||
|
||||
let { banner = null, resolvedImages = [], headline, subheadline }: Props = $props();
|
||||
|
||||
const headlineHtml = $derived(
|
||||
headline?.trim() ? (marked.parseInline(headline) as string) : "",
|
||||
);
|
||||
const subheadlineHtml = $derived(
|
||||
subheadline?.trim() ? (marked.parseInline(subheadline) as string) : "",
|
||||
);
|
||||
|
||||
const hasImage = $derived(resolvedImages.length > 0 && Boolean(resolvedImages[0]?.trim()));
|
||||
const hasText = $derived(banner?.text != null && banner.text !== "");
|
||||
const hasPageTitle = $derived((headline != null && headline !== "") || (subheadline != null && subheadline !== ""));
|
||||
const showBanner = $derived(hasImage || hasText || hasPageTitle);
|
||||
</script>
|
||||
|
||||
{#if showBanner}
|
||||
<div class="w-full">
|
||||
{#if hasImage}
|
||||
<div class="w-full overflow-hidden relative flex justify-center items-center shadow-lg border-b border-white">
|
||||
<img
|
||||
src={resolvedImages[0]}
|
||||
alt={banner?.headline ?? headline ?? ""}
|
||||
class="w-full object-cover max-h-[400px] lg:max-h-[600px] max-w-[1920px] aspect-square sm:aspect-video lg:aspect-24/9"
|
||||
width={1920}
|
||||
height={600}
|
||||
loading="eager"
|
||||
fetchpriority="high"
|
||||
/>
|
||||
{#if hasPageTitle}
|
||||
<div class="absolute inset-0 flex items-center justify-start ">
|
||||
<div class="container-custom mx-auto px-6 relative">
|
||||
{#if headlineHtml}
|
||||
<h1 class="bg-red-400/70 inline-block py-1 px-2 -ml-2 backdrop-blur">{@html headlineHtml}</h1>
|
||||
{/if}
|
||||
<div></div>
|
||||
{#if subheadlineHtml}
|
||||
<h2 class="bg-white/50 inline-block py-1 px-2 -ml-2 backdrop-blur font-light! text-xl!">{@html subheadlineHtml}</h2>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else if hasPageTitle}
|
||||
<div class="border-b border-zinc-200 container mx-auto px-6 py-4">
|
||||
{#if headlineHtml}
|
||||
<h1 class="text-2xl font-bold text-zinc-900">{@html headlineHtml}</h1>
|
||||
{/if}
|
||||
{#if subheadlineHtml}
|
||||
<h2 class="text-lg text-zinc-600 mt-1">{@html subheadlineHtml}</h2>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if hasText}
|
||||
<div class="w-full bg-green-700 text-white text-center py-2 px-4">
|
||||
<div class="container mx-auto">
|
||||
<div class="text-sm font-medium">{banner!.text}</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user