From 3c9fd3d55cb1b1b8cd48edd38efe40f43564dff7 Mon Sep 17 00:00:00 2001 From: iris Date: Mon, 3 Aug 2026 17:26:13 +0200 Subject: [PATCH] client: long-press picker also offers quick-remove when already in cart Fixes the rest of #70 - mara's answer: "when there are already drinks in cart, i want to be able to remove them - so show negative numbers there too." Second row of -1..-5 buttons appears in the count picker only when the long-pressed drink already has cart quantity (an empty-cart drink keeps the original add-only picker - nothing to remove). Routed through incLine (the qty-stepper's own clamp-at-zero-and-drop-the-line logic) rather than addDrink's raw qty+n, so over-removing (e.g. -5 on a qty-3 line) drops the line cleanly instead of going negative - verified this specific clamping behavior with a standalone reproduction of the logic before trusting it. Remove buttons get the existing button.danger styling (red), matching the app's established negative/removal convention (Pfand-return tile, cart-line.return). pnpm --filter client typecheck and build both clean. --- client/src/tablet/Sale.tsx | 58 +++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/client/src/tablet/Sale.tsx b/client/src/tablet/Sale.tsx index 7bd0fab..0d1739a 100644 --- a/client/src/tablet/Sale.tsx +++ b/client/src/tablet/Sale.tsx @@ -122,8 +122,14 @@ export function Sale({ config, onChangeBar }: Props) { addDrink(d.id); } + // Positive n adds (works on any drink, cart-empty or not). Negative n + // removes — routed through incLine rather than addDrink so it shares + // the qty-stepper's clamp-at-zero-and-drop-the-line behaviour instead + // of letting a line go negative (addDrink's raw `qty + n` would). function pickCount(n: number) { - if (pickerDrink) addDrink(pickerDrink.id, n); + if (!pickerDrink) return; + if (n > 0) addDrink(pickerDrink.id, n); + else incLine(pickerDrink.id, n); setPickerDrink(null); } @@ -191,23 +197,43 @@ export function Sale({ config, onChangeBar }: Props) { )} - {pickerDrink && ( -
setPickerDrink(null)}> -
e.stopPropagation()}> -
{pickerDrink.name}
-
- {PICKER_COUNTS.map(n => ( - - ))} + {pickerDrink && (() => { + // #70: "when there are already drinks in cart, i want to be able + // to remove them" — the remove row only makes sense (and only + // appears) once there's cart quantity for this drink to remove; + // an empty-cart drink keeps the original add-only picker. + const cartQty = lines.find(l => l.drink_id === pickerDrink.id)?.qty ?? 0; + return ( +
setPickerDrink(null)}> +
e.stopPropagation()}> +
{pickerDrink.name}
+
+ {PICKER_COUNTS.map(n => ( + + ))} +
+ {cartQty > 0 && ( +
+ {PICKER_COUNTS.map(n => ( + + ))} +
+ )} +
-
-
- )} + ); + })()}