mirror of
https://github.com/vercel/commerce.git
synced 2025-05-17 23:16:59 +00:00
Fix typescript errors & normalize cart
Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
parent
7d1b542b6f
commit
2a32beb5cd
@ -5,7 +5,9 @@ import type {
|
|||||||
HookFetcherContext,
|
HookFetcherContext,
|
||||||
} from '@vercel/commerce/utils/types'
|
} from '@vercel/commerce/utils/types'
|
||||||
import { ValidationError } from '@vercel/commerce/utils/errors'
|
import { ValidationError } from '@vercel/commerce/utils/errors'
|
||||||
import useUpdateItem, { UseUpdateItem } from '@vercel/commerce/cart/use-update-item'
|
import useUpdateItem, {
|
||||||
|
UseUpdateItem,
|
||||||
|
} from '@vercel/commerce/cart/use-update-item'
|
||||||
import type { LineItem, UpdateItemHook } from '@vercel/commerce/types/cart'
|
import type { LineItem, UpdateItemHook } from '@vercel/commerce/types/cart'
|
||||||
import { handler as removeItemHandler } from './use-remove-item'
|
import { handler as removeItemHandler } from './use-remove-item'
|
||||||
import useCart from './use-cart'
|
import useCart from './use-cart'
|
||||||
|
@ -4,7 +4,6 @@ import addCartItemsMutation from '../../mutations/add-cart-item'
|
|||||||
import createCartMutation from '../../mutations/create-cart'
|
import createCartMutation from '../../mutations/create-cart'
|
||||||
|
|
||||||
import type { CartEndpoint } from '.'
|
import type { CartEndpoint } from '.'
|
||||||
import { CreateCartPayload } from '../../../../schema'
|
|
||||||
|
|
||||||
const addItem: CartEndpoint['handlers']['addItem'] = async ({
|
const addItem: CartEndpoint['handlers']['addItem'] = async ({
|
||||||
res,
|
res,
|
||||||
@ -37,20 +36,28 @@ const addItem: CartEndpoint['handlers']['addItem'] = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!cartId) {
|
if (!cartId) {
|
||||||
const { data } = await config.fetch(createCartMutation, { variables })
|
const {
|
||||||
|
data: { createCart },
|
||||||
|
} = await config.fetch(createCartMutation, { variables })
|
||||||
res.setHeader('Set-Cookie', [
|
res.setHeader('Set-Cookie', [
|
||||||
getCartCookie(config.cartCookie, data.cart._id, config.cartCookieMaxAge),
|
getCartCookie(
|
||||||
|
config.cartCookie,
|
||||||
|
createCart.cart._id,
|
||||||
|
config.cartCookieMaxAge
|
||||||
|
),
|
||||||
getCartCookie(
|
getCartCookie(
|
||||||
config.anonymousCartTokenCookie,
|
config.anonymousCartTokenCookie,
|
||||||
data.token,
|
createCart.token,
|
||||||
config.cartCookieMaxAge
|
config.cartCookieMaxAge
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
|
|
||||||
return res.status(200).json({ data: normalizeCart(data.cart) })
|
return res.status(200).json({ data: normalizeCart(createCart.cart) })
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data } = await config.fetch(addCartItemsMutation, {
|
const {
|
||||||
|
data: { addCartItems },
|
||||||
|
} = await config.fetch(addCartItemsMutation, {
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
items: variables.input.items,
|
items: variables.input.items,
|
||||||
@ -60,7 +67,7 @@ const addItem: CartEndpoint['handlers']['addItem'] = async ({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
return res.status(200).json({ data: normalizeCart(data.cart) })
|
return res.status(200).json({ data: normalizeCart(addCartItems.cart) })
|
||||||
}
|
}
|
||||||
|
|
||||||
export default addItem
|
export default addItem
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { normalizeCart } from '../../../utils/normalize'
|
import { normalizeCart } from '../../../utils/normalize'
|
||||||
import getCartCookie from '../../utils/get-cart-cookie'
|
import getAnonymousCartQuery from '../../queries/get-anonymous-cart'
|
||||||
import getAnonymousCart from '../../queries/get-anonymous-cart'
|
|
||||||
import type { CartEndpoint } from '.'
|
import type { CartEndpoint } from '.'
|
||||||
|
|
||||||
// Return current cart info
|
// Return current cart info
|
||||||
@ -11,7 +10,9 @@ const getCart: CartEndpoint['handlers']['getCart'] = async ({
|
|||||||
config,
|
config,
|
||||||
}) => {
|
}) => {
|
||||||
if (cartId && cookies[config.anonymousCartTokenCookie]) {
|
if (cartId && cookies[config.anonymousCartTokenCookie]) {
|
||||||
const { data } = await config.fetch(getAnonymousCart, {
|
const {
|
||||||
|
data: { cart: rawAnonymousCart },
|
||||||
|
} = await config.fetch(getAnonymousCartQuery, {
|
||||||
variables: {
|
variables: {
|
||||||
cartId,
|
cartId,
|
||||||
cartToken: cookies[config.anonymousCartTokenCookie],
|
cartToken: cookies[config.anonymousCartTokenCookie],
|
||||||
@ -19,7 +20,7 @@ const getCart: CartEndpoint['handlers']['getCart'] = async ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
data: normalizeCart(data),
|
data: normalizeCart(rawAnonymousCart),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ const removeItem: CartEndpoint['handlers']['removeItem'] = async ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data } = await config.fetch(removeCartItemsMutation, {
|
const {
|
||||||
|
data: { removeCartItems },
|
||||||
|
} = await config.fetch(removeCartItemsMutation, {
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
cartId,
|
cartId,
|
||||||
@ -31,7 +33,7 @@ const removeItem: CartEndpoint['handlers']['removeItem'] = async ({
|
|||||||
getCartCookie(config.cartCookie, cartId, config.cartCookieMaxAge)
|
getCartCookie(config.cartCookie, cartId, config.cartCookieMaxAge)
|
||||||
)
|
)
|
||||||
|
|
||||||
res.status(200).json({ data: normalizeCart(data.cart) })
|
res.status(200).json({ data: normalizeCart(removeCartItems.cart) })
|
||||||
}
|
}
|
||||||
|
|
||||||
export default removeItem
|
export default removeItem
|
||||||
|
@ -2,6 +2,7 @@ import { normalizeCart } from '../../../utils/normalize'
|
|||||||
import getCartCookie from '../../utils/get-cart-cookie'
|
import getCartCookie from '../../utils/get-cart-cookie'
|
||||||
import updateCartItemsQuantityMutation from '../../mutations/update-cart-item-quantity'
|
import updateCartItemsQuantityMutation from '../../mutations/update-cart-item-quantity'
|
||||||
import type { CartEndpoint } from '.'
|
import type { CartEndpoint } from '.'
|
||||||
|
import { UpdateCartItemsQuantityPayload } from '../../../../schema'
|
||||||
|
|
||||||
const updateItem: CartEndpoint['handlers']['updateItem'] = async ({
|
const updateItem: CartEndpoint['handlers']['updateItem'] = async ({
|
||||||
res,
|
res,
|
||||||
@ -16,9 +17,11 @@ const updateItem: CartEndpoint['handlers']['updateItem'] = async ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data } = await config.fetch(updateCartItemsQuantityMutation, {
|
const {
|
||||||
|
data: { updateCartItemsQuantity },
|
||||||
|
} = await config.fetch(updateCartItemsQuantityMutation, {
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
updateCartItemsQuantityInput: {
|
||||||
cartId,
|
cartId,
|
||||||
cartToken: cookies[config.anonymousCartTokenCookie],
|
cartToken: cookies[config.anonymousCartTokenCookie],
|
||||||
items: [{ cartItemId: itemId, quantity: item.quantity }],
|
items: [{ cartItemId: itemId, quantity: item.quantity }],
|
||||||
@ -31,7 +34,7 @@ const updateItem: CartEndpoint['handlers']['updateItem'] = async ({
|
|||||||
'Set-Cookie',
|
'Set-Cookie',
|
||||||
getCartCookie(config.cartCookie, cartId, config.cartCookieMaxAge)
|
getCartCookie(config.cartCookie, cartId, config.cartCookieMaxAge)
|
||||||
)
|
)
|
||||||
res.status(200).json({ data: normalizeCart(data.cart) })
|
res.status(200).json({ data: normalizeCart(updateCartItemsQuantity.cart) })
|
||||||
}
|
}
|
||||||
|
|
||||||
export default updateItem
|
export default updateItem
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { cartPayloadFragment } from '../queries/get-cart-query'
|
import { cartPayloadFragment } from '../queries/get-cart-query'
|
||||||
|
|
||||||
const updateCartItemsQuantityMutation = `
|
const updateCartItemsQuantityMutation = /* GraphQL */ `
|
||||||
mutation updateCartItemsQuantity($updateCartItemsQuantityInput: UpdateCartItemsQuantityInput!) {
|
mutation updateCartItemsQuantity($updateCartItemsQuantityInput: UpdateCartItemsQuantityInput!) {
|
||||||
updateCartItemsQuantity(input: $updateCartItemsQuantityInput) {
|
updateCartItemsQuantity(input: $updateCartItemsQuantityInput) {
|
||||||
cart {
|
cart {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { cartQueryFragment } from './get-cart-query'
|
import { cartQueryFragment } from './get-cart-query'
|
||||||
|
|
||||||
export const getAnonymousCart = /* GraphQL */ `
|
export const getAnonymousCart = `
|
||||||
query anonymousCartByCartIdQuery($cartId: ID!, $cartToken: String!) {
|
query anonymousCartByCartIdQuery($cartId: ID!, $cartToken: String!, $itemsAfterCursor: ConnectionCursor) {
|
||||||
cart: anonymousCartByCartId(cartId: $cartId, cartToken: $cartToken) {
|
cart: anonymousCartByCartId(cartId: $cartId, cartToken: $cartToken) {
|
||||||
${cartQueryFragment}
|
${cartQueryFragment}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@ import useAddItem, { UseAddItem } from '@vercel/commerce/cart/use-add-item'
|
|||||||
import type { AddItemHook } from '@vercel/commerce/types/cart'
|
import type { AddItemHook } from '@vercel/commerce/types/cart'
|
||||||
import { CommerceError } from '@vercel/commerce/utils/errors'
|
import { CommerceError } from '@vercel/commerce/utils/errors'
|
||||||
import { MutationHook } from '@vercel/commerce/utils/types'
|
import { MutationHook } from '@vercel/commerce/utils/types'
|
||||||
|
import { CartTypes } from '../types/cart'
|
||||||
import useCart from './use-cart'
|
import useCart from './use-cart'
|
||||||
|
|
||||||
export default useAddItem as UseAddItem<typeof handler>
|
export default useAddItem as UseAddItem<typeof handler>
|
||||||
|
|
||||||
export const handler: MutationHook<AddItemHook> = {
|
export const handler: MutationHook<AddItemHook<CartTypes>> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
url: '/api/cart',
|
url: '/api/cart',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
import {
|
import {
|
||||||
HookFetcherContext,
|
HookFetcherContext,
|
||||||
|
MutationHook,
|
||||||
MutationHookContext,
|
MutationHookContext,
|
||||||
} from '@vercel/commerce/utils/types'
|
} from '@vercel/commerce/utils/types'
|
||||||
import useRemoveItem, {
|
import useRemoveItem, {
|
||||||
@ -24,16 +25,12 @@ export type RemoveItemFn<T = any> = T extends LineItem
|
|||||||
|
|
||||||
export default useRemoveItem as UseRemoveItem<typeof handler>
|
export default useRemoveItem as UseRemoveItem<typeof handler>
|
||||||
|
|
||||||
export const handler = {
|
export const handler: MutationHook<RemoveItemHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
url: '/api/cart',
|
url: '/api/cart',
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
},
|
},
|
||||||
async fetcher({
|
async fetcher({ input: { itemId }, options, fetch }) {
|
||||||
input: { itemId },
|
|
||||||
options,
|
|
||||||
fetch,
|
|
||||||
}: HookFetcherContext<RemoveItemHook>) {
|
|
||||||
return await fetch({ ...options, body: { itemId } })
|
return await fetch({ ...options, body: { itemId } })
|
||||||
},
|
},
|
||||||
useHook:
|
useHook:
|
||||||
@ -54,6 +51,6 @@ export const handler = {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
return useCallback(removeItem, [fetch, mutate])
|
return useCallback(removeItem as RemoveItemFn<T>, [fetch, mutate])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,14 @@ export default useUpdateItem as UseUpdateItem<typeof handler>
|
|||||||
|
|
||||||
export const handler: MutationHook<UpdateItemHook> = {
|
export const handler: MutationHook<UpdateItemHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: '/api/cart',
|
url: '/api/cart',
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
},
|
},
|
||||||
async fetcher({ input: { itemId, item }, options, fetch }) {
|
async fetcher({ input: { itemId, item }, options, fetch }) {
|
||||||
if (Number.isInteger(item.quantity)) {
|
if (Number.isInteger(item.quantity)) {
|
||||||
// Also allow the update hook to remove an item if the quantity is lower than 1
|
// Also allow the update hook to remove an item if the quantity is lower than 1
|
||||||
if (item.quantity! < 1) {
|
if (item.quantity! < 1) {
|
||||||
return removeItemHandler.fetcher({
|
return removeItemHandler.fetcher!({
|
||||||
options: removeItemHandler.fetchOptions,
|
options: removeItemHandler.fetchOptions,
|
||||||
input: { itemId },
|
input: { itemId },
|
||||||
fetch,
|
fetch,
|
||||||
|
@ -8,15 +8,13 @@ export type Cart = Core.Cart & {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type CartItemBody = Core.CartItemBody & {
|
export type CartItemBody = Core.CartItemBody & {
|
||||||
price: {
|
price?: {
|
||||||
amount: number
|
amount: number
|
||||||
currency: string
|
currencyCode: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CartTypes = {
|
export type CartTypes = Core.CartTypes & {
|
||||||
cart: Cart
|
|
||||||
item: Core.LineItem
|
|
||||||
itemBody: CartItemBody
|
itemBody: CartItemBody
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,6 +273,7 @@ function normalizeLineItem(cartItemEdge: CartItemEdge): LineItem {
|
|||||||
optionTitle,
|
optionTitle,
|
||||||
variantTitle,
|
variantTitle,
|
||||||
quantity,
|
quantity,
|
||||||
|
productSlug,
|
||||||
} = <CartItem>cartItem
|
} = <CartItem>cartItem
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -292,7 +293,7 @@ function normalizeLineItem(cartItemEdge: CartItemEdge): LineItem {
|
|||||||
price: priceWhenAdded?.amount,
|
price: priceWhenAdded?.amount,
|
||||||
listPrice: compareAtPrice?.amount ?? 0,
|
listPrice: compareAtPrice?.amount ?? 0,
|
||||||
},
|
},
|
||||||
path: '',
|
path: productSlug ?? '',
|
||||||
discounts: [],
|
discounts: [],
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
|
@ -45,13 +45,17 @@ const CartItem = ({
|
|||||||
target: { value },
|
target: { value },
|
||||||
}: ChangeEvent<HTMLInputElement>) => {
|
}: ChangeEvent<HTMLInputElement>) => {
|
||||||
setQuantity(Number(value))
|
setQuantity(Number(value))
|
||||||
await updateItem({ quantity: Number(value) })
|
await updateItem({
|
||||||
|
quantity: Number(value),
|
||||||
|
variantId: item.variantId,
|
||||||
|
id: item.id,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const increaseQuantity = async (n = 1) => {
|
const increaseQuantity = async (n = 1) => {
|
||||||
const val = Number(quantity) + n
|
const val = Number(quantity) + n
|
||||||
setQuantity(val)
|
setQuantity(val)
|
||||||
await updateItem({ quantity: val })
|
await updateItem({ quantity: val, variantId: item.variantId, id: item.id })
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRemove = async () => {
|
const handleRemove = async () => {
|
||||||
@ -93,7 +97,7 @@ const CartItem = ({
|
|||||||
width={150}
|
width={150}
|
||||||
height={150}
|
height={150}
|
||||||
src={item.variant.image?.url || placeholderImg}
|
src={item.variant.image?.url || placeholderImg}
|
||||||
alt={item.variant.image?.altText || "Product Image"}
|
alt={item.variant.image?.altText || 'Product Image'}
|
||||||
unoptimized
|
unoptimized
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
@ -32,6 +32,10 @@ const ProductSidebar: FC<ProductSidebarProps> = ({ product, className }) => {
|
|||||||
await addItem({
|
await addItem({
|
||||||
productId: String(product.id),
|
productId: String(product.id),
|
||||||
variantId: String(variant ? variant.id : product.variants[0]?.id),
|
variantId: String(variant ? variant.id : product.variants[0]?.id),
|
||||||
|
price: {
|
||||||
|
amount: product.price.value,
|
||||||
|
currencyCode: String(product.price.currencyCode),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
openSidebar()
|
openSidebar()
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user