Files
Artista-Filmcamp/src/lib/public-page.ts
T
Nick Szaunig 59bb5a38a3
Docker-Images bauen und veroeffentlichen / build-and-push (push) Failing after 1m32s
first commit
2026-09-27 06:06:56 +02:00

74 lines
2.5 KiB
TypeScript

/**
* 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<PublicPageData> {
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 };
}