Rabatt-System, größerer Mengen-Stepper, Zahlungsart zuerst, echte HasiDog-Inhalte
- Neues Rabatt-System: Prozent-/Betrag-Rabatt mit optionalem Ablaufdatum, Mengenrabatt-Staffel pro Produkt, sowie site-weite Gutscheincodes. Wird live im Warenkorb/Checkout berechnet (src/data/rabatt.ts, src/data/gutscheine.ts, cart.ts) und ist im Adminbereich direkt unter dem Preis bearbeitbar (config.yml: "Rabatte" + neue Collection "Gutscheincodes"). Effektiver Preis + Rabatt-Badge auf Produktkarten und Produktseite sichtbar. - Mengen-Stepper auf der Produktseite vergrößert (bereits vorbereitet, jetzt mit Build/Test verifiziert). - Zahlungsart im Checkout auf Platz 1, mit markenfarbigen, fertig gestalteten Buttons (PayPal/Klarna/Banküberweisung). - Unterkategorie-Seiten zeigen jetzt VanVans eigene Produktbeschreibung und das echte Fotos des Produkts statt Platzhaltertext, mit kleinem Link zur HasiDog-Universum-Seite statt großem Button. Verifiziert per Puppeteer-Funktionstest gegen den echten Production-Build (Rabatt-Berechnung, Mengenrabatt, Gutschein-Einlösung, Checkout-Summary, keine Konsolenfehler).
This commit is contained in:
+41
-1
@@ -1,6 +1,10 @@
|
||||
// Rein clientseitiger Warenkorb (Phase 1, kein Backend). Speichert im localStorage.
|
||||
// TODO Phase 2: durch echten Cloudflare-Worker-Warenkorb/Checkout ersetzen.
|
||||
|
||||
import { getProduct } from "../data/products";
|
||||
import { effektiverZeilenpreis } from "../data/rabatt";
|
||||
import { findeGutschein, gutscheinRabatt, type Gutschein } from "../data/gutscheine";
|
||||
|
||||
export interface CartItem {
|
||||
slug: string;
|
||||
name: string;
|
||||
@@ -54,6 +58,42 @@ export function cartCount(): number {
|
||||
return getCart().reduce((sum, i) => sum + i.menge, 0);
|
||||
}
|
||||
|
||||
// Zwischensumme inkl. Produkt-Rabatt (Prozent/Betrag) UND Mengenrabatt-Staffel — schaut sich
|
||||
// dafür live die aktuellen Produktdaten an (nicht den bei addToCart gespeicherten Preis), damit
|
||||
// ein nachträglich geänderter/abgelaufener Rabatt sich sofort korrekt auswirkt.
|
||||
export function cartTotal(): number {
|
||||
return getCart().reduce((sum, i) => sum + i.menge * i.preis, 0);
|
||||
return getCart().reduce((sum, i) => {
|
||||
const produkt = getProduct(i.slug);
|
||||
return sum + (produkt ? effektiverZeilenpreis(produkt, i.menge) : i.menge * i.preis);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
const COUPON_KEY = "vandiy_coupon_v1";
|
||||
|
||||
export function getCouponCode(): string {
|
||||
if (typeof localStorage === "undefined") return "";
|
||||
return localStorage.getItem(COUPON_KEY) || "";
|
||||
}
|
||||
|
||||
export function setCouponCode(code: string) {
|
||||
localStorage.setItem(COUPON_KEY, code.trim());
|
||||
window.dispatchEvent(new CustomEvent("cart:changed", { detail: getCart() }));
|
||||
}
|
||||
|
||||
export function clearCoupon() {
|
||||
localStorage.removeItem(COUPON_KEY);
|
||||
window.dispatchEvent(new CustomEvent("cart:changed", { detail: getCart() }));
|
||||
}
|
||||
|
||||
/** Der aktuell eingelöste Gutschein, falls der gespeicherte Code (noch) gültig ist. */
|
||||
export function appliedCoupon(): Gutschein | undefined {
|
||||
const code = getCouponCode();
|
||||
if (!code) return undefined;
|
||||
return findeGutschein(code);
|
||||
}
|
||||
|
||||
/** Rabatt-Betrag in Euro, den der eingelöste Gutschein auf die gegebene Zwischensumme gibt. */
|
||||
export function couponDiscount(subtotal: number): number {
|
||||
const g = appliedCoupon();
|
||||
return g ? gutscheinRabatt(g, subtotal) : 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user