-
Notifications
You must be signed in to change notification settings - Fork 214
Expand file tree
/
Copy pathcheckout-context.js
More file actions
109 lines (95 loc) · 3.52 KB
/
checkout-context.js
File metadata and controls
109 lines (95 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* Copyright (c) 2023, Salesforce, Inc.
* All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import React, {useEffect, useState} from 'react'
import PropTypes from 'prop-types'
import useEinstein from '@salesforce/retail-react-app/app/hooks/use-einstein'
import {useCurrentCustomer} from '@salesforce/retail-react-app/app/hooks/use-current-customer'
import {useCurrentBasket} from '@salesforce/retail-react-app/app/hooks/use-current-basket'
const CheckoutContext = React.createContext()
export const CheckoutProvider = ({children}) => {
const {data: customer} = useCurrentCustomer()
const {data: basket} = useCurrentBasket()
const einstein = useEinstein()
const [step, setStep] = useState()
const CHECKOUT_STEPS_LIST = [
'CONTACT_INFO',
'PICKUP_ADDRESS',
'SHIPPING_ADDRESS',
'SHIPPING_OPTIONS',
'PAYMENT',
'REVIEW_ORDER'
]
const STEPS = CHECKOUT_STEPS_LIST.reduce((acc, step, idx) => ({...acc, [step]: idx}), {})
const getCheckoutStepName = (step) => CHECKOUT_STEPS_LIST[step]
useEffect(() => {
if (!customer || !basket) {
return
}
let step = STEPS.REVIEW_ORDER
if (customer.isGuest && !basket.customerInfo?.email) {
step = STEPS.CONTACT_INFO
} else if (!basket.shipments[0]?.shippingAddress?.address1) {
// Check if it's a pickup order
const isPickupOrder =
basket?.shipments[0]?.shippingMethod?.c_storePickupEnabled === true
step = isPickupOrder ? STEPS.PICKUP_ADDRESS : STEPS.SHIPPING_ADDRESS
} else if (!basket.shipments[0]?.shippingMethod) {
step = STEPS.SHIPPING_OPTIONS
} else if (!basket.paymentInstruments || !basket.billingAddress) {
step = STEPS.PAYMENT
}
setStep(step)
}, [
customer?.isGuest,
basket?.customerInfo?.email,
basket?.shipments[0]?.shippingAddress,
basket?.shipments[0]?.shippingMethod,
basket?.paymentInstruments,
basket?.billingAddress
])
/**************** Einstein ****************/
// Run this once when checkout begins
useEffect(() => {
if (basket?.productItems) {
einstein.sendBeginCheckout(basket)
}
}, [])
// Run this every time checkout steps change
useEffect(() => {
if (step != undefined) {
einstein.sendCheckoutStep(getCheckoutStepName(step), step, basket)
}
}, [step])
const value = {
step,
STEPS,
goToNextStep: () => {
// Check if current step is CONTACT_INFO
if (step === STEPS.CONTACT_INFO) {
// Determine if it's a pickup order
const isPickupOrder =
basket?.shipments[0]?.shippingMethod?.c_storePickupEnabled === true
// Skip to appropriate next step
setStep(isPickupOrder ? STEPS.PICKUP_ADDRESS : STEPS.SHIPPING_ADDRESS)
} else {
setStep(step + 1)
}
},
goToStep: (step) => setStep(step)
}
return <CheckoutContext.Provider value={value}>{children}</CheckoutContext.Provider>
}
CheckoutProvider.propTypes = {
children: PropTypes.any
}
/**
* A hook for managing checkout state and actions
* @returns {Object} Checkout data and actions
*/
export const useCheckout = () => {
return React.useContext(CheckoutContext)
}