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:
qcigano
2026-08-02 18:59:11 +02:00
parent 0f93ab73c3
commit 6f850181f1
25 changed files with 1098 additions and 194 deletions
+36
View File
@@ -0,0 +1,36 @@
// Gutscheincodes — site-weit gültig, von VanVan im Adminbereich unter "🎟️ Gutscheincodes"
// verwaltet. Werden im Warenkorb/Checkout eingelöst und auf den Gesamt-Warenwert angewendet.
// @ts-ignore -- JSON-Import, zur Build-Zeit von Astro/Vite aufgelöst
import gutscheineRaw from "../content/gutscheine.json";
export interface Gutschein {
code: string;
prozent?: number;
betrag?: number;
bis?: string; // ISO-Datum, optional
}
const gutscheine = (gutscheineRaw as { codes: Gutschein[] }).codes ?? [];
function istGueltig(bis?: string): boolean {
if (!bis) return true;
return new Date() <= new Date(`${bis}T23:59:59`);
}
/** Sucht einen Gutschein anhand des eingegebenen Codes (Groß-/Kleinschreibung egal). */
export function findeGutschein(code: string): Gutschein | undefined {
const normalisiert = code.trim().toUpperCase();
return gutscheine.find((g) => g.code.toUpperCase() === normalisiert && istGueltig(g.bis));
}
/** Berechnet den Rabatt-Betrag in Euro für einen gegebenen Warenwert. */
export function gutscheinRabatt(gutschein: Gutschein, warenwert: number): number {
if (typeof gutschein.prozent === "number" && gutschein.prozent > 0) {
return Math.min(warenwert, warenwert * (gutschein.prozent / 100));
}
if (typeof gutschein.betrag === "number" && gutschein.betrag > 0) {
return Math.min(warenwert, gutschein.betrag);
}
return 0;
}