Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 2m51s
- Alle sieben Tage aus dem Wochenplan-PDF mit Uhrzeit, Coach und Foto-Kennzeichnung im Karussell - Migration: Camp-Termin 03.05. bis 09.05.2027 (ersetzt 08. bis 15.05.) - Leistungen laut PDF: 20 Workshops und Shootings, sechs Naechte, Bustransfer ab und bis Florenz, Fruehstueck, Snacks und Abendessen - FAQ Anreise mit Transferzeiten - Hinweise "Programmentwurf" und "Laut Beschreibung der Unterkunft" entfernt Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
64 lines
2.6 KiB
TypeScript
64 lines
2.6 KiB
TypeScript
import { site } from "@/content/site";
|
|
import type { PublicCampFacts } from "@/lib/camp";
|
|
import { addDays, formatIsoWeekdayDate } from "@/lib/time";
|
|
import { ScheduleCarousel, type ScheduleCard } from "../ScheduleCarousel";
|
|
import { Slideshow } from "../Slideshow";
|
|
|
|
/** Stellt die Villa vor: Text links, laufende Bilderfolge rechts. */
|
|
export function ExpectSection() {
|
|
const { expect } = site;
|
|
return (
|
|
<section id="erwartet" aria-labelledby="erwartet-title" className="py-24 md:py-32">
|
|
<div className="container-edge grid items-center gap-12 md:grid-cols-12 md:gap-10">
|
|
<div className="md:col-span-5">
|
|
<h2 id="erwartet-title" className="section-title">{expect.title}</h2>
|
|
<p className="mt-6 text-xl font-semibold leading-snug md:text-2xl">{expect.lead}</p>
|
|
<div className="prose-body mt-6 text-ink/85">
|
|
{expect.paragraphs.map((p) => (
|
|
<p key={p}>{p}</p>
|
|
))}
|
|
</div>
|
|
<ul className="mt-8 space-y-3">
|
|
{expect.highlights.map((item) => (
|
|
<li key={item} className="flex items-center gap-3 font-medium">
|
|
<span aria-hidden className="grid h-7 w-7 shrink-0 place-items-center rounded-full bg-rosso text-paper">
|
|
<svg viewBox="0 0 24 24" className="h-4 w-4">
|
|
<path d="M5 12.5l4.5 4.5L19 7.5" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</span>
|
|
{item}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
<Slideshow images={expect.slides} className="md:col-span-7 md:col-start-6 lg:col-span-6 lg:col-start-7" />
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
function scheduleCards(facts: PublicCampFacts): ScheduleCard[] {
|
|
return site.schedule.days.map((day, index) => ({
|
|
label: `Tag ${index + 1}`,
|
|
date: facts.startDate ? formatIsoWeekdayDate(addDays(facts.startDate, index)) : null,
|
|
title: day.title,
|
|
items: day.items,
|
|
}));
|
|
}
|
|
|
|
/** Tagesablauf als Karten pro Tag, wie das Programm bei der Referenz. */
|
|
export function ScheduleSection({ facts }: { facts: PublicCampFacts }) {
|
|
const { schedule } = site;
|
|
return (
|
|
<section id="ablauf" aria-labelledby="ablauf-title" className="bg-sand/35 py-24 md:py-32">
|
|
<div className="container-edge">
|
|
<h2 id="ablauf-title" className="section-title">{schedule.title}</h2>
|
|
<div className="mt-12">
|
|
<ScheduleCarousel days={scheduleCards(facts)} />
|
|
</div>
|
|
<p className="mt-8 text-ink/80">{schedule.footnote}</p>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|