first commit
Docker-Images bauen und veroeffentlichen / build-and-push (push) Failing after 1m32s

This commit is contained in:
Nick Szaunig committed 2026-09-27 06:06:56 +02:00
commit 59bb5a38a3
132 files changed
+19435

No files matched your search

+104
View File
@@ -0,0 +1,104 @@
import { site } from "@/content/site";
import type { PublicCampFacts } from "@/lib/camp";
import { formatEuroShort } from "@/lib/money";
import type { PublicPricing } from "@/lib/public-page";
import { BookButton } from "../booking/BookingProvider";
const CLOSED_TEXT: Record<Exclude<PublicPricing["closedReason"], null>, string> = {
PREVIEW: "Die Buchung öffnet am 1. November 2026.",
NOT_RELEASED: "Die Buchung ist noch nicht freigeschaltet. Wir veröffentlichen alle verbindlichen Angaben vor dem Verkaufsstart.",
CAMP_STARTED: "Die Buchung ist geschlossen.",
NOT_CONFIGURED: "Die Buchung ist derzeit nicht verfügbar.",
};
export function PricingSection({ pricing, facts, showDrafts }: { pricing: PublicPricing; facts: PublicCampFacts; showDrafts: boolean }) {
const included = site.services.included.filter((s) => s.confirmed);
return (
<section id="preis" aria-labelledby="preis-title" className="bg-paper py-20 md:py-32">
<div className="container-edge grid gap-14 md:grid-cols-12">
<div className="md:col-span-7">
<h2 id="preis-title" className="section-title">Preis und Buchung</h2>
{pricing.mode === "test" && (
<p className="mt-6 rounded-lg border border-line bg-plaster p-4 text-[0.9375rem]">
<span className="draft-flag">Testmodus</span> Zahlungen laufen über Stripe-Testdaten, es wird kein Geld eingezogen.
{pricing.phaseSimulated && " Die Preisphase ist für Tests simuliert."}
</p>
)}
<div className="mt-10">
{pricing.phase === "EARLY_BIRD" && pricing.currentCents !== null && (
<>
<p className="text-stone">
Regulärer Preis <s className="tabular-nums">{formatEuroShort(pricing.regularCents)}</s>
</p>
<p className="display mt-2 text-[clamp(4rem,12vw,8rem)] leading-none tabular-nums">{formatEuroShort(pricing.currentCents)}</p>
<p className="mt-3 text-lg">Early-Bird-Preis pro Person, gültig bis einschließlich 31. Dezember 2026.</p>
</>
)}
{pricing.phase === "REGULAR" && pricing.currentCents !== null && (
<>
<p className="display text-[clamp(4rem,12vw,8rem)] leading-none tabular-nums">{formatEuroShort(pricing.currentCents)}</p>
<p className="mt-3 text-lg">pro Person</p>
</>
)}
{pricing.phase === "PREVIEW" && (
<dl className="grid gap-6 sm:grid-cols-2">
<div className="border-t border-ink pt-4">
<dt className="text-stone">Early Bird, 1. November bis 31. Dezember 2026</dt>
<dd className="display mt-2 text-6xl tabular-nums">{formatEuroShort(pricing.earlyBirdCents)}</dd>
</div>
<div className="border-t border-line pt-4">
<dt className="text-stone">Regulär, ab 1. Januar 2027</dt>
<dd className="display mt-2 text-6xl tabular-nums">{formatEuroShort(pricing.regularCents)}</dd>
</div>
</dl>
)}
</div>
<ul className="mt-8 max-w-xl space-y-2 text-[0.9375rem] text-ink/85">
<li>Gesamtpreis pro Person für die Teilnahme mit geteilter Unterbringung.</li>
<li>
{pricing.installmentsAllowed
? "Bezahlen kannst du auf einmal oder in bis zu drei Raten. Die erste Rate ist bei Buchung fällig, die letzte spätestens 30 Tage vor Anreise."
: "Bezahlt wird bei Buchung. Ob zusätzlich Ratenzahlung möglich ist, geben wir bekannt, sobald der Termin feststeht."}
</li>
<li>Einen Gutscheincode kannst du im Buchungsschritt eingeben.</li>
{facts.taxNote ? (
<li>{facts.taxNote}</li>
) : (
showDrafts && (
<li>
<span className="draft-flag">Steuerlicher Preishinweis folgt vor Verkaufsstart</span>
</li>
)
)}
</ul>
<div className="mt-10">
{pricing.checkoutOpen ? (
<BookButton className="btn btn-primary px-8 text-lg">Platz buchen</BookButton>
) : (
<p className="max-w-xl text-lg font-semibold">{CLOSED_TEXT[pricing.closedReason ?? "NOT_CONFIGURED"]}</p>
)}
</div>
</div>
<aside aria-labelledby="preis-umfang" className="md:col-span-4 md:col-start-9 md:pt-24">
<h3 id="preis-umfang" className="text-lg font-semibold">Was du buchst</h3>
<ul className="mt-4 divide-y divide-line border-y border-line">
{included.map((item) => (
<li key={item.text} className="py-3">{item.text}</li>
))}
</ul>
<p className="mt-6 text-[0.9375rem] text-stone">
Nicht enthalten: {site.services.excluded.join(", ")}.
</p>
<p className="mt-4 text-[0.9375rem] text-stone">
Vor der Zahlung siehst du Gesamtpreis, heute fälligen Betrag, alle weiteren Raten mit Terminen und die Beschreibung der Unterbringung auf einen Blick.
</p>
</aside>
</div>
</section>
);
}