From b5b5d1343f230522bb0f1e685f4d09e4b8f37a35 Mon Sep 17 00:00:00 2001
From: Luis Alvarez <luis@vercel.com>
Date: Tue, 6 Oct 2020 19:07:02 -0500
Subject: [PATCH] Update item quantity

---
 components/cart/CartItem/CartItem.module.css |  9 +++++
 components/cart/CartItem/CartItem.tsx        | 39 +++++++++++++++++++-
 lib/bigcommerce/api/cart.ts                  |  2 +-
 lib/bigcommerce/cart/use-update-item.tsx     |  2 +-
 4 files changed, 48 insertions(+), 4 deletions(-)
 create mode 100644 components/cart/CartItem/CartItem.module.css

diff --git a/components/cart/CartItem/CartItem.module.css b/components/cart/CartItem/CartItem.module.css
new file mode 100644
index 000000000..b6a8858b1
--- /dev/null
+++ b/components/cart/CartItem/CartItem.module.css
@@ -0,0 +1,9 @@
+.quantity {
+  appearance: textfield;
+  @apply w-6 border-gray-300 border mx-3 rounded text-center text-sm;
+}
+
+.quantity::-webkit-outer-spin-button,
+.quantity::-webkit-inner-spin-button {
+  @apply appearance-none m-0;
+}
diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx
index 692217979..87da31bd3 100644
--- a/components/cart/CartItem/CartItem.tsx
+++ b/components/cart/CartItem/CartItem.tsx
@@ -1,6 +1,9 @@
 import { Trash } from '@components/icon'
 import { useCommerce } from '@lib/bigcommerce'
+import useUpdateItem from '@lib/bigcommerce/cart/use-update-item'
+import { useEffect, useState } from 'react'
 import formatVariantPrice from 'utils/format-item-price'
+import styles from './CartItem.module.css'
 
 const CartItem = ({
   item,
@@ -10,12 +13,35 @@ const CartItem = ({
   currencyCode: string
 }) => {
   const { locale } = useCommerce()
+  const updateItem = useUpdateItem()
+  const [quantity, setQuantity] = useState(item.quantity)
   const { price } = formatVariantPrice({
     listPrice: item.extended_list_price,
     salePrice: item.extended_sale_price,
     currencyCode,
     locale,
   })
+  const handleBlur = async () => {
+    const val = Number(quantity)
+
+    if (val !== item.quantity) {
+      const data = await updateItem({
+        itemId: item.id,
+        item: {
+          productId: item.product_id,
+          variantId: item.variant_id,
+          quantity: val,
+        },
+      })
+    }
+  }
+
+  useEffect(() => {
+    // Reset the quantity state if the item quantity changes
+    if (item.quantity !== quantity) {
+      setQuantity(item.quantity)
+    }
+  }, [item.quantity])
 
   console.log('ITEM', item)
 
@@ -27,8 +53,17 @@ const CartItem = ({
         <div className="py-2">
           <span>-</span>
           <input
-            className="w-6 border-gray-300 border mx-3 rounded text-center text-sm"
-            defaultValue="1"
+            type="number"
+            className={styles.quantity}
+            value={quantity}
+            onChange={(e) => {
+              const val = Number(e.target.value)
+
+              if (Number.isInteger(val) && val >= 0) {
+                setQuantity(e.target.value)
+              }
+            }}
+            onBlur={handleBlur}
           />
           <span>+</span>
         </div>
diff --git a/lib/bigcommerce/api/cart.ts b/lib/bigcommerce/api/cart.ts
index 739f90f22..1a563b943 100644
--- a/lib/bigcommerce/api/cart.ts
+++ b/lib/bigcommerce/api/cart.ts
@@ -117,7 +117,7 @@ const cartApi: BigcommerceApiHandler<Cart> = async (req, res, config) => {
         {
           method: 'PUT',
           body: JSON.stringify({
-            line_items: [parseItem(item)],
+            line_item: parseItem(item),
           }),
         }
       )
diff --git a/lib/bigcommerce/cart/use-update-item.tsx b/lib/bigcommerce/cart/use-update-item.tsx
index be9d30ff7..0dfc30e52 100644
--- a/lib/bigcommerce/cart/use-update-item.tsx
+++ b/lib/bigcommerce/cart/use-update-item.tsx
@@ -27,7 +27,7 @@ export default function useUpdateItem() {
   const fn = useCartUpdateItem<Cart, UpdateItemBody>(fetcher)
   const updateItem: typeof fn = async (input) => {
     const data = await fn(input)
-    mutate(data)
+    await mutate(data)
     return data
   }