This commit is contained in:
commit
59bb5a38a3
132 files changed
+19435
No files matched your search
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user