Warenkorb/Produktseite: nie mehr in den Warenkorb legen können als auf Lager ist

- Produktseite: Mengen-Stepper und manuelle Eingabe sind jetzt auf den
  tatsächlichen Lagerbestand begrenzt (zählt bereits im Warenkorb
  liegende Menge desselben Produkts mit). Ist das Maximum schon
  erreicht, wird der "In den Warenkorb"-Button deaktiviert und zeigt
  "Maximale verfügbare Menge ist bereits im Warenkorb"; bei wenig Rest-
  bestand (≤5) erscheint stattdessen "Nur noch X auf Lager".
- Warenkorb-Seite: der "+"-Button bei der Mengenauswahl ist ebenfalls auf
  den Lagerbestand begrenzt.
- Als zusätzliche Absicherung greift das Limit jetzt auch direkt in
  addToCart()/updateQuantity() selbst (cart.ts) — unabhängig davon,
  welche Oberfläche die Funktion aufruft, kann so nie mehr Menge als
  Bestand ins localStorage gelangen.

Verifiziert per Puppeteer an einem Produkt mit Bestand 2: 6× auf "+"
klicken bleibt bei 2, manuelles Eintippen von 999 wird auf 2 geklemmt,
nach dem Hinzufügen ist der Button deaktiviert, der "+"-Button im
Warenkorb erhöht nicht weiter — keine Konsolenfehler.
This commit is contained in:
qcigano
2026-08-02 20:42:21 +02:00
parent 7e8e85851c
commit 51ac0affa7
10 changed files with 288 additions and 22 deletions
+4
View File
@@ -20,6 +20,7 @@ export const ui = {
badge: { neu: "Neu", bestseller: "Bestseller", sale: "Sale", handgemacht: "Handgemacht", ausverkauft: "Ausverkauft" },
common: {
addToCart: "In den Warenkorb", soldOut: "Ausverkauft", addedToCart: "Zum Warenkorb hinzugefügt ✓",
onlyXLeft: (n: string) => `Nur noch ${n} auf Lager`, maxInCart: "Maximale verfügbare Menge ist bereits im Warenkorb",
browseShop: "Jetzt stöbern", viewAll: "Alle ansehen →", viewAllSale: "Alle Angebote →",
toShop: "Zum Shop →", moreAboutMe: "Mehr über mich →", discoverNow: "Jetzt entdecken",
vatNote: "Gemäß §19 UStG wird keine Umsatzsteuer berechnet und ausgewiesen.",
@@ -202,6 +203,7 @@ export const ui = {
badge: { neu: "New", bestseller: "Bestseller", sale: "Sale", handgemacht: "Handmade", ausverkauft: "Sold out" },
common: {
addToCart: "Add to cart", soldOut: "Sold out", addedToCart: "Added to cart ✓",
onlyXLeft: (n: string) => `Only ${n} left in stock`, maxInCart: "The maximum available quantity is already in your cart",
browseShop: "Browse now", viewAll: "View all →", viewAllSale: "View all offers →",
toShop: "To the shop →", moreAboutMe: "More about me →", discoverNow: "Discover now",
vatNote: "Under §19 UStG (German small-business rule) no VAT is charged or shown.",
@@ -384,6 +386,7 @@ export const ui = {
badge: { neu: "Neu", bestseller: "Bestseller", sale: "Aktion", handgemacht: "Handgmacht", ausverkauft: "Usverkauft" },
common: {
addToCart: "In Warenchorb", soldOut: "Usverkauft", addedToCart: "Zum Warenchorb dezuegfüegt ✓",
onlyXLeft: (n: string) => `Nume no ${n} a Lager`, maxInCart: "D'maximal verfügbari Mengi isch scho im Warenchorb",
browseShop: "Jetzt use luege", viewAll: "Alles aluege →", viewAllSale: "Alli Aktione →",
toShop: "Zum Shop →", moreAboutMe: "Meh über mich →", discoverNow: "Jetzt aluege",
vatNote: "Gemäss §19 UStG (dütsches Rächt) wird kei Umsatzsteuer berechnet und usgwiese.",
@@ -566,6 +569,7 @@ export const ui = {
badge: { neu: "Nouveau", bestseller: "Best-seller", sale: "Soldes", handgemacht: "Fait main", ausverkauft: "Épuisé" },
common: {
addToCart: "Ajouter au panier", soldOut: "Épuisé", addedToCart: "Ajouté au panier ✓",
onlyXLeft: (n: string) => `Plus que ${n} en stock`, maxInCart: "La quantité maximale disponible est déjà dans votre panier",
browseShop: "Découvrir la boutique", viewAll: "Tout voir →", viewAllSale: "Toutes les offres →",
toShop: "Vers la boutique →", moreAboutMe: "En savoir plus sur moi →", discoverNow: "Découvrir maintenant",
vatNote: "Conformément à l'§19 UStG (droit allemand), aucune TVA n'est calculée ni indiquée.",