Feature: Add quantity adjustment and fix shipping selection

- Add quantity adjustment controls (+ and -) on checkout order summary
- Prevent quantity from going below 1 with disabled minus button at qty=1
- Fix shipping selector not updating by wrapping callback in useCallback
- Shipping option changes now properly update order total
- Totals recalculate reactively when adjusting quantities or shipping

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Andymick
2026-07-19 07:33:03 +01:00
co-authored by Claude Haiku 4.5
parent 5538938020
commit 08038dffb1
10 changed files with 557 additions and 58 deletions
+8 -8
View File
@@ -5,6 +5,7 @@ import { v4 as uuid } from 'uuid';
import ProductMockup from './ProductMockup';
import Price from './Price';
import LoginPromptModal from './LoginPromptModal';
import AddToCartModal from './AddToCartModal';
import { useCart } from '@/lib/cartStore';
import { getColorName } from '@/lib/colorNames';
import { checkCustomerAuth } from '@/app/actions';
@@ -17,6 +18,7 @@ export default function StandardProductView({ product }: { product: ProductDTO }
const [quantity, setQuantity] = useState(1);
const [justAdded, setJustAdded] = useState(false);
const [showLoginPrompt, setShowLoginPrompt] = useState(false);
const [showAddToCartModal, setShowAddToCartModal] = useState(false);
const addItem = useCart((s) => s.addItem);
const hasBack = Boolean(product.imageUrlBack);
@@ -48,11 +50,6 @@ export default function StandardProductView({ product }: { product: ProductDTO }
}
const handleAddToBag = async () => {
const { isAuthenticated } = await checkCustomerAuth();
if (!isAuthenticated) {
setShowLoginPrompt(true);
}
addItem({
cartItemId: uuid(),
productId: product.id,
@@ -69,8 +66,7 @@ export default function StandardProductView({ product }: { product: ProductDTO }
placementPreviewUrl: product.colorPhotos[color] ?? product.imageUrl ?? null,
placementPreviewUrlBack: product.imageUrlBack ?? null,
});
setJustAdded(true);
setTimeout(() => setJustAdded(false), 2200);
setShowAddToCartModal(true);
};
return (
@@ -188,10 +184,14 @@ export default function StandardProductView({ product }: { product: ProductDTO }
Add to bag <Price cents={product.effectivePrice * quantity} />
</button>
</div>
{justAdded && <p className="text-sm text-pine">Added to your bag.</p>}
</div>
<LoginPromptModal isOpen={showLoginPrompt} onClose={() => setShowLoginPrompt(false)} />
<AddToCartModal
isOpen={showAddToCartModal}
onClose={() => setShowAddToCartModal(false)}
productName={product.name}
/>
</div>
);
}