Cap add-to-cart quantity at actual remaining stock
Stock was only checked at checkout; a shopper could add more of a product to the cart than was actually in stock and only find out at the last step. Product/variant now carry a real maxQty, and AddToCartButton/AddToCartInlineButton/the cart's quantity stepper all disable or cap once the cart already holds that many. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -191,6 +191,19 @@ export function CartContent({
|
||||
const lowStock = entry.variant
|
||||
? (product.variants.find((v) => v.name === entry.variant)?.lowStock ?? false)
|
||||
: product.lowStock;
|
||||
// Same per-line resolution as lowStock above — caps how high
|
||||
// the quantity stepper below can go, instead of only finding
|
||||
// out at checkout that this many aren't actually available
|
||||
// (api/checkout/route.ts's own stock check stays as the
|
||||
// authoritative server-side guard). null (no cap) falls back
|
||||
// to the stepper's original fixed 1-9 range; at least 1 is
|
||||
// always offered even if maxQty is somehow lower than the
|
||||
// qty already in this line, so the remove (×) button stays
|
||||
// the only way down, never an empty <select>.
|
||||
const maxQty = entry.variant
|
||||
? (product.variants.find((v) => v.name === entry.variant)?.maxQty ?? null)
|
||||
: product.maxQty;
|
||||
const qtyOptions = Array.from({ length: Math.max(1, Math.min(9, maxQty ?? 9)) }, (_, n) => n + 1);
|
||||
return (
|
||||
<div key={lineKey} className="w-full">
|
||||
{i > 0 && <div className="h-px bg-border w-full mb-6" />}
|
||||
@@ -238,7 +251,7 @@ export function CartContent({
|
||||
onChange={(e) => setQuantity(product.id, Number(e.target.value), entry.variant)}
|
||||
className="border border-border rounded-sm px-3.5 py-2 text-body-sm text-text-primary outline-none focus:border-brand transition-colors"
|
||||
>
|
||||
{Array.from({ length: 9 }, (_, n) => n + 1).map((n) => (
|
||||
{qtyOptions.map((n) => (
|
||||
<option key={n} value={n}>{n}</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
@@ -198,7 +198,7 @@ export function RelatedProducts({ defaultTaxRate }: { defaultTaxRate: number })
|
||||
<p className="min-h-[1.05rem] text-label font-bold text-warning">
|
||||
{anyLowStock ? "Nur noch wenige verfügbar" : null}
|
||||
</p>
|
||||
<AddToCartInlineButton id={product.id} outOfStock={product.outOfStock} variants={product.variants} />
|
||||
<AddToCartInlineButton id={product.id} outOfStock={product.outOfStock} maxQty={product.maxQty} variants={product.variants} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user