Skip to content

Commit

Permalink
Custom checkout improvements (vercel#590)
Browse files Browse the repository at this point in the history
* Add context for storing checkout information

* Remove unused useState
  • Loading branch information
goncy authored Dec 6, 2021
1 parent 950a763 commit d65b2ef
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 7 deletions.
4 changes: 2 additions & 2 deletions components/checkout/ShippingView/ShippingView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface Form extends HTMLFormElement {
country: HTMLSelectElement
}

const PaymentMethodView: FC = () => {
const ShippingView: FC = () => {
const { setSidebarView } = useUI()
const addAddress = useAddAddress()

Expand Down Expand Up @@ -115,4 +115,4 @@ const PaymentMethodView: FC = () => {
)
}

export default PaymentMethodView
export default ShippingView
111 changes: 111 additions & 0 deletions components/checkout/context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React, {
FC,
useCallback,
useMemo,
useReducer,
useContext,
createContext,
} from 'react'
import type { CardFields } from '@commerce/types/customer/card'
import type { AddressFields } from '@commerce/types/customer/address'

export type State = {
cardFields: CardFields
addressFields: AddressFields
}

type CheckoutContextType = State & {
setCardFields: (cardFields: CardFields) => void
setAddressFields: (addressFields: AddressFields) => void
clearCheckoutFields: () => void
}

type Action =
| {
type: 'SET_CARD_FIELDS'
card: CardFields
}
| {
type: 'SET_ADDRESS_FIELDS'
address: AddressFields
}
| {
type: 'CLEAR_CHECKOUT_FIELDS'
}

const initialState: State = {
cardFields: {} as CardFields,
addressFields: {} as AddressFields,
}

export const CheckoutContext = createContext<State | any>(initialState)

CheckoutContext.displayName = 'CheckoutContext'

const checkoutReducer = (state: State, action: Action): State => {
switch (action.type) {
case 'SET_CARD_FIELDS':
return {
...state,
cardFields: action.card,
}
case 'SET_ADDRESS_FIELDS':
return {
...state,
addressFields: action.address,
}
case 'CLEAR_CHECKOUT_FIELDS':
return {
...state,
cardFields: initialState.cardFields,
addressFields: initialState.addressFields,
}
default:
return state
}
}

export const CheckoutProvider: FC = (props) => {
const [state, dispatch] = useReducer(checkoutReducer, initialState)

const setCardFields = useCallback(
(card: CardFields) => dispatch({ type: 'SET_CARD_FIELDS', card }),
[dispatch]
)

const setAddressFields = useCallback(
(address: AddressFields) =>
dispatch({ type: 'SET_ADDRESS_FIELDS', address }),
[dispatch]
)

const clearCheckoutFields = useCallback(
() => dispatch({ type: 'CLEAR_CHECKOUT_FIELDS' }),
[dispatch]
)

const cardFields = useMemo(() => state.cardFields, [state.cardFields])

const addressFields = useMemo(() => state.addressFields, [state.addressFields])

const value = useMemo(
() => ({
cardFields,
addressFields,
setCardFields,
setAddressFields,
clearCheckoutFields,
}),
[cardFields, addressFields, setCardFields, setAddressFields, clearCheckoutFields]
)

return <CheckoutContext.Provider value={value} {...props} />
}

export const useCheckoutContext = () => {
const context = useContext<CheckoutContextType>(CheckoutContext)
if (context === undefined) {
throw new Error(`useCheckoutContext must be used within a CheckoutProvider`)
}
return context
}
5 changes: 4 additions & 1 deletion components/common/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useAcceptCookies } from '@lib/hooks/useAcceptCookies'
import { Sidebar, Button, LoadingDots } from '@components/ui'
import PaymentMethodView from '@components/checkout/PaymentMethodView'
import CheckoutSidebarView from '@components/checkout/CheckoutSidebarView'
import { CheckoutProvider } from '@components/checkout/context'
import MenuSidebarView, { Link } from '../UserNav/MenuSidebarView'

import LoginView from '@components/auth/LoginView'
Expand Down Expand Up @@ -120,7 +121,9 @@ const Layout: FC<Props> = ({
<main className="fit">{children}</main>
<Footer pages={pageProps.pages} />
<ModalUI />
<SidebarUI links={navBarlinks} />
<CheckoutProvider>
<SidebarUI links={navBarlinks} />
</CheckoutProvider>
<FeatureBar
title="This site uses cookies to improve your experience. By clicking, you agree to our Privacy Policy."
hide={acceptedCookies}
Expand Down
8 changes: 4 additions & 4 deletions framework/commerce/types/checkout.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { UseSubmitCheckout } from '../checkout/use-submit-checkout'
import type { Address } from './customer/address'
import type { Card } from './customer/card'
import type { Address, AddressFields } from './customer/address'
import type { Card, CardFields } from './customer/card'

// Index
export type Checkout = any

export type CheckoutTypes = {
card?: Card
address?: Address
card?: Card | CardFields
address?: Address | AddressFields
checkout?: Checkout
hasPayment?: boolean
hasShipping?: boolean
Expand Down

0 comments on commit d65b2ef

Please sign in to comment.