Migrate CMS from Sanity to self-hosted Directus, add Impressum + Datenschutz

- Replace src/lib/sanity.ts with src/lib/directus.ts (REST API client)
- Update all 9 pages to use Directus field names and imageUrl()
- Add Impressum (§5 TMG) and Datenschutz (DSGVO) pages
- Update .env.example for Directus URL + token

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 05:25:41 +00:00
parent 1d1492e611
commit c54762532c
14 changed files with 408 additions and 101 deletions

View File

@@ -1,12 +1,10 @@
---
import Layout from "../layouts/Layout.astro";
import { getSettings, getFeaturedProjects, getLatestPosts } from "../lib/sanity";
import { getSettings, getFeaturedProjects, getLatestPosts, imageUrl } from "../lib/directus";
const settings = await getSettings();
const featuredProjects = await getFeaturedProjects();
const latestPosts = await getLatestPosts(3);
const stats = settings?.stats;
---
<Layout
@@ -83,25 +81,19 @@ const stats = settings?.stats;
</section>
<!-- Zahlen -->
{stats && (stats.members || stats.fundsPerYear || stats.projectsTotal) && (
{settings && (settings.stats_members || settings.stats_funded) && (
<section class="bg-[var(--color-primary)] text-white">
<div class="max-w-6xl mx-auto px-4 py-16 grid grid-cols-1 md:grid-cols-3 gap-8 text-center">
{stats.members && (
<div class="max-w-6xl mx-auto px-4 py-16 grid grid-cols-1 md:grid-cols-2 gap-8 text-center">
{settings.stats_members && (
<div>
<p class="font-brand text-5xl mb-2">{stats.members}</p>
<p class="font-brand text-5xl mb-2">{settings.stats_members}</p>
<p class="text-white/80">Mitglieder unterstützen den Verein</p>
</div>
)}
{stats.fundsPerYear && (
{settings.stats_funded && (
<div>
<p class="font-brand text-5xl mb-2">{stats.fundsPerYear.toLocaleString("de")} €</p>
<p class="text-white/80">jährlich für die Kinder</p>
</div>
)}
{stats.projectsTotal && (
<div>
<p class="font-brand text-5xl mb-2">{stats.projectsTotal}</p>
<p class="text-white/80">Projekte seit Vereinsgründung</p>
<p class="font-brand text-5xl mb-2">{settings.stats_funded.toLocaleString("de")} €</p>
<p class="text-white/80">geförderte Projekte</p>
</div>
)}
</div>
@@ -115,10 +107,10 @@ const stats = settings?.stats;
<p class="text-[var(--color-text-muted)] mb-8">Was wir gerade machen und was geplant ist.</p>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{featuredProjects.map((p: any) => (
<a href={`/projekte/${p.slug.current}`} class="card group">
{p.image?.asset && (
<a href={`/projekte/${p.slug}`} class="card group">
{p.image && (
<div class="aspect-video bg-[var(--color-surface-alt)] rounded-xl mb-4 overflow-hidden">
<img src={p.image.asset.url} alt={p.title} class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
<img src={imageUrl(p.image, 600)} alt={p.title} class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
</div>
)}
<p class="text-xs text-[var(--color-text-muted)] mb-1">{p.date}</p>
@@ -139,9 +131,9 @@ const stats = settings?.stats;
<h2 class="text-3xl font-bold mb-8">Aktuelles</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
{latestPosts.map((post: any) => (
<a href={`/aktuelles/${post.slug.current}`} class="card group">
<a href={`/aktuelles/${post.slug}`} class="card group">
<p class="text-xs text-[var(--color-text-muted)] mb-2">
{new Date(post.publishedAt).toLocaleDateString("de-DE", { day: "numeric", month: "long", year: "numeric" })}
{new Date(post.published_at).toLocaleDateString("de-DE", { day: "numeric", month: "long", year: "numeric" })}
</p>
<h3 class="font-bold leading-snug group-hover:text-[var(--color-primary)] transition-colors">{post.title}</h3>
{post.excerpt && <p class="text-sm text-[var(--color-text-muted)] mt-2 line-clamp-3">{post.excerpt}</p>}