Abo-System: VanVan kann jetzt wirklich alles im Admin einstellen
Bisher waren nur Preis, Rabatt-% und ein paar Verhaltensregeln im CMS editierbar — Namen, Vorteilstexte und die Teddy-Vergabe-Intervalle steckten fest im Code. Jetzt ist pro Abo-Stufe (Klein/Mittel/Groß) direkt im Adminbereich einstellbar: - Name & Vorteilstext der Stufe, in allen 4 Sprachen einzeln - Ob die Stufe aktuell überhaupt neu buchbar ist (bestehende Abonnent:innen behalten ihre Vorteile trotzdem, im Kundenkonto wird die Stufe nur für neue Buchungen ausgegraut mit "Derzeit nicht buchbar") - Nach wie vielen Monaten es den kleinen/großen Teddy gibt (ersetzt die vorher fest verankerten 6-/12-Monats-Abstände) - Welches Produkt als "kleiner"/"großer" Teddy für die Prämien-Einlösung verwendet wird (Produktauswahl statt festem Slug im Code) Alle Berechnungen (Meilensteine, Fortschrittsanzeige) laufen jetzt komplett über diese Admin-Werte statt über Konstanten im Code. Konto-Plan-Karten in allen 4 Sprachen zeigen die admin-gepflegten Texte live an. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
208d995941
commit
a222d6c96e
+50
-12
@@ -8,15 +8,38 @@ import raw from "../content/abo-einstellungen.json";
|
||||
|
||||
export type AboStufe = "klein" | "mittel" | "gross";
|
||||
|
||||
export interface MehrsprachigerText {
|
||||
de: string;
|
||||
en: string;
|
||||
ch: string;
|
||||
fr: string;
|
||||
}
|
||||
|
||||
export interface AboStufenKonfig {
|
||||
preis: number;
|
||||
rabattProzent: number;
|
||||
/** Ob diese Stufe aktuell neu buchbar ist. Bestehende Abonnent:innen dieser Stufe behalten
|
||||
* ihre Vorteile unabhängig davon — nur NEUE Buchungen werden im Kundenkonto gesperrt. */
|
||||
aktiv: boolean;
|
||||
/** Nach wie vielen durchgehend bezahlten Monaten es jeweils einen kleinen/großen Teddy gibt.
|
||||
* 0 oder nicht gesetzt = diese Stufe kennt diese Prämienart gar nicht. Admin-editierbar,
|
||||
* ersetzt die früher fest im Code verankerten 6-/12-Monats-Intervalle. */
|
||||
kleinIntervallMonate: number;
|
||||
grossIntervallMonate: number;
|
||||
/** Anzeigename/Vorteilstext der Stufe, pro Sprache — ersetzt die früher fest in i18n/ui.ts
|
||||
* verankerten Texte, damit VanVan Name und Beschreibung jeder Stufe selbst pflegen kann. */
|
||||
name: MehrsprachigerText;
|
||||
vorteil: MehrsprachigerText;
|
||||
}
|
||||
|
||||
export interface AboEinstellungen {
|
||||
klein: AboStufenKonfig;
|
||||
mittel: AboStufenKonfig;
|
||||
gross: AboStufenKonfig;
|
||||
/** Produkt-Slugs (siehe src/content/products/*.json), die als "kleiner"/"großer" Teddy für
|
||||
* die Prämien-Einlösung verwendet werden — im Admin per Produkt-Auswahl änderbar. */
|
||||
kleinTeddySlug: string;
|
||||
grossTeddySlug: string;
|
||||
kombinierbarMitAnderenRabatten: boolean;
|
||||
versandKostenlosBeiPraemie: boolean;
|
||||
fortsetzungBeiWiederanmeldung: boolean;
|
||||
@@ -31,27 +54,42 @@ export function aboStufenKonfig(stufe: AboStufe): AboStufenKonfig {
|
||||
|
||||
export const ABO_STUFEN: AboStufe[] = ["klein", "mittel", "gross"];
|
||||
|
||||
/** Name/Vorteilstext der Stufe in der gewünschten Sprache, mit Fallback auf Deutsch, falls das
|
||||
* Feld im Admin (noch) leer gelassen wurde. */
|
||||
export function aboStufeName(stufe: AboStufe, lang: keyof MehrsprachigerText): string {
|
||||
const cfg = aboStufenKonfig(stufe);
|
||||
return cfg.name?.[lang] || cfg.name?.de || stufe;
|
||||
}
|
||||
export function aboStufeVorteil(stufe: AboStufe, lang: keyof MehrsprachigerText): string {
|
||||
const cfg = aboStufenKonfig(stufe);
|
||||
return cfg.vorteil?.[lang] || cfg.vorteil?.de || "";
|
||||
}
|
||||
|
||||
/** Wie viele Teddy-Prämien welcher Art bei X durchgehend bezahlten Monaten in dieser Stufe
|
||||
* INSGESAMT freigeschaltet sein müssten (kumulativ, nicht nur "neu diesen Monat"):
|
||||
* - Klein-Abo: 1 kleiner Teddy pro volles Jahr.
|
||||
* - Mittel-Abo: 1 großer Teddy pro volles Jahr.
|
||||
* - Groß-Abo: 1 kleiner Teddy alle 6 Monate UND zusätzlich 1 großer Teddy pro volles Jahr
|
||||
* (nach 6 Monaten: 1 klein · nach 12: 2 klein + 1 groß · nach 18: 3 klein · nach 24: 4 klein + 2 groß). */
|
||||
* INSGESAMT freigeschaltet sein müssten (kumulativ, nicht nur "neu diesen Monat") — rechnet
|
||||
* rein aus den admin-konfigurierten Intervallen (siehe AboStufenKonfig), keine fest im Code
|
||||
* verankerten Zahlen mehr. Ein Intervall von 0 (oder nicht gesetzt) bedeutet "diese Stufe
|
||||
* kennt diese Prämienart nicht". */
|
||||
export function teddyMeilensteine(stufe: AboStufe, monate: number): { klein: number; gross: number } {
|
||||
if (monate <= 0) return { klein: 0, gross: 0 };
|
||||
if (stufe === "klein") return { klein: Math.floor(monate / 12), gross: 0 };
|
||||
if (stufe === "mittel") return { klein: 0, gross: Math.floor(monate / 12) };
|
||||
return { klein: Math.floor(monate / 6), gross: Math.floor(monate / 12) };
|
||||
const cfg = aboStufenKonfig(stufe);
|
||||
const kleinIntervall = cfg.kleinIntervallMonate || 0;
|
||||
const grossIntervall = cfg.grossIntervallMonate || 0;
|
||||
return {
|
||||
klein: kleinIntervall > 0 ? Math.floor(monate / kleinIntervall) : 0,
|
||||
gross: grossIntervall > 0 ? Math.floor(monate / grossIntervall) : 0,
|
||||
};
|
||||
}
|
||||
|
||||
/** Wie viele Monate fehlen noch bis zum jeweils nächsten Meilenstein (für die
|
||||
* Fortschrittsanzeige im Kundenkonto), null wenn diese Stufe die Prämienart gar nicht kennt. */
|
||||
export function naechsteMeilensteine(stufe: AboStufe, monate: number): { klein: number | null; gross: number | null } {
|
||||
const kleinIntervall = stufe === "gross" ? 6 : stufe === "klein" ? 12 : null;
|
||||
const grossIntervall = stufe === "klein" ? null : 12;
|
||||
const cfg = aboStufenKonfig(stufe);
|
||||
const kleinIntervall = cfg.kleinIntervallMonate || 0;
|
||||
const grossIntervall = cfg.grossIntervallMonate || 0;
|
||||
return {
|
||||
klein: kleinIntervall ? kleinIntervall - (monate % kleinIntervall) : null,
|
||||
gross: grossIntervall ? grossIntervall - (monate % grossIntervall) : null,
|
||||
klein: kleinIntervall > 0 ? kleinIntervall - (monate % kleinIntervall) : null,
|
||||
gross: grossIntervall > 0 ? grossIntervall - (monate % grossIntervall) : null,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user