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,78 @@
|
||||
<script lang="ts">
|
||||
import type { PostEntry } from "$lib/cms";
|
||||
import PostMeta from "./PostMeta.svelte";
|
||||
import EventBadges from "./EventBadges.svelte";
|
||||
|
||||
type PostWithImage = PostEntry & { _resolvedImageUrl?: string };
|
||||
|
||||
let {
|
||||
post,
|
||||
href,
|
||||
tagBase = "/posts/tag",
|
||||
}: {
|
||||
post: PostWithImage;
|
||||
href: string;
|
||||
tagBase?: string;
|
||||
} = $props();
|
||||
|
||||
const resolvedImg = $derived(post._resolvedImageUrl);
|
||||
|
||||
type PostWithEvent = PostWithImage & {
|
||||
isEvent?: boolean;
|
||||
eventDate?: string;
|
||||
eventLocation?: { text?: string };
|
||||
};
|
||||
const p = post as PostWithEvent;
|
||||
|
||||
const eventDate = $derived(p.isEvent && p.eventDate ? p.eventDate : null);
|
||||
const locationText = $derived(p.eventLocation?.text ?? null);
|
||||
</script>
|
||||
|
||||
<a
|
||||
href={href}
|
||||
class="transition-all flex flex-col text-slate-950 no-underline overflow-hidden border border-gray-200 bg-white"
|
||||
>
|
||||
<div class="relative aspect-3/2 w-full overflow-hidden bg-gray-100">
|
||||
{#if resolvedImg}
|
||||
<img
|
||||
src={resolvedImg}
|
||||
alt={post.headline ?? ""}
|
||||
class="w-full h-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
{:else}
|
||||
<div class="w-full h-full flex items-center justify-center text-gray-300">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="size-12" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/>
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
{#if eventDate}
|
||||
<div class="absolute bottom-2 left-2 right-2">
|
||||
<EventBadges {eventDate} {locationText} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex-1 flex flex-col justify-start p-4">
|
||||
<PostMeta
|
||||
date={post.created ?? null}
|
||||
tags={post.postTag ?? []}
|
||||
{tagBase}
|
||||
/>
|
||||
<div>
|
||||
<h5 class="line-clamp-2 font-medium leading-tight mb-1">
|
||||
{post.headline ?? post.linkName ?? post.slug ?? post._slug}
|
||||
</h5>
|
||||
{#if post.subheadline}
|
||||
<div class="text-xs line-clamp-2 mb-1">
|
||||
{post.subheadline}
|
||||
</div>
|
||||
{/if}
|
||||
{#if post.excerpt}
|
||||
<p class="text-xs font-light line-clamp-3">
|
||||
{post.excerpt}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
Reference in New Issue
Block a user