forked from crowetic/commerce
bug fixes for cart actions
This commit is contained in:
parent
80614a1df0
commit
3ac6805ebe
@ -14,7 +14,7 @@ const CartItem = ({
|
||||
currencyCode: string
|
||||
}) => {
|
||||
const { locale } = useCommerce()
|
||||
const updateItem = useUpdateItem()
|
||||
const updateItem = useUpdateItem(item)
|
||||
const removeItem = useRemoveItem()
|
||||
const [quantity, setQuantity] = useState(item.quantity)
|
||||
const { price } = formatVariantPrice({
|
||||
@ -24,14 +24,7 @@ const CartItem = ({
|
||||
locale,
|
||||
})
|
||||
const updateQuantity = async (val: number) => {
|
||||
const data = await updateItem({
|
||||
itemId: item.id,
|
||||
item: {
|
||||
productId: item.product_id,
|
||||
variantId: item.variant_id,
|
||||
quantity: val,
|
||||
},
|
||||
})
|
||||
const data = await updateItem({ quantity: val })
|
||||
}
|
||||
const handleQuantity = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const val = Number(e.target.value)
|
||||
|
@ -146,14 +146,18 @@ const cartApi: BigcommerceApiHandler<Cart> = async (req, res, config) => {
|
||||
`/v3/carts/${cartId}/items/${itemId}`,
|
||||
{ method: 'DELETE' }
|
||||
)
|
||||
const data = result?.data ?? null
|
||||
|
||||
// Update the cart cookie
|
||||
res.setHeader(
|
||||
'Set-Cookie',
|
||||
getCartCookie(config.cartCookie, cartId, config.cartCookieMaxAge)
|
||||
data
|
||||
? // Update the cart cookie
|
||||
getCartCookie(config.cartCookie, cartId, config.cartCookieMaxAge)
|
||||
: // Remove the cart cookie if the cart was removed (empty items)
|
||||
getCartCookie(config.cartCookie)
|
||||
)
|
||||
|
||||
return res.status(200).json({ data: result?.data })
|
||||
return res.status(200).json({ data })
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
@ -16,7 +16,7 @@ export const CartProvider: FC = ({ children }) => {
|
||||
}
|
||||
|
||||
export function useCart() {
|
||||
const cart = useCommerceCart<Cart>()
|
||||
const cart = useCommerceCart<Cart | null>()
|
||||
|
||||
// Uses a getter to only calculate the prop when required
|
||||
// cart.data is also a getter and it's better to not trigger it early
|
||||
|
@ -23,7 +23,7 @@ export default function useAddItem() {
|
||||
const fn = useCartAddItem<Cart, AddItemBody>(fetcher)
|
||||
const addItem: typeof fn = async (input) => {
|
||||
const data = await fn(input)
|
||||
mutate(data)
|
||||
await mutate(data, false)
|
||||
return data
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,10 @@ import { Cart, useCart } from '.'
|
||||
|
||||
export type { ItemBody, RemoveItemBody }
|
||||
|
||||
function fetcher(fetch: Fetcher<Cart>, { itemId }: RemoveItemBody) {
|
||||
export function fetcher(
|
||||
fetch: Fetcher<Cart | null>,
|
||||
{ itemId }: RemoveItemBody
|
||||
) {
|
||||
return fetch({
|
||||
url: '/api/bigcommerce/cart',
|
||||
method: 'DELETE',
|
||||
@ -15,10 +18,10 @@ function fetcher(fetch: Fetcher<Cart>, { itemId }: RemoveItemBody) {
|
||||
|
||||
export default function useRemoveItem() {
|
||||
const { mutate } = useCart()
|
||||
const fn = useCartRemoveItem<Cart, RemoveItemBody>(fetcher)
|
||||
const fn = useCartRemoveItem<Cart | null, RemoveItemBody>(fetcher)
|
||||
const removeItem: typeof fn = async (input) => {
|
||||
const data = await fn(input)
|
||||
mutate(data)
|
||||
await mutate(data, false)
|
||||
return data
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,22 @@
|
||||
import type { Fetcher } from '@lib/commerce'
|
||||
import { default as useCartUpdateItem } from '@lib/commerce/cart/use-update-item'
|
||||
import type { ItemBody, UpdateItemBody } from '../api/cart'
|
||||
import { fetcher as removeFetcher } from './use-remove-item'
|
||||
import { Cart, useCart } from '.'
|
||||
|
||||
export type { ItemBody, UpdateItemBody }
|
||||
export type UpdateItemInput = Partial<{ id: string } & ItemBody>
|
||||
|
||||
function fetcher(fetch: Fetcher<Cart>, { itemId, item }: UpdateItemBody) {
|
||||
if (
|
||||
item.quantity &&
|
||||
(!Number.isInteger(item.quantity) || item.quantity! < 1)
|
||||
) {
|
||||
throw new Error(
|
||||
'The item quantity has to be a valid integer greater than 0'
|
||||
)
|
||||
function fetcher(
|
||||
fetch: Fetcher<Cart | null>,
|
||||
{ itemId, item }: UpdateItemBody
|
||||
) {
|
||||
if (Number.isInteger(item.quantity)) {
|
||||
// Also allow the update hook to remove an item if the quantity is lower than 1
|
||||
if (item.quantity! < 1) {
|
||||
return removeFetcher(fetch, { itemId })
|
||||
}
|
||||
} else if (item.quantity) {
|
||||
throw new Error('The item quantity has to be a valid integer')
|
||||
}
|
||||
|
||||
return fetch({
|
||||
@ -22,11 +26,18 @@ function fetcher(fetch: Fetcher<Cart>, { itemId, item }: UpdateItemBody) {
|
||||
})
|
||||
}
|
||||
|
||||
export default function useUpdateItem() {
|
||||
export default function useUpdateItem(item: any = {}) {
|
||||
const { mutate } = useCart()
|
||||
const fn = useCartUpdateItem<Cart, UpdateItemBody>(fetcher)
|
||||
const updateItem: typeof fn = async (input) => {
|
||||
const data = await fn(input)
|
||||
const fn = useCartUpdateItem<Cart | null, UpdateItemBody>(fetcher)
|
||||
const updateItem = async (input: UpdateItemInput) => {
|
||||
const data = await fn({
|
||||
itemId: input.id ?? item.id,
|
||||
item: {
|
||||
productId: input.productId ?? item.product_id,
|
||||
variantId: input.productId ?? item.variant_id,
|
||||
quantity: input.quantity,
|
||||
},
|
||||
})
|
||||
await mutate(data, false)
|
||||
return data
|
||||
}
|
||||
|
@ -20,10 +20,11 @@ const CartProvider: FC<CartProviderProps> = ({ children, query, url }) => {
|
||||
|
||||
function useCart<C>() {
|
||||
const { fetcher: fetch, cartCookie } = useCommerce()
|
||||
const fetcher = (url?: string, query?: string) => fetch({ url, query })
|
||||
const cartId = Cookies.get(cartCookie)
|
||||
const fetcher = (url?: string, query?: string) => {
|
||||
return Cookies.get(cartCookie) ? fetch({ url, query }) : null
|
||||
}
|
||||
const { url, query } = useContext(CartContext)
|
||||
const response = useSWR(() => (cartId ? [url, query] : null), fetcher, {
|
||||
const response = useSWR([url, query], fetcher, {
|
||||
revalidateOnFocus: false,
|
||||
})
|
||||
|
||||
|
@ -8,6 +8,7 @@ import getAllProductPaths from '@lib/bigcommerce/api/operations/get-all-product-
|
||||
export async function getStaticProps({
|
||||
params,
|
||||
}: GetStaticPropsContext<{ slug: string }>) {
|
||||
console.log('SLUG', params!.slug)
|
||||
const { product } = await getProduct({ variables: { slug: params!.slug } })
|
||||
|
||||
if (!product) {
|
||||
@ -43,7 +44,7 @@ export async function getStaticPaths() {
|
||||
|
||||
return {
|
||||
paths: products.map((product) => `/product${product!.node.path}`),
|
||||
fallback: 'unstable_blocking',
|
||||
fallback: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user