Abosystem mit dauerhaften Rabatten und Teddy-Prämien

Drei Mitgliedschaftsstufen (Klein 4,99€/5%, Mittel 9,99€/10%, Groß 19,99€/20%)
mit automatischem Bestellrabatt und Teddy-Prämien nach Meilensteinen (12-Monats-
Rhythmus bzw. 6+12 bei Groß). Preise/Rabatte und alle Admin-Regeln (Kombinier-
barkeit mit anderen Rabatten, Fortsetzung bei Wiederanmeldung, Monate über
Stufen zusammenzählen, kostenloser Versand bei Prämie) sind über Decap CMS
einstellbar (src/content/abo-einstellungen.json).

Neuer "Mein Abo"-Bereich im Kundenkonto (6. Nav-Kachel) mit Plan-Vergleich,
Live-Status (Laufzeit, nächste Zahlung, Rabatt, Fortschritt bis zur nächsten
Prämie), Einlösen-Buttons für freigeschaltete Teddys, Kündigen/Wechseln sowie
einer übersetzten Benachrichtigungsliste. Dazu ein extra hervorgehobener
"Mein Abo verwalten"-Button neben Abmelden in der Kopfkarte.

Warenkorb/Checkout rechnen den Abo-Rabatt korrekt in die Summe ein und stellen
eingelöste Teddys als 0€-Gratisposition dar. Alles in 4 Sprachen (DE/EN/CH/FR).

Unterwegs zwei echte Bugs gefunden und behoben: addMonateISO() vermischte
lokale Zeit mit toISOString() (UTC) und verlor dadurch bei jeder Monats-
verlängerung reproduzierbar einen Tag; die Checkout-Positionsliste zeigte für
Gratis-Prämien fälschlich den vollen Preis statt 0€.

Wie beim Treuebonus gilt: Speicherung aktuell im localStorage des Geräts
(Phase 1) statt einer echten geräteübergreifenden Datenbank — folgt mit der
Zahlungsanbindung in Phase 2.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
qcigano
2026-08-03 16:54:25 +02:00
co-authored by Claude Sonnet 5
parent 0cb7d3ca65
commit 208d995941
21 changed files with 1902 additions and 91 deletions
+9
View File
@@ -0,0 +1,9 @@
{
"klein": { "preis": 4.99, "rabattProzent": 5 },
"mittel": { "preis": 9.99, "rabattProzent": 10 },
"gross": { "preis": 19.99, "rabattProzent": 20 },
"kombinierbarMitAnderenRabatten": false,
"versandKostenlosBeiPraemie": false,
"fortsetzungBeiWiederanmeldung": false,
"monateUeberStufenZusammenzaehlen": false
}