Skip to content

Commit

Permalink
feat: wip react query cart mutations
Browse files Browse the repository at this point in the history
  • Loading branch information
field123 committed Nov 13, 2023
1 parent 55b4b0b commit e1a7faa
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 0 deletions.
91 changes: 91 additions & 0 deletions packages/react-shopper-hooks/src/context/cart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React, { useState } from "react"
import { useCreateCart, useUpdateCart } from "../hooks/cart"
import { Cart } from "../types"

interface CartState {
cart?: Cart
}

interface CartContext extends CartState {
setCart: (cart: Cart) => void
pay: ReturnType<typeof useSetPaymentSession>
createCart: ReturnType<typeof useCreateCart>
startCheckout: ReturnType<typeof useCreatePaymentSession>
completeCheckout: ReturnType<typeof useCompleteCart>
updateCart: ReturnType<typeof useUpdateCart>
addShippingMethod: ReturnType<typeof useAddShippingMethodToCart>
totalItems: number
}

const CartContext = React.createContext<CartContext | null>(null)

export const useCart = () => {
const context = React.useContext(CartContext)
if (!context) {
throw new Error("useCart must be used within a CartProvider")
}
return context
}

interface CartProps {
children: React.ReactNode
initialState?: Cart
}

const defaultInitialState = {
id: "",
items: [] as any,
} as Cart

export const CartProvider = ({
children,
initialState = defaultInitialState,
}: CartProps) => {
const [cart, setCart] = useState<Cart>(initialState)

const createCart = useCreateCart({
onSuccess: (response) => setCart(cart),
})

const updateCart = useUpdateCart(cart?.id, {
onSuccess: ({ cart }) => setCart(cart),
})

const addShippingMethod = useAddShippingMethodToCart(cart?.id, {
onSuccess: ({ cart }) => setCart(cart),
})

const startCheckout = useCreatePaymentSession(cart?.id, {
onSuccess: ({ cart }) => setCart(cart),
})

const pay = useSetPaymentSession(cart?.id, {
onSuccess: ({ cart }) => {
setCart(cart)
},
})

const completeCheckout = useCompleteCart(cart?.id)

const totalItems = cart?.items
.map((i) => i.quantity)
.reduce((acc, curr) => acc + curr, 0)

return (
<CartContext.Provider
value={{
cart,
setCart,
createCart,
pay,
startCheckout,
completeCheckout,
updateCart,
addShippingMethod,
totalItems: totalItems || 0,
}}
>
{children}
</CartContext.Provider>
)
}
1 change: 1 addition & 0 deletions packages/react-shopper-hooks/src/hooks/cart/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./queries"
export * from "./mutations"
97 changes: 97 additions & 0 deletions packages/react-shopper-hooks/src/hooks/cart/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import {
Address,
Cart,
CartAdditionalHeaders,
CartItemsResponse,
CheckoutCustomer,
CheckoutCustomerObject,
CreateCartObject,
Moltin as ElasticPath,
Order,
Resource,
} from "@moltin/sdk"
import { useMutation, UseMutationOptions } from "@tanstack/react-query"
import { useElasticPath } from "../../context"

type CartFnReturn = ReturnType<ElasticPath["Cart"]>

export const useCreateCart = (
options?: UseMutationOptions<
Resource<Cart>,
Error,
{
data: CreateCartObject
token?: string
}
>,
) => {
const { client } = useElasticPath()
return useMutation({
mutationFn: ({ data, token }: { data: CreateCartObject; token?: string }) =>
client.Cart().CreateCart(data, token),
...options,
})
}

export const useUpdateCart = (
cartId: string,
options?: UseMutationOptions<
CartItemsResponse,
Error,
{
data: CreateCartObject
token?: string
}
>,
) => {
const { client } = useElasticPath()
return useMutation({
mutationFn: ({ data, token }: { data: CreateCartObject; token?: string }) =>
client.Cart(cartId).UpdateCart(data, token),
...options,
})
}

export const useCheckoutCart = (
cartId: string,
options?: UseMutationOptions<
Resource<Order>,
Error,
{
customer: string | CheckoutCustomer | CheckoutCustomerObject
billingAddress: Partial<Address>
shippingAddress?: Partial<Address>
additionalHeaders?: CartAdditionalHeaders
}
>,
) => {
const { client } = useElasticPath()
return useMutation({
mutationFn: ({
customer,
billingAddress,
shippingAddress,
additionalHeaders,
}: {
customer: string | CheckoutCustomer | CheckoutCustomerObject
billingAddress: Partial<Address>
shippingAddress?: Partial<Address>
additionalHeaders?: CartAdditionalHeaders
}) =>
client
.Cart(cartId)
.Checkout(customer, billingAddress, shippingAddress, additionalHeaders),
...options,
})
}

export const useRemoveAllItems = (
cartId: string,
options?: UseMutationOptions<CartItemsResponse, Error>,
) => {
const { client } = useElasticPath()
return useMutation({
mutationFn: () => client.Cart(cartId).RemoveAllItems(),
...options,
})
}

0 comments on commit e1a7faa

Please sign in to comment.