/** * Daten fuer die oeffentliche Onepage. Liefert ausschliesslich, was * oeffentlich sein darf: keine Kapazitaet, keine Restplaetze, kein * Kontingent, keine Gutscheine, keine internen Kalkulationswerte. */ import { getCamp, publicCampFacts, salesStateFor, type PublicCampFacts } from "./camp"; import { getDb } from "./db"; import { env, showDevPlaceholders, stripeModeOrNull } from "./env"; import { BASE_PRICE_CENTS, calculatePrice, EARLY_BIRD_START, REGULAR_START, type PricePhase } from "./pricing"; import type { SalesState, StripeMode } from "./sales-gate"; export type PublicPricing = { mode: StripeMode | null; checkoutOpen: boolean; closedReason: SalesState["closedReason"] | "NOT_CONFIGURED"; phase: PricePhase; phaseSimulated: boolean; regularCents: number; earlyBirdCents: number; /** Aktuell gueltiger Preis ohne Gutschein; null in der Vorschau. */ currentCents: number | null; earlyBirdStartIso: string; earlyBirdEndIso: string; installmentsAllowed: boolean; reservationMinutes: number; }; export type PublicPageData = { facts: PublicCampFacts; pricing: PublicPricing; showDrafts: boolean; externalVideoProvider: "none" | "youtube-nocookie" | "vimeo"; }; export async function loadPublicPage(now: Date = new Date()): Promise { const camp = await getCamp(getDb()); const mode = stripeModeOrNull(); const facts = publicCampFacts(camp); let pricing: PublicPricing; const base = { regularCents: BASE_PRICE_CENTS, earlyBirdCents: calculatePrice("EARLY_BIRD", false).totalCents, earlyBirdStartIso: EARLY_BIRD_START.toISOString(), earlyBirdEndIso: REGULAR_START.toISOString(), reservationMinutes: camp.reservationMinutes, }; if (!mode) { pricing = { ...base, mode: null, checkoutOpen: false, closedReason: "NOT_CONFIGURED", phase: "PREVIEW", phaseSimulated: false, currentCents: null, installmentsAllowed: false, }; } else { const state = salesStateFor(camp, mode, now); pricing = { ...base, mode, checkoutOpen: state.checkoutOpen, closedReason: state.closedReason, phase: state.effectivePhase, phaseSimulated: state.phaseSimulated, currentCents: state.effectivePhase === "PREVIEW" ? null : calculatePrice(state.effectivePhase, false).totalCents, installmentsAllowed: state.installmentsAllowed, }; } return { facts, pricing, showDrafts: showDevPlaceholders(), externalVideoProvider: env().EXTERNAL_VIDEO_PROVIDER }; }