forked from crowetic/commerce
Custom checkout improvements (#590)
* Add context for storing checkout information * Remove unused useState
This commit is contained in:
parent
950a7637a5
commit
d65b2efe9a
@ -22,7 +22,7 @@ interface Form extends HTMLFormElement {
|
||||
country: HTMLSelectElement
|
||||
}
|
||||
|
||||
const PaymentMethodView: FC = () => {
|
||||
const ShippingView: FC = () => {
|
||||
const { setSidebarView } = useUI()
|
||||
const addAddress = useAddAddress()
|
||||
|
||||
@ -115,4 +115,4 @@ const PaymentMethodView: FC = () => {
|
||||
)
|
||||
}
|
||||
|
||||
export default PaymentMethodView
|
||||
export default ShippingView
|
||||
|
111
components/checkout/context.tsx
Normal file
111
components/checkout/context.tsx
Normal file
@ -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
|
||||
}
|
@ -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'
|
||||
@ -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}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user