tf-checkout-react 1.6.6 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +401 -59
- package/dist/adapters/customFields.d.ts +1 -0
- package/dist/api/checkout.d.ts +2 -0
- package/dist/api/common.d.ts +1 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/preRegistrationComplete.d.ts +1 -1
- package/dist/components/addonsContainer/AddonComponent.d.ts +6 -1
- package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +17 -0
- package/dist/components/addonsContainer/index.d.ts +6 -1
- package/dist/components/billing-info-container/hooks/index.d.ts +3 -0
- package/dist/components/billing-info-container/hooks/usePaymentContext.d.ts +5 -0
- package/dist/components/billing-info-container/hooks/usePaymentRedirect.d.ts +14 -0
- package/dist/components/billing-info-container/hooks/useStripePayment.d.ts +18 -0
- package/dist/components/billing-info-container/index.d.ts +13 -2
- package/dist/components/billing-info-container/utils.d.ts +25 -1
- package/dist/components/common/DatePickerField.d.ts +7 -1
- package/dist/components/confirmationContainer/index.d.ts +4 -1
- package/dist/components/countdown/index.d.ts +1 -1
- package/dist/components/forgotPasswordModal/index.d.ts +2 -1
- package/dist/components/myTicketsContainer/index.d.ts +3 -2
- package/dist/components/orderDetailsContainer/index.d.ts +8 -1
- package/dist/components/paymentContainer/OrderDetails.d.ts +9 -0
- package/dist/components/paymentContainer/handlePayment.d.ts +15 -0
- package/dist/components/paymentContainer/index.d.ts +12 -6
- package/dist/components/preRegistration/FieldsSection.d.ts +7 -1
- package/dist/components/preRegistration/PreRegistrationComplete.d.ts +6 -0
- package/dist/components/preRegistration/constants.d.ts +2 -2
- package/dist/components/preRegistration/index.d.ts +6 -0
- package/dist/components/resetPasswordContainer/index.d.ts +2 -2
- package/dist/components/ticketsContainer/InfoIcon.d.ts +5 -0
- package/dist/components/ticketsContainer/TicketsSection.d.ts +3 -2
- package/dist/components/ticketsContainer/TimeSlotsSection.d.ts +25 -0
- package/dist/components/ticketsContainer/index.d.ts +29 -5
- package/dist/components/timerWidget/index.d.ts +2 -1
- package/dist/constants/index.d.ts +5 -0
- package/dist/index.d.ts +4 -1
- package/dist/tf-checkout-react.cjs.development.js +11231 -9563
- package/dist/tf-checkout-react.cjs.development.js.map +1 -1
- package/dist/tf-checkout-react.cjs.production.min.js +1 -1
- package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
- package/dist/tf-checkout-react.esm.js +11194 -9529
- package/dist/tf-checkout-react.esm.js.map +1 -1
- package/dist/tf-checkout-styles.css +1 -1
- package/dist/types/add_on.d.ts +1 -0
- package/dist/types/checkoutPageConfigs.d.ts +1 -1
- package/dist/types/order-data.d.ts +3 -1
- package/dist/utils/auth.d.ts +8 -0
- package/dist/utils/customFields.d.ts +11 -0
- package/dist/utils/getDomain.d.ts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/setConfigs.d.ts +1 -0
- package/package.json +14 -8
- package/src/adapters/customFields.ts +7 -1
- package/src/api/auth.ts +2 -1
- package/src/api/checkout.ts +9 -4
- package/src/api/common.ts +49 -2
- package/src/api/index.ts +1 -0
- package/src/api/interceptors.ts +7 -23
- package/src/api/preRegistrationComplete.ts +1 -1
- package/src/api/publicRequest.ts +10 -0
- package/src/components/addonsContainer/AddonComponent.tsx +96 -11
- package/src/components/addonsContainer/SimpleAddonsContainer.tsx +420 -0
- package/src/components/addonsContainer/index.tsx +198 -47
- package/src/components/billing-info-container/hooks/index.ts +3 -0
- package/src/components/billing-info-container/hooks/usePaymentContext.ts +22 -0
- package/src/components/billing-info-container/hooks/usePaymentRedirect.ts +147 -0
- package/src/components/billing-info-container/hooks/useStripePayment.ts +121 -0
- package/src/components/billing-info-container/index.tsx +827 -406
- package/src/components/billing-info-container/{utils.ts → utils.tsx} +119 -0
- package/src/components/common/CheckboxField/index.tsx +1 -1
- package/src/components/common/CustomField.tsx +38 -2
- package/src/components/common/DatePickerField.tsx +25 -10
- package/src/components/common/SnackbarAlert.tsx +32 -34
- package/src/components/confirmationContainer/config.ts +3 -3
- package/src/components/confirmationContainer/index.tsx +20 -1
- package/src/components/confirmationContainer/social-buttons.tsx +5 -3
- package/src/components/confirmationContainer/style.css +9 -5
- package/src/components/countdown/index.tsx +22 -22
- package/src/components/delegationsContainer/IssueComponent.tsx +2 -1
- package/src/components/forgotPasswordModal/index.tsx +44 -13
- package/src/components/loginForm/index.tsx +1 -1
- package/src/components/loginModal/index.tsx +19 -27
- package/src/components/loginModal/style.css +3 -1
- package/src/components/myTicketsContainer/index.tsx +13 -9
- package/src/components/orderDetailsContainer/index.tsx +206 -174
- package/src/components/paymentContainer/OrderDetails.tsx +257 -0
- package/src/components/paymentContainer/handlePayment.ts +86 -0
- package/src/components/paymentContainer/index.tsx +299 -259
- package/src/components/paymentContainer/style.css +141 -0
- package/src/components/preRegistration/FieldsSection.tsx +8 -0
- package/src/components/preRegistration/PreRegistrationComplete.tsx +128 -118
- package/src/components/preRegistration/PreRegistrationInformations.tsx +21 -15
- package/src/components/preRegistration/constants.tsx +10 -4
- package/src/components/preRegistration/index.tsx +194 -174
- package/src/components/registerForm/constants.tsx +3 -1
- package/src/components/registerForm/index.tsx +3 -3
- package/src/components/registerModal/index.tsx +47 -72
- package/src/components/resetPasswordContainer/index.tsx +20 -14
- package/src/components/seatMapContainer/TicketsSection.tsx +2 -2
- package/src/components/signupModal/index.tsx +13 -6
- package/src/components/ticketResale/index.tsx +7 -0
- package/src/components/ticketsContainer/InfoIcon.tsx +35 -0
- package/src/components/ticketsContainer/PromoCodeSection.tsx +34 -28
- package/src/components/ticketsContainer/TicketRow.tsx +1 -1
- package/src/components/ticketsContainer/TicketsSection.tsx +189 -57
- package/src/components/ticketsContainer/TimeSlotsSection.tsx +120 -0
- package/src/components/ticketsContainer/index.tsx +268 -106
- package/src/components/timerWidget/index.tsx +15 -3
- package/src/constants/index.ts +2 -0
- package/src/env.ts +14 -6
- package/src/hoc/CustomFields/index.tsx +9 -1
- package/src/index.ts +7 -2
- package/src/types/add_on.ts +1 -0
- package/src/types/api/cart.d.ts +8 -0
- package/src/types/api/checkout.d.ts +58 -7
- package/src/types/api/common.d.ts +30 -0
- package/src/types/api/orders.d.ts +19 -3
- package/src/types/api/payment.d.ts +6 -2
- package/src/types/api/preRegistrationComplete.d.ts +2 -2
- package/src/types/checkoutPageConfigs.ts +1 -1
- package/src/types/order-data.ts +3 -1
- package/src/types/pre-registration-complete.d.ts +6 -1
- package/src/utils/auth.ts +32 -0
- package/src/utils/cookies.ts +42 -11
- package/src/utils/customFields.ts +22 -0
- package/src/utils/getDomain.ts +10 -4
- package/src/utils/index.ts +1 -1
- package/src/utils/setConfigs.ts +3 -1
- package/dist/components/stripePayment/index.d.ts +0 -24
- package/src/components/stripePayment/index.tsx +0 -281
- package/src/components/stripePayment/style.css +0 -60
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
2
|
import './style.css'
|
|
2
3
|
|
|
3
4
|
import { CircularProgress, ThemeOptions } from '@mui/material'
|
|
@@ -5,6 +6,7 @@ import Backdrop from '@mui/material/Backdrop'
|
|
|
5
6
|
import Button from '@mui/material/Button'
|
|
6
7
|
import { createTheme, ThemeProvider } from '@mui/material/styles'
|
|
7
8
|
import { CSSProperties } from '@mui/styles'
|
|
9
|
+
import { Stripe, StripeElementsOptions } from '@stripe/stripe-js'
|
|
8
10
|
import axios, { AxiosError } from 'axios'
|
|
9
11
|
import { Field, Form, Formik, FormikHelpers, FormikProps, FormikValues } from 'formik'
|
|
10
12
|
import _find from 'lodash/find'
|
|
@@ -16,22 +18,25 @@ import _isEmpty from 'lodash/isEmpty'
|
|
|
16
18
|
import _isEqual from 'lodash/isEqual'
|
|
17
19
|
import _map from 'lodash/map'
|
|
18
20
|
import { nanoid } from 'nanoid'
|
|
19
|
-
import React, { FC, useEffect, useRef, useState } from 'react'
|
|
21
|
+
import React, { FC, useCallback, useEffect, useRef, useState } from 'react'
|
|
20
22
|
|
|
21
23
|
import {
|
|
22
24
|
AttributesConfig,
|
|
23
25
|
getCart,
|
|
24
26
|
getCheckoutPageConfigs,
|
|
25
27
|
getCountries,
|
|
28
|
+
getPaymentData,
|
|
26
29
|
getProfileData,
|
|
27
30
|
getStates,
|
|
28
31
|
postOnCheckout,
|
|
29
32
|
register,
|
|
30
33
|
setCustomHeader,
|
|
31
34
|
} from '../../api'
|
|
35
|
+
import { updateCheckout } from '../../api/checkout'
|
|
32
36
|
import { withCustomFields } from '../../hoc'
|
|
33
37
|
import { usePixel } from '../../hooks/usePixel'
|
|
34
38
|
import { IBillingInfoData } from '../../types'
|
|
39
|
+
import { ICheckoutResponseData } from '../../types/api/checkout'
|
|
35
40
|
import {
|
|
36
41
|
createCheckoutDataBodyWithDefaultHolder,
|
|
37
42
|
deleteCookieByName,
|
|
@@ -40,21 +45,27 @@ import {
|
|
|
40
45
|
setLoggedUserData,
|
|
41
46
|
} from '../../utils'
|
|
42
47
|
import { ErrorFocus } from '../../utils/formikErrorFocus'
|
|
48
|
+
import { AddonsContainter, IAddonContainterProps } from '../addonsContainer'
|
|
49
|
+
import SimpleAddonsContainer from '../addonsContainer/SimpleAddonsContainer'
|
|
43
50
|
import SnackbarAlert from '../common/SnackbarAlert'
|
|
44
51
|
import { ForgotPasswordModal } from '../forgotPasswordModal'
|
|
45
52
|
import { VerificationPendingModal } from '../idVerificationContainer/VerificationPendingModal'
|
|
46
53
|
import { LoginModal } from '../loginModal'
|
|
54
|
+
import { IPaymentPage, PaymentContainer } from '../paymentContainer'
|
|
47
55
|
import { SignupModal } from '../signupModal'
|
|
48
56
|
import TimerWidget from '../timerWidget'
|
|
57
|
+
import { usePaymentRedirect, useStripePayment } from './hooks'
|
|
49
58
|
import {
|
|
50
59
|
assingUniqueIds,
|
|
51
60
|
createCheckoutDataBody,
|
|
52
61
|
createRegisterFormData,
|
|
62
|
+
filterBillingInfoFields,
|
|
53
63
|
getFieldComponent,
|
|
54
64
|
getFieldLabel,
|
|
55
65
|
getInitialValues,
|
|
56
66
|
getValidateFunctions,
|
|
57
67
|
ICheckoutBody,
|
|
68
|
+
renderComponentWithProps,
|
|
58
69
|
} from './utils'
|
|
59
70
|
|
|
60
71
|
export interface IBillingInfoPage {
|
|
@@ -64,7 +75,9 @@ export interface IBillingInfoPage {
|
|
|
64
75
|
values: FormikValues,
|
|
65
76
|
formikHelpers: FormikHelpers<FormikValues>,
|
|
66
77
|
eventId: any,
|
|
67
|
-
res: any
|
|
78
|
+
res: any,
|
|
79
|
+
checkoutUpdateResponse?: any,
|
|
80
|
+
paymentResponse?: any
|
|
68
81
|
) => void;
|
|
69
82
|
onRegisterSuccess?: (value: any) => void;
|
|
70
83
|
onRegisterError?: (e: AxiosError, email: string) => void;
|
|
@@ -82,8 +95,11 @@ export interface IBillingInfoPage {
|
|
|
82
95
|
onLogin?: () => void;
|
|
83
96
|
onLoginSuccess?: () => void;
|
|
84
97
|
onErrorClose?: () => void;
|
|
98
|
+
onCheckoutUpdateSuccess?: (res: any) => void;
|
|
99
|
+
onCheckoutUpdateError?: (e: AxiosError) => void;
|
|
85
100
|
initialValues?: FormikValues;
|
|
86
101
|
buttonName?: string;
|
|
102
|
+
freeOrderButtonName?: string;
|
|
87
103
|
theme?: 'light' | 'dark';
|
|
88
104
|
isLoggedIn?: boolean;
|
|
89
105
|
accountInfoTitle?: string | JSX.Element;
|
|
@@ -110,11 +126,18 @@ export interface IBillingInfoPage {
|
|
|
110
126
|
customFieldsOrderKeys?: string[];
|
|
111
127
|
customFieldsTicketHolderKeys?: string[];
|
|
112
128
|
onPendingVerification?: () => void;
|
|
129
|
+
includeAddons?: boolean;
|
|
130
|
+
addonsProps?: IAddonContainterProps;
|
|
131
|
+
addOnDataWithCustomFields?: any;
|
|
132
|
+
isSinglePageCheckout?: boolean;
|
|
133
|
+
paymentProps?: Partial<IPaymentPage>;
|
|
134
|
+
paymentSectionAddon?: React.ReactNode;
|
|
113
135
|
}
|
|
114
136
|
|
|
115
137
|
const LogicRunner: FC<{
|
|
116
138
|
brandOptIn?: boolean;
|
|
117
139
|
values: any;
|
|
140
|
+
errors: any;
|
|
118
141
|
setStates: React.Dispatch<any>;
|
|
119
142
|
setFieldValue: any;
|
|
120
143
|
setValues: any;
|
|
@@ -133,72 +156,72 @@ const LogicRunner: FC<{
|
|
|
133
156
|
shouldFetchCountries,
|
|
134
157
|
brandOptIn,
|
|
135
158
|
}) => {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
159
|
+
const prevCountry = useRef(values.country)
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
const fetchStates = async () => {
|
|
162
|
+
try {
|
|
163
|
+
const res = await getStates(values.country)
|
|
164
|
+
const mappedStates = _map(res.data, (item, key) => ({
|
|
165
|
+
label: item,
|
|
166
|
+
value: key,
|
|
167
|
+
}))
|
|
168
|
+
setStates(mappedStates)
|
|
169
|
+
if (prevCountry.current !== values.country) {
|
|
170
|
+
const stateExists = mappedStates.find(
|
|
171
|
+
state => state.value === values.state
|
|
172
|
+
)?.value
|
|
173
|
+
setFieldValue('state', stateExists ?? mappedStates[0]?.value ?? '')
|
|
174
|
+
prevCountry.current = values.country
|
|
175
|
+
}
|
|
176
|
+
onGetStatesSuccess(res.data)
|
|
177
|
+
} catch (e) {
|
|
178
|
+
if (axios.isAxiosError(e)) {
|
|
179
|
+
onGetStatesError(e)
|
|
158
180
|
}
|
|
159
181
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
182
|
+
}
|
|
183
|
+
shouldFetchCountries && fetchStates()
|
|
184
|
+
}, [values.country, setStates, setFieldValue])
|
|
185
|
+
const userDataEncoded = isBrowser ? window.localStorage.getItem('user_data') : ''
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
// set user data from local storage
|
|
188
|
+
const getStoredUserData = () => {
|
|
189
|
+
if (isBrowser) {
|
|
190
|
+
if (userDataEncoded) {
|
|
191
|
+
try {
|
|
192
|
+
const parsedData = JSON.parse(userDataEncoded)
|
|
193
|
+
const mappedValues = {
|
|
194
|
+
firstName: parsedData?.first_name || parsedData?.firstName || '',
|
|
195
|
+
lastName: parsedData?.last_name || parsedData?.lastName || '',
|
|
196
|
+
email: parsedData?.email || '',
|
|
197
|
+
phone: parsedData?.phone || '',
|
|
198
|
+
confirmEmail: parsedData?.email || '',
|
|
199
|
+
state: parsedData?.state || '',
|
|
200
|
+
street_address: parsedData?.street_address || '',
|
|
201
|
+
country: parsedData?.country || '1',
|
|
202
|
+
zip: parsedData?.zip || '',
|
|
203
|
+
brand_opt_in: brandOptIn ? brandOptIn : parsedData?.brand_opt_in || false,
|
|
204
|
+
city: parsedData?.city || '',
|
|
205
|
+
confirmPassword: '',
|
|
206
|
+
password: '',
|
|
207
|
+
'holderFirstName-0': parsedData?.first_name || parsedData?.firstName || '',
|
|
208
|
+
'holderLastName-0': parsedData?.last_name || parsedData?.lastName || '',
|
|
209
|
+
'holderEmail-0': parsedData?.email || '',
|
|
210
|
+
}
|
|
188
211
|
|
|
189
|
-
|
|
190
|
-
|
|
212
|
+
const extraDataJSON = window.localStorage.getItem('extraData')
|
|
213
|
+
const extraData = extraDataJSON ? JSON.parse(extraDataJSON) : null
|
|
191
214
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
215
|
+
setValues({ ...values, ...mappedValues, ...(extraData ?? {}) })
|
|
216
|
+
setUserValues(mappedValues)
|
|
217
|
+
} catch (e) {}
|
|
196
218
|
}
|
|
197
219
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
220
|
+
}
|
|
221
|
+
getStoredUserData()
|
|
222
|
+
}, [userDataEncoded, setValues, setUserValues, brandOptIn])
|
|
223
|
+
return null
|
|
224
|
+
}
|
|
202
225
|
|
|
203
226
|
const BillingInfoContainer = React.memo(
|
|
204
227
|
({
|
|
@@ -209,6 +232,7 @@ const BillingInfoContainer = React.memo(
|
|
|
209
232
|
},
|
|
210
233
|
initialValues = {},
|
|
211
234
|
buttonName = 'Submit',
|
|
235
|
+
freeOrderButtonName = 'Complete Registration',
|
|
212
236
|
handleSubmit = _identity,
|
|
213
237
|
theme = 'light',
|
|
214
238
|
onRegisterSuccess = _identity,
|
|
@@ -224,6 +248,8 @@ const BillingInfoContainer = React.memo(
|
|
|
224
248
|
onGetProfileDataError = _identity,
|
|
225
249
|
onLogin,
|
|
226
250
|
onLoginSuccess = _identity,
|
|
251
|
+
onCheckoutUpdateSuccess = _identity,
|
|
252
|
+
onCheckoutUpdateError = _identity,
|
|
227
253
|
isLoggedIn: pIsLoggedIn = false,
|
|
228
254
|
accountInfoTitle = '',
|
|
229
255
|
hideLogo,
|
|
@@ -249,12 +275,20 @@ const BillingInfoContainer = React.memo(
|
|
|
249
275
|
onPendingVerification = _identity,
|
|
250
276
|
onGetCheckoutConfigsSuccess = _identity,
|
|
251
277
|
onGetCheckoutConfigsError = _identity,
|
|
278
|
+
includeAddons = false,
|
|
279
|
+
addonsProps,
|
|
280
|
+
addOnDataWithCustomFields,
|
|
281
|
+
isSinglePageCheckout = false,
|
|
282
|
+
paymentProps = {},
|
|
283
|
+
paymentSectionAddon,
|
|
252
284
|
}: IBillingInfoPage) => {
|
|
253
285
|
const [extraData, setExtraData] = useState(null)
|
|
254
286
|
const [isConfigLoading, setIsConfigLoading] = useState(true)
|
|
255
287
|
const [configs, setConfigs] = useState<null | AttributesConfig>(null)
|
|
256
288
|
const [isNewUser, setIsNewUser] = useState(false)
|
|
257
289
|
const themeMui = createTheme(themeOptions)
|
|
290
|
+
const elementsRef = useRef<any>(null)
|
|
291
|
+
const stripeRef = useRef<Stripe | null>(null)
|
|
258
292
|
|
|
259
293
|
useEffect(() => {
|
|
260
294
|
if (isBrowser) {
|
|
@@ -280,8 +314,15 @@ const BillingInfoContainer = React.memo(
|
|
|
280
314
|
const defaultCountry = isBrowser ? window.localStorage.getItem('eventCountry') : ''
|
|
281
315
|
const userData =
|
|
282
316
|
isBrowser && window.localStorage.getItem('user_data')
|
|
283
|
-
? JSON.parse(window.localStorage.getItem('user_data') || '')
|
|
317
|
+
? JSON.parse(window.localStorage.getItem('user_data') || '{}')
|
|
284
318
|
: {}
|
|
319
|
+
const additionalConfigs =
|
|
320
|
+
isBrowser && window.localStorage.getItem('checkoutAdditionalConfigs')
|
|
321
|
+
? JSON.parse(
|
|
322
|
+
window.localStorage.getItem('checkoutAdditionalConfigs') ||
|
|
323
|
+
'{"resale": false, "resaleWithAddons": false}'
|
|
324
|
+
)
|
|
325
|
+
: { resale: false, resaleWithAddons: false }
|
|
285
326
|
const [dataWithUniqueIds, setDataWithUniqueIds] = useState<IBillingInfoData[]>(
|
|
286
327
|
assingUniqueIds(data)
|
|
287
328
|
)
|
|
@@ -314,7 +355,7 @@ const BillingInfoContainer = React.memo(
|
|
|
314
355
|
const [loading, setLoading] = useState(true)
|
|
315
356
|
const [cardLoading, setCardLoading] = useState(false)
|
|
316
357
|
const [isCountriesLoading, setIsCountriesLoading] = useState(true)
|
|
317
|
-
const [error, setError] = useState(null)
|
|
358
|
+
const [error, setError] = useState<string | null>(null)
|
|
318
359
|
const [phoneValidationIsLoading, setPhoneValidationIsLoading] = useState(false)
|
|
319
360
|
const emailLogged = _get(userData, 'email', '') || _get(userValues, 'email', '')
|
|
320
361
|
const firstNameLogged =
|
|
@@ -349,18 +390,27 @@ const BillingInfoContainer = React.memo(
|
|
|
349
390
|
const hideInstagramField = !collectMandatoryInstagram && !collectOptionalInstagram
|
|
350
391
|
const collectMandatoryBusinessCategory = configs?.collect_mandatory_business_category
|
|
351
392
|
const collectOptionalBusinessCategory = configs?.collect_optional_business_category
|
|
393
|
+
const eventHasAddons = configs?.has_add_on
|
|
352
394
|
const hideBusinessCategoryField =
|
|
353
395
|
!collectMandatoryBusinessCategory && !collectOptionalBusinessCategory
|
|
354
396
|
|
|
355
|
-
const [pendingVerificationMessage, setPendingVerificationMessage] = useState()
|
|
356
|
-
|
|
357
|
-
|
|
397
|
+
const [pendingVerificationMessage, setPendingVerificationMessage] = useState<string>()
|
|
398
|
+
const [reviewData, setReviewData] = useState<any>({})
|
|
399
|
+
const [checkoutData, setCheckoutData] = useState<any>({})
|
|
400
|
+
const [checkoutUpdateData, setCheckoutUpdateData] =
|
|
401
|
+
useState<ICheckoutResponseData | null>(null)
|
|
358
402
|
const prevData = useRef(data)
|
|
359
403
|
|
|
360
|
-
const addAddOnsInAttributes = (checkoutBody: any) => {
|
|
404
|
+
const addAddOnsInAttributes = useCallback((checkoutBody: any) => {
|
|
361
405
|
const selectedAddOns = window.localStorage.getItem('add_ons') || '{}'
|
|
406
|
+
const addOnDataCapture = window.localStorage.getItem('add_on_data_capture') || '{}'
|
|
407
|
+
|
|
362
408
|
checkoutBody.attributes.add_ons = JSON.parse(selectedAddOns)
|
|
363
|
-
|
|
409
|
+
checkoutBody.attributes.add_on_data_capture = JSON.parse(addOnDataCapture)
|
|
410
|
+
}, [])
|
|
411
|
+
const [singleCheckoutAddons, setSingleCheckoutAddOns] = useState<any>({})
|
|
412
|
+
|
|
413
|
+
const orderIsFree = !Number(checkoutData?.total)
|
|
364
414
|
|
|
365
415
|
useEffect(() => {
|
|
366
416
|
const hasUniqueId = _get(dataWithUniqueIds, '[0].uniqueId')
|
|
@@ -373,13 +423,13 @@ const BillingInfoContainer = React.memo(
|
|
|
373
423
|
}
|
|
374
424
|
}, [dataWithUniqueIds, data])
|
|
375
425
|
|
|
376
|
-
const getQuantity = (cart: any = []) => {
|
|
426
|
+
const getQuantity = useCallback((cart: any = []) => {
|
|
377
427
|
let qty = 0
|
|
378
428
|
cart.forEach((item: any) => {
|
|
379
429
|
qty += +item.quantity
|
|
380
430
|
})
|
|
381
431
|
return qty
|
|
382
|
-
}
|
|
432
|
+
}, [])
|
|
383
433
|
|
|
384
434
|
useEffect(() => {
|
|
385
435
|
if (pIsLoggedIn !== isLoggedIn || xtfCookie) {
|
|
@@ -407,10 +457,22 @@ const BillingInfoContainer = React.memo(
|
|
|
407
457
|
shouldFetchCountries && fetchCountries()
|
|
408
458
|
fetchCart()
|
|
409
459
|
|
|
460
|
+
// Initialize checkout with event_id on first load
|
|
461
|
+
if (isSinglePageCheckout && eventId) {
|
|
462
|
+
updateCheckoutWithAddOns()
|
|
463
|
+
}
|
|
464
|
+
|
|
410
465
|
return () => {
|
|
411
466
|
isBrowser && localStorage.removeItem('selectedTicketsQuantity')
|
|
412
467
|
}
|
|
413
|
-
|
|
468
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
469
|
+
}, [
|
|
470
|
+
eventId,
|
|
471
|
+
isSinglePageCheckout,
|
|
472
|
+
shouldFetchCountries,
|
|
473
|
+
onGetCountriesSuccess,
|
|
474
|
+
onGetCountriesError,
|
|
475
|
+
])
|
|
414
476
|
|
|
415
477
|
// fetch cart data
|
|
416
478
|
const fetchCart = async () => {
|
|
@@ -459,6 +521,45 @@ const BillingInfoContainer = React.memo(
|
|
|
459
521
|
fetchCart()
|
|
460
522
|
}, [isLoggedIn])
|
|
461
523
|
|
|
524
|
+
useEffect(() => {
|
|
525
|
+
const fetchCheckoutUpdate = async () => {
|
|
526
|
+
if (!eventId) return
|
|
527
|
+
|
|
528
|
+
try {
|
|
529
|
+
const checkoutUpdateResponse = await updateCheckout({
|
|
530
|
+
attributes: {
|
|
531
|
+
event_id: eventId,
|
|
532
|
+
is_from_resale: additionalConfigs?.resale,
|
|
533
|
+
},
|
|
534
|
+
})
|
|
535
|
+
console.log('Stripe in [useEffect] fetchCheckoutUpdate', checkoutUpdateResponse)
|
|
536
|
+
|
|
537
|
+
if (checkoutUpdateResponse.success) {
|
|
538
|
+
const checkoutAttributes = checkoutUpdateResponse.data.attributes
|
|
539
|
+
const cartPriceBreakdown = _get(
|
|
540
|
+
checkoutAttributes,
|
|
541
|
+
'cart_price_breakdown',
|
|
542
|
+
{}
|
|
543
|
+
)
|
|
544
|
+
localStorage.setItem(
|
|
545
|
+
'checkoutData',
|
|
546
|
+
JSON.stringify({ hash: '', total: _get(cartPriceBreakdown, 'total', 0) })
|
|
547
|
+
)
|
|
548
|
+
console.log(
|
|
549
|
+
'Stripe in [useEffect] fetchCheckoutUpdate | checkoutAttributes',
|
|
550
|
+
checkoutAttributes
|
|
551
|
+
)
|
|
552
|
+
setCheckoutUpdateData(checkoutAttributes)
|
|
553
|
+
onCheckoutUpdateSuccess({ expires_at: expirationTime, ...cartPriceBreakdown })
|
|
554
|
+
}
|
|
555
|
+
} catch (error) {
|
|
556
|
+
console.error('Failed to fetch checkout update:', error)
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
fetchCheckoutUpdate()
|
|
561
|
+
}, [eventId, additionalConfigs?.resale])
|
|
562
|
+
|
|
462
563
|
useEffect(() => {
|
|
463
564
|
const collectPaymentData = async () => {
|
|
464
565
|
if (
|
|
@@ -481,12 +582,13 @@ const BillingInfoContainer = React.memo(
|
|
|
481
582
|
|
|
482
583
|
const checkoutResponse = await postOnCheckout(checkoutBody, flagFreeTicket)
|
|
483
584
|
removeReferralKey()
|
|
585
|
+
removeAdditionalConfigs()
|
|
484
586
|
onSkipBillingPage(checkoutResponse.data.attributes)
|
|
485
587
|
setLoading(false)
|
|
486
588
|
} catch (e) {
|
|
487
|
-
onSubmitError(e)
|
|
488
|
-
if (e.
|
|
489
|
-
setPendingVerificationMessage(e.
|
|
589
|
+
onSubmitError(e as AxiosError)
|
|
590
|
+
if (_get(e, 'response.data.data.hasUnverifiedOrder')) {
|
|
591
|
+
setPendingVerificationMessage(_get(e, 'response.data.message'))
|
|
490
592
|
}
|
|
491
593
|
}
|
|
492
594
|
} else {
|
|
@@ -496,91 +598,266 @@ const BillingInfoContainer = React.memo(
|
|
|
496
598
|
collectPaymentData()
|
|
497
599
|
}, [skipPage, ticketsQuantity])
|
|
498
600
|
|
|
499
|
-
const collectCheckoutBody = (
|
|
500
|
-
values: Record<string, any>,
|
|
501
|
-
|
|
502
|
-
): Record<string, any> => {
|
|
503
|
-
let checkoutBody = {} as ICheckoutBody
|
|
504
|
-
|
|
505
|
-
// Auto collect ticket holders name when it was skipped optionally
|
|
506
|
-
if (showDOB && !showTicketHolders && canSkipHolderNames) {
|
|
507
|
-
checkoutBody = createCheckoutDataBodyWithDefaultHolder(
|
|
508
|
-
ticketsQuantity.length,
|
|
509
|
-
values,
|
|
510
|
-
true,
|
|
511
|
-
{ emailLogged, firstNameLogged, lastNameLogged }
|
|
512
|
-
)
|
|
513
|
-
} else {
|
|
514
|
-
checkoutBody = createCheckoutDataBody(
|
|
515
|
-
ticketsQuantity.length,
|
|
516
|
-
values,
|
|
517
|
-
{
|
|
518
|
-
emailLogged: emailLogged || profileData.email,
|
|
519
|
-
firstNameLogged:
|
|
520
|
-
firstNameLogged || profileData.first_name || profileData.firstName,
|
|
521
|
-
lastNameLogged:
|
|
522
|
-
lastNameLogged || profileData.last_name || profileData.lastName,
|
|
523
|
-
},
|
|
524
|
-
showDOB
|
|
525
|
-
)
|
|
526
|
-
}
|
|
601
|
+
const collectCheckoutBody = useCallback(
|
|
602
|
+
(values: Record<string, any>, profileData?: any): Record<string, any> => {
|
|
603
|
+
let checkoutBody = {} as ICheckoutBody
|
|
527
604
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
605
|
+
// Auto collect ticket holders name when it was skipped optionally
|
|
606
|
+
if (showDOB && !showTicketHolders && canSkipHolderNames) {
|
|
607
|
+
checkoutBody = createCheckoutDataBodyWithDefaultHolder(
|
|
608
|
+
ticketsQuantity.length,
|
|
609
|
+
values,
|
|
610
|
+
true,
|
|
611
|
+
{ emailLogged, firstNameLogged, lastNameLogged }
|
|
612
|
+
)
|
|
613
|
+
} else {
|
|
614
|
+
checkoutBody = createCheckoutDataBody(
|
|
615
|
+
ticketsQuantity.length,
|
|
616
|
+
values,
|
|
617
|
+
{
|
|
618
|
+
emailLogged: emailLogged || profileData.email,
|
|
619
|
+
firstNameLogged:
|
|
620
|
+
firstNameLogged || profileData.first_name || profileData.firstName,
|
|
621
|
+
lastNameLogged:
|
|
622
|
+
lastNameLogged || profileData.last_name || profileData.lastName,
|
|
623
|
+
},
|
|
624
|
+
showDOB
|
|
625
|
+
)
|
|
626
|
+
}
|
|
532
627
|
|
|
533
|
-
//
|
|
534
|
-
|
|
535
|
-
|
|
628
|
+
// Collect data_capture for Order Custom Fields
|
|
629
|
+
const data_capture: Record<string, any> = {}
|
|
630
|
+
_forEach(customFieldsOrderKeys, (key: string) => {
|
|
631
|
+
data_capture[key] = values[key]
|
|
536
632
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
'company',
|
|
541
|
-
'instagram',
|
|
542
|
-
'jobTitle',
|
|
543
|
-
'wallet_address',
|
|
544
|
-
]
|
|
633
|
+
// Delete from values list
|
|
634
|
+
delete checkoutBody.attributes[key]
|
|
635
|
+
})
|
|
545
636
|
|
|
546
|
-
|
|
547
|
-
const
|
|
548
|
-
|
|
637
|
+
// Temp solution for hardcoded data capture values, to be deleted in the future
|
|
638
|
+
const captureKeys = [
|
|
639
|
+
'businessCategory',
|
|
640
|
+
'company',
|
|
641
|
+
'instagram',
|
|
642
|
+
'jobTitle',
|
|
643
|
+
'wallet_address',
|
|
644
|
+
]
|
|
549
645
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
646
|
+
captureKeys.forEach(key => {
|
|
647
|
+
const path = `data_capture.${key}`
|
|
648
|
+
const value = _get(values, path, '')
|
|
553
649
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
650
|
+
if (value !== '') {
|
|
651
|
+
data_capture[key] = value
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
const attributeKey = `data_capture[${key}]`
|
|
655
|
+
delete checkoutBody.attributes?.[attributeKey]
|
|
656
|
+
})
|
|
657
|
+
|
|
658
|
+
// Collect data_capture for Ticket Holders Fields
|
|
659
|
+
_forEach(checkoutBody.attributes.ticket_holders, (holder, holderIndex) => {
|
|
660
|
+
const holderDataCapture: Record<string, any> = {}
|
|
661
|
+
|
|
662
|
+
_forEach(customFieldsTicketHolderKeys, customFieldKey => {
|
|
663
|
+
const customFieldHolderName = `${customFieldKey}-${holderIndex}`
|
|
664
|
+
const customFieldHolderKey = values[customFieldHolderName] || ''
|
|
665
|
+
holderDataCapture[customFieldKey] = customFieldHolderKey
|
|
557
666
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
667
|
+
// Delete holder specific value from values list
|
|
668
|
+
delete checkoutBody.attributes[customFieldHolderName]
|
|
669
|
+
})
|
|
670
|
+
|
|
671
|
+
// Assign Ticket Holder data_capture final value
|
|
672
|
+
if (!_isEmpty(holderDataCapture)) {
|
|
673
|
+
holder.ticket_data_capture = holderDataCapture
|
|
674
|
+
}
|
|
675
|
+
})
|
|
676
|
+
|
|
677
|
+
// Collect add_on_data_capture for Add-on Custom Fields
|
|
678
|
+
const add_on_data_capture: Record<string, any> = {}
|
|
679
|
+
_forEach(values, (val: any, key: string) => {
|
|
680
|
+
// Matches keys like: `${addonId}-${groupId}-${fieldKey}` created in AddonComponent
|
|
681
|
+
const match = key.match(/^(\d+)-\d+-(.+)$/)
|
|
682
|
+
if (match) {
|
|
683
|
+
const addonId = match[1]
|
|
684
|
+
const fieldKey = match[2]
|
|
685
|
+
|
|
686
|
+
// Initialize addon bucket
|
|
687
|
+
if (!add_on_data_capture[addonId]) {
|
|
688
|
+
add_on_data_capture[addonId] = {}
|
|
689
|
+
}
|
|
561
690
|
|
|
562
|
-
|
|
563
|
-
const customFieldHolderName = `${customFieldKey}-${holderIndex}`
|
|
564
|
-
const customFieldHolderKey = values[customFieldHolderName] || ''
|
|
565
|
-
holderDataCapture[customFieldKey] = customFieldHolderKey
|
|
691
|
+
add_on_data_capture[addonId][fieldKey] = val
|
|
566
692
|
|
|
567
|
-
|
|
568
|
-
|
|
693
|
+
// Remove the raw form key from attributes to avoid leaking internals
|
|
694
|
+
delete checkoutBody.attributes[key]
|
|
695
|
+
}
|
|
569
696
|
})
|
|
570
697
|
|
|
571
|
-
//
|
|
572
|
-
if (
|
|
573
|
-
|
|
698
|
+
// Also include add_on_data_capture from localStorage for single-page checkout
|
|
699
|
+
if (isBrowser) {
|
|
700
|
+
const storedAddOnDataCapture = localStorage.getItem('add_on_data_capture')
|
|
701
|
+
if (storedAddOnDataCapture) {
|
|
702
|
+
const parsed = JSON.parse(storedAddOnDataCapture)
|
|
703
|
+
Object.keys(parsed).forEach(addonId => {
|
|
704
|
+
if (!add_on_data_capture[addonId]) {
|
|
705
|
+
add_on_data_capture[addonId] = {}
|
|
706
|
+
}
|
|
707
|
+
Object.keys(parsed[addonId]).forEach(fieldKey => {
|
|
708
|
+
add_on_data_capture[addonId][fieldKey] = parsed[addonId][fieldKey]
|
|
709
|
+
})
|
|
710
|
+
})
|
|
711
|
+
}
|
|
574
712
|
}
|
|
575
|
-
})
|
|
576
713
|
|
|
577
|
-
|
|
578
|
-
|
|
714
|
+
const mergedAttributes: Record<string, any> = {
|
|
715
|
+
...checkoutBody.attributes,
|
|
716
|
+
data_capture,
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
if (!_isEmpty(add_on_data_capture)) {
|
|
720
|
+
mergedAttributes.add_on_data_capture = add_on_data_capture
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
return { attributes: mergedAttributes }
|
|
724
|
+
},
|
|
725
|
+
[
|
|
726
|
+
showDOB,
|
|
727
|
+
showTicketHolders,
|
|
728
|
+
canSkipHolderNames,
|
|
729
|
+
customFieldsOrderKeys,
|
|
730
|
+
ticketsQuantity.length,
|
|
731
|
+
emailLogged,
|
|
732
|
+
firstNameLogged,
|
|
733
|
+
lastNameLogged,
|
|
734
|
+
customFieldsTicketHolderKeys,
|
|
735
|
+
]
|
|
736
|
+
)
|
|
579
737
|
|
|
580
|
-
const removeReferralKey = () => {
|
|
738
|
+
const removeReferralKey = useCallback(() => {
|
|
581
739
|
localStorage.removeItem('referral_key')
|
|
582
|
-
}
|
|
740
|
+
}, [])
|
|
741
|
+
|
|
742
|
+
const removeAdditionalConfigs = useCallback(() => {
|
|
743
|
+
localStorage.removeItem('checkoutAdditionalConfigs')
|
|
744
|
+
}, [])
|
|
745
|
+
|
|
746
|
+
useEffect(() => {
|
|
747
|
+
onCheckoutUpdateSuccess({ expires_at: expirationTime, ...checkoutData })
|
|
748
|
+
}, [checkoutData, cartInfoData])
|
|
749
|
+
|
|
750
|
+
// Initialize payment hooks
|
|
751
|
+
usePaymentRedirect({
|
|
752
|
+
stripeRef,
|
|
753
|
+
setError,
|
|
754
|
+
setLoading,
|
|
755
|
+
removeReferralKey,
|
|
756
|
+
removeAdditionalConfigs,
|
|
757
|
+
handleSubmit,
|
|
758
|
+
isBrowser,
|
|
759
|
+
})
|
|
760
|
+
|
|
761
|
+
const { processPayment } = useStripePayment({
|
|
762
|
+
stripeRef,
|
|
763
|
+
elementsRef,
|
|
764
|
+
setError,
|
|
765
|
+
isBrowser,
|
|
766
|
+
})
|
|
767
|
+
|
|
768
|
+
const updateCheckoutWithAddOns = useCallback(
|
|
769
|
+
async (addOns: { [key: string]: number } = {}) => {
|
|
770
|
+
if (!isSinglePageCheckout) return
|
|
771
|
+
|
|
772
|
+
const mergedAddOns = { ...singleCheckoutAddons }
|
|
773
|
+
|
|
774
|
+
// Update existing entries and add new ones
|
|
775
|
+
Object.entries(addOns).forEach(([key, value]) => {
|
|
776
|
+
const amount = Number(value)
|
|
777
|
+
if (amount) {
|
|
778
|
+
mergedAddOns[key] = amount
|
|
779
|
+
} else {
|
|
780
|
+
delete mergedAddOns[key]
|
|
781
|
+
}
|
|
782
|
+
})
|
|
783
|
+
|
|
784
|
+
try {
|
|
785
|
+
const checkoutUpdateData = {
|
|
786
|
+
attributes: {
|
|
787
|
+
event_id: eventId,
|
|
788
|
+
add_ons: mergedAddOns,
|
|
789
|
+
is_from_resale: additionalConfigs?.resale,
|
|
790
|
+
},
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
const checkoutResponse = await updateCheckout(checkoutUpdateData)
|
|
794
|
+
|
|
795
|
+
if (checkoutResponse.success) {
|
|
796
|
+
const checkoutDataObj = _get(
|
|
797
|
+
checkoutResponse,
|
|
798
|
+
'data.attributes.cart_price_breakdown',
|
|
799
|
+
{}
|
|
800
|
+
)
|
|
801
|
+
setCheckoutData(checkoutDataObj)
|
|
802
|
+
setSingleCheckoutAddOns(mergedAddOns)
|
|
803
|
+
}
|
|
804
|
+
} catch (error) {
|
|
805
|
+
const errorMessage = _get(
|
|
806
|
+
error,
|
|
807
|
+
'response.data.message',
|
|
808
|
+
'Failed to update add-ons'
|
|
809
|
+
)
|
|
810
|
+
setError(errorMessage)
|
|
811
|
+
onCheckoutUpdateError(error as AxiosError)
|
|
812
|
+
}
|
|
813
|
+
},
|
|
814
|
+
[eventId, isSinglePageCheckout, onCheckoutUpdateError, onCheckoutUpdateSuccess]
|
|
815
|
+
)
|
|
816
|
+
console.log({ checkoutData })
|
|
817
|
+
|
|
818
|
+
const handleAddOnSelect = useCallback(
|
|
819
|
+
async (selectedAddOns: { [key: string]: number }) => {
|
|
820
|
+
await updateCheckoutWithAddOns(selectedAddOns)
|
|
821
|
+
},
|
|
822
|
+
[updateCheckoutWithAddOns]
|
|
823
|
+
)
|
|
824
|
+
|
|
825
|
+
const onAddOnSelect = useCallback(
|
|
826
|
+
(id: string, value: string, addon: any, fieldUpdates: Record<string, any> = {}) => {
|
|
827
|
+
const quantity = parseInt(value) || 0
|
|
828
|
+
const addonId = addon.id || id
|
|
829
|
+
|
|
830
|
+
// Get current add-ons and their custom fields
|
|
831
|
+
const currentAddOns = JSON.parse(localStorage.getItem('add_ons') || '{}')
|
|
832
|
+
const currentDataCapture = JSON.parse(
|
|
833
|
+
localStorage.getItem('add_on_data_capture') || '{}'
|
|
834
|
+
)
|
|
835
|
+
|
|
836
|
+
// Update quantities
|
|
837
|
+
const updatedAddOns = { ...currentAddOns }
|
|
838
|
+
updatedAddOns[addonId] = quantity
|
|
583
839
|
|
|
840
|
+
// Update custom fields if any
|
|
841
|
+
const updatedDataCapture = { ...currentDataCapture }
|
|
842
|
+
if (Object.keys(fieldUpdates).length > 0) {
|
|
843
|
+
updatedDataCapture[addonId] = {
|
|
844
|
+
...(updatedDataCapture[addonId] || {}),
|
|
845
|
+
...fieldUpdates,
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
if (quantity === 0 && updatedDataCapture[addonId]) {
|
|
850
|
+
delete updatedDataCapture[addonId]
|
|
851
|
+
}
|
|
852
|
+
// Save to localStorage
|
|
853
|
+
localStorage.setItem('add_ons', JSON.stringify(updatedAddOns))
|
|
854
|
+
localStorage.setItem('add_on_data_capture', JSON.stringify(updatedDataCapture))
|
|
855
|
+
|
|
856
|
+
// Call handleAddOnSelect with the updated addons object
|
|
857
|
+
handleAddOnSelect(updatedAddOns)
|
|
858
|
+
},
|
|
859
|
+
[handleAddOnSelect]
|
|
860
|
+
)
|
|
584
861
|
if (loading || (enableTimer && !expirationTime && isBrowser)) {
|
|
585
862
|
if (expirationTime === 0) {
|
|
586
863
|
// Redirect to homepage (countdown finished and browser reloaded case)
|
|
@@ -597,20 +874,38 @@ const BillingInfoContainer = React.memo(
|
|
|
597
874
|
if (isTable) {
|
|
598
875
|
dataWithUniqueIds[0].label = 'Get Your Tables'
|
|
599
876
|
}
|
|
877
|
+
|
|
878
|
+
const stripePublishableKey =
|
|
879
|
+
reviewData?.payment_method?.stripe_publishable_key ||
|
|
880
|
+
checkoutUpdateData?.additional_payment_information?.basic_config?.apiKey
|
|
881
|
+
const stripeAccountId =
|
|
882
|
+
reviewData?.payment_method?.stripe_connected_account ||
|
|
883
|
+
checkoutUpdateData?.additional_payment_information?.basic_config?.accountId
|
|
884
|
+
const addOnsIncludedOnInvitation =
|
|
885
|
+
additionalConfigs.resale && additionalConfigs.resaleWithAddons
|
|
886
|
+
|
|
887
|
+
const elementsOptions: StripeElementsOptions = {
|
|
888
|
+
...checkoutUpdateData?.additional_payment_information?.elements_config,
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
if (loading || cardLoading || isCountriesLoading || isConfigLoading || !eventId) {
|
|
892
|
+
return (
|
|
893
|
+
<Backdrop
|
|
894
|
+
sx={{ color: '#fff', backgroundColor: '#000000bd', zIndex: 1205 }}
|
|
895
|
+
open={true}
|
|
896
|
+
>
|
|
897
|
+
<CircularProgress color="inherit" />
|
|
898
|
+
</Backdrop>
|
|
899
|
+
)
|
|
900
|
+
}
|
|
901
|
+
|
|
600
902
|
return (
|
|
601
903
|
<ThemeProvider theme={themeMui}>
|
|
602
|
-
{(loading || cardLoading || isCountriesLoading || isConfigLoading) && (
|
|
603
|
-
<Backdrop
|
|
604
|
-
sx={{ color: '#fff', backgroundColor: '#000000bd', zIndex: 1205 }}
|
|
605
|
-
open={true}
|
|
606
|
-
>
|
|
607
|
-
<CircularProgress color="inherit" />
|
|
608
|
-
</Backdrop>
|
|
609
|
-
)}
|
|
610
904
|
{!!expirationTime && enableTimer && (
|
|
611
905
|
<TimerWidget
|
|
612
906
|
expires_at={expirationTime}
|
|
613
907
|
onCountdownFinish={onCountdownFinish}
|
|
908
|
+
container={isSinglePageCheckout ? 'body' : ''}
|
|
614
909
|
/>
|
|
615
910
|
)}
|
|
616
911
|
{!isCountriesLoading && !isConfigLoading && (
|
|
@@ -619,8 +914,9 @@ const BillingInfoContainer = React.memo(
|
|
|
619
914
|
dataWithUniqueIds,
|
|
620
915
|
{
|
|
621
916
|
country: initialCountry,
|
|
622
|
-
state:
|
|
623
|
-
|
|
917
|
+
state:
|
|
918
|
+
_get(userData, 'stateId', '') || _get(userData, 'state', '') || '1',
|
|
919
|
+
brand_opt_in: Boolean(optedInFieldValue),
|
|
624
920
|
ttf_opt_in: ttfOptIn,
|
|
625
921
|
data_capture: {
|
|
626
922
|
instagram: _get(extraData, 'data_capture.instagram', ''),
|
|
@@ -637,6 +933,16 @@ const BillingInfoContainer = React.memo(
|
|
|
637
933
|
enableReinitialize={false}
|
|
638
934
|
onSubmit={async (values, formikHelpers) => {
|
|
639
935
|
try {
|
|
936
|
+
if ((!elementsRef.current || !stripeRef.current) && !orderIsFree) {
|
|
937
|
+
setError('Fill in the payment details')
|
|
938
|
+
return
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
if (isSinglePageCheckout && !orderIsFree) {
|
|
942
|
+
// For PaymentElement, we'll use confirmPayment directly
|
|
943
|
+
// No need to create payment method separately
|
|
944
|
+
}
|
|
945
|
+
|
|
640
946
|
if (isBrowser) {
|
|
641
947
|
window.localStorage.setItem(
|
|
642
948
|
'extraData',
|
|
@@ -654,124 +960,213 @@ const BillingInfoContainer = React.memo(
|
|
|
654
960
|
})
|
|
655
961
|
)
|
|
656
962
|
}
|
|
657
|
-
if (isLoggedIn) {
|
|
658
|
-
const checkoutBody = collectCheckoutBody(values, userData)
|
|
659
|
-
|
|
660
|
-
if (isBrowser) {
|
|
661
|
-
addAddOnsInAttributes(checkoutBody)
|
|
662
|
-
}
|
|
663
963
|
|
|
664
|
-
|
|
665
|
-
|
|
964
|
+
if (!isLoggedIn) {
|
|
965
|
+
const checkoutBodyForRegistration = createCheckoutDataBody(
|
|
966
|
+
ticketsQuantity.length,
|
|
967
|
+
values,
|
|
968
|
+
{ emailLogged, firstNameLogged, lastNameLogged },
|
|
969
|
+
showDOB
|
|
970
|
+
)
|
|
971
|
+
const bodyFormData = createRegisterFormData(
|
|
972
|
+
values,
|
|
973
|
+
checkoutBodyForRegistration,
|
|
666
974
|
flagFreeTicket
|
|
667
975
|
)
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
const
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
'user_data',
|
|
676
|
-
JSON.stringify(profileDataObj)
|
|
976
|
+
try {
|
|
977
|
+
setLoading(true)
|
|
978
|
+
const resRegister = await register(bodyFormData)
|
|
979
|
+
const xtfCookie = _get(resRegister, 'headers.x-tf-ecommerce')
|
|
980
|
+
const refreshToken = _get(
|
|
981
|
+
resRegister,
|
|
982
|
+
'data.attributes.refresh_token'
|
|
677
983
|
)
|
|
678
|
-
|
|
984
|
+
const userProfile = _get(resRegister, 'data.attributes.user_profile')
|
|
679
985
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
values,
|
|
696
|
-
checkoutBodyForRegistration,
|
|
697
|
-
flagFreeTicket
|
|
698
|
-
)
|
|
699
|
-
try {
|
|
700
|
-
setLoading(true)
|
|
701
|
-
const resRegister = await register(bodyFormData)
|
|
702
|
-
const xtfCookie = _get(resRegister, 'headers.x-tf-ecommerce')
|
|
703
|
-
const refreshToken = _get(resRegister, 'data.attributes.refresh_token')
|
|
704
|
-
const userProfile = _get(resRegister, 'data.attributes.user_profile')
|
|
705
|
-
|
|
706
|
-
setIsNewUser(true)
|
|
707
|
-
onRegisterSuccess({
|
|
708
|
-
xtfCookie,
|
|
709
|
-
refreshToken,
|
|
710
|
-
userProfile,
|
|
711
|
-
})
|
|
712
|
-
} catch (e) {
|
|
713
|
-
setLoading(false)
|
|
714
|
-
|
|
715
|
-
if (e.response?.data?.data?.hasUnverifiedOrder) {
|
|
716
|
-
setPendingVerificationMessage(e.response?.data?.message)
|
|
717
|
-
} else if (axios.isAxiosError(e)) {
|
|
718
|
-
const error = e?.response?.data?.message
|
|
719
|
-
if (_includes(error, 'You must be aged')) {
|
|
720
|
-
formikHelpers.setFieldError('holderAge', error)
|
|
721
|
-
}
|
|
722
|
-
if (error?.password) {
|
|
723
|
-
formikHelpers.setFieldError('password', error.password)
|
|
724
|
-
formikHelpers.setFieldError('confirmPassword', error.password)
|
|
725
|
-
}
|
|
726
|
-
if (error?.email && !onLogin) {
|
|
727
|
-
// False will stand for outside controll
|
|
728
|
-
setAlreadyHasUser(true)
|
|
729
|
-
setShowModalLogin(true)
|
|
730
|
-
}
|
|
986
|
+
setIsNewUser(true)
|
|
987
|
+
onRegisterSuccess({
|
|
988
|
+
xtfCookie,
|
|
989
|
+
refreshToken,
|
|
990
|
+
userProfile,
|
|
991
|
+
})
|
|
992
|
+
} catch (e) {
|
|
993
|
+
setLoading(false)
|
|
994
|
+
const hasUnverifiedOrder = _get(
|
|
995
|
+
e,
|
|
996
|
+
'response.data.data.hasUnverifiedOrder'
|
|
997
|
+
)
|
|
998
|
+
const message = _get(e, 'response.data.message', {}) as
|
|
999
|
+
| { password?: string | null, email?: string | null }
|
|
1000
|
+
| string
|
|
731
1001
|
|
|
732
|
-
if (
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
1002
|
+
if (hasUnverifiedOrder && typeof message === 'string') {
|
|
1003
|
+
setPendingVerificationMessage(message)
|
|
1004
|
+
} else if (axios.isAxiosError(e)) {
|
|
1005
|
+
if (
|
|
1006
|
+
_includes(message, 'You must be aged') &&
|
|
1007
|
+
typeof message === 'string'
|
|
1008
|
+
) {
|
|
1009
|
+
formikHelpers.setFieldError('holderAge', message)
|
|
1010
|
+
}
|
|
1011
|
+
if (typeof message !== 'string' && message?.password) {
|
|
1012
|
+
formikHelpers.setFieldError('password', message.password)
|
|
1013
|
+
formikHelpers.setFieldError('confirmPassword', message.password)
|
|
1014
|
+
}
|
|
1015
|
+
if (typeof message !== 'string' && message?.email && !onLogin) {
|
|
1016
|
+
// False will stand for outside controll
|
|
1017
|
+
setAlreadyHasUser(true)
|
|
1018
|
+
setShowModalLogin(true)
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if (
|
|
1022
|
+
_includes(error, 'The cart is expired') &&
|
|
1023
|
+
!hideErrorsAlertSection
|
|
1024
|
+
) {
|
|
1025
|
+
setError(error)
|
|
1026
|
+
}
|
|
738
1027
|
|
|
739
|
-
|
|
1028
|
+
onRegisterError(e, values.email)
|
|
1029
|
+
}
|
|
1030
|
+
return
|
|
740
1031
|
}
|
|
741
|
-
return
|
|
742
1032
|
}
|
|
1033
|
+
|
|
743
1034
|
const profileData = await getProfileData()
|
|
744
1035
|
const profileSpecifiedData = _get(profileData, 'data')
|
|
745
1036
|
const profileDataObj = setLoggedUserData(profileSpecifiedData)
|
|
1037
|
+
const userDataObj = isLoggedIn ? userData : profileDataObj
|
|
1038
|
+
|
|
746
1039
|
if (isBrowser) {
|
|
747
|
-
window.localStorage.setItem('user_data', JSON.stringify(
|
|
1040
|
+
window.localStorage.setItem('user_data', JSON.stringify(userDataObj))
|
|
748
1041
|
}
|
|
749
1042
|
|
|
750
|
-
const checkoutBody = collectCheckoutBody(values,
|
|
1043
|
+
const checkoutBody = collectCheckoutBody(values, userDataObj)
|
|
751
1044
|
|
|
752
|
-
if (isBrowser) {
|
|
1045
|
+
if (isBrowser && !isSinglePageCheckout) {
|
|
753
1046
|
addAddOnsInAttributes(checkoutBody)
|
|
754
1047
|
}
|
|
755
1048
|
|
|
1049
|
+
if (isSinglePageCheckout) {
|
|
1050
|
+
checkoutBody.attributes.add_ons = singleCheckoutAddons
|
|
1051
|
+
// Include add_on_data_capture for single-page checkout
|
|
1052
|
+
const storedAddOnDataCapture =
|
|
1053
|
+
localStorage.getItem('add_on_data_capture')
|
|
1054
|
+
if (storedAddOnDataCapture) {
|
|
1055
|
+
checkoutBody.attributes.add_on_data_capture =
|
|
1056
|
+
JSON.parse(storedAddOnDataCapture)
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
756
1060
|
const checkoutResponse = await postOnCheckout(
|
|
757
1061
|
checkoutBody,
|
|
758
1062
|
flagFreeTicket
|
|
759
1063
|
)
|
|
1064
|
+
|
|
1065
|
+
const checkoutUpdateResponse = await updateCheckout({
|
|
1066
|
+
attributes: {
|
|
1067
|
+
event_id: eventId,
|
|
1068
|
+
add_ons: checkoutBody?.attributes?.add_ons ?? [],
|
|
1069
|
+
is_from_resale: additionalConfigs?.resale,
|
|
1070
|
+
},
|
|
1071
|
+
})
|
|
1072
|
+
console.log(
|
|
1073
|
+
'Stripe checkoutUpdateResponse in billing-info-container',
|
|
1074
|
+
checkoutUpdateResponse
|
|
1075
|
+
)
|
|
1076
|
+
|
|
1077
|
+
setCheckoutUpdateData(checkoutUpdateResponse.data.attributes)
|
|
1078
|
+
|
|
1079
|
+
let paymentResponse = null
|
|
1080
|
+
|
|
1081
|
+
if (isSinglePageCheckout) {
|
|
1082
|
+
const { hash, total } = checkoutResponse.data.attributes
|
|
1083
|
+
localStorage.setItem('checkoutData', JSON.stringify({ hash, total }))
|
|
1084
|
+
|
|
1085
|
+
const paymentDataResponse = await getPaymentData(String(hash))
|
|
1086
|
+
|
|
1087
|
+
if (paymentDataResponse.success) {
|
|
1088
|
+
const { attributes } = paymentDataResponse.data
|
|
1089
|
+
console.log('Stripe confirmPayment success in billing-info-container')
|
|
1090
|
+
setReviewData(attributes)
|
|
1091
|
+
|
|
1092
|
+
const { order_details, cart } = attributes
|
|
1093
|
+
const {
|
|
1094
|
+
tickets: [ticket],
|
|
1095
|
+
} = order_details
|
|
1096
|
+
|
|
1097
|
+
const updatedOrderData = {
|
|
1098
|
+
add_ons: order_details.add_ons || [],
|
|
1099
|
+
total: order_details.total,
|
|
1100
|
+
subtotal: order_details.subtotal,
|
|
1101
|
+
fees: order_details.fees,
|
|
1102
|
+
pay_now: order_details.pay_now || '',
|
|
1103
|
+
|
|
1104
|
+
id: order_details?.id,
|
|
1105
|
+
product_name: cart[0]?.product_name,
|
|
1106
|
+
ticketType: ticket?.name,
|
|
1107
|
+
quantity: ticket?.quantity,
|
|
1108
|
+
price: ticket?.price,
|
|
1109
|
+
currency: order_details?.currency,
|
|
1110
|
+
guest_count: order_details?.guest_count || '',
|
|
1111
|
+
debt: order_details?.debt || null,
|
|
1112
|
+
cost: ticket?.cost,
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
const isFreeTickets =
|
|
1116
|
+
(!Number(total) && !Number(updatedOrderData.total)) ||
|
|
1117
|
+
!Number(updatedOrderData?.pay_now || 0)
|
|
1118
|
+
const paymentMethod = attributes.payment_method || {}
|
|
1119
|
+
const paymentPlanAvailable = paymentMethod.stripe_payment_plan_enabled
|
|
1120
|
+
console.log({ paymentPlanAvailable })
|
|
1121
|
+
// Process payment using the hook
|
|
1122
|
+
paymentResponse = await processPayment(
|
|
1123
|
+
paymentDataResponse,
|
|
1124
|
+
values,
|
|
1125
|
+
formikHelpers,
|
|
1126
|
+
checkoutResponse,
|
|
1127
|
+
checkoutUpdateResponse,
|
|
1128
|
+
{
|
|
1129
|
+
attributes,
|
|
1130
|
+
isFreeTickets,
|
|
1131
|
+
updatedOrderData,
|
|
1132
|
+
eventId,
|
|
1133
|
+
}
|
|
1134
|
+
)
|
|
1135
|
+
|
|
1136
|
+
if (!paymentResponse && !isFreeTickets) {
|
|
1137
|
+
// Payment failed or redirected, don't continue
|
|
1138
|
+
return
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
|
|
760
1143
|
removeReferralKey()
|
|
1144
|
+
removeAdditionalConfigs()
|
|
761
1145
|
handleSubmit(
|
|
762
1146
|
values,
|
|
763
1147
|
formikHelpers as FormikHelpers<any>,
|
|
764
1148
|
eventId,
|
|
765
|
-
checkoutResponse
|
|
1149
|
+
checkoutResponse,
|
|
1150
|
+
checkoutUpdateResponse,
|
|
1151
|
+
paymentResponse
|
|
766
1152
|
)
|
|
767
1153
|
} catch (e) {
|
|
768
1154
|
setLoading(false)
|
|
769
|
-
|
|
770
|
-
|
|
1155
|
+
onSubmitError(e as AxiosError)
|
|
1156
|
+
const hasUnverifiedOrder = _get(
|
|
1157
|
+
e,
|
|
1158
|
+
'response.data.data.hasUnverifiedOrder'
|
|
1159
|
+
)
|
|
1160
|
+
const message = _get(e, 'response.data.message', {}) as
|
|
1161
|
+
| { password?: string | null, email?: string | null }
|
|
1162
|
+
| string
|
|
1163
|
+
|
|
1164
|
+
if (hasUnverifiedOrder && typeof message === 'string') {
|
|
1165
|
+
setPendingVerificationMessage(message)
|
|
771
1166
|
} else if (axios.isAxiosError(e)) {
|
|
772
1167
|
if (
|
|
773
|
-
e.response?.status === 401 ||
|
|
774
|
-
e.
|
|
1168
|
+
(e as any).response?.status === 401 ||
|
|
1169
|
+
_get(e, 'response.data.error') === 'invalid_token'
|
|
775
1170
|
) {
|
|
776
1171
|
if (isBrowser) {
|
|
777
1172
|
window.localStorage.removeItem('user_data')
|
|
@@ -785,8 +1180,8 @@ const BillingInfoContainer = React.memo(
|
|
|
785
1180
|
window.document.dispatchEvent(event)
|
|
786
1181
|
}
|
|
787
1182
|
}
|
|
788
|
-
if (
|
|
789
|
-
setError(
|
|
1183
|
+
if (message && !hideErrorsAlertSection && typeof message === 'string') {
|
|
1184
|
+
setError(message)
|
|
790
1185
|
}
|
|
791
1186
|
onSubmitError(e)
|
|
792
1187
|
}
|
|
@@ -801,6 +1196,7 @@ const BillingInfoContainer = React.memo(
|
|
|
801
1196
|
<LogicRunner
|
|
802
1197
|
brandOptIn={brandOptIn}
|
|
803
1198
|
values={props.values}
|
|
1199
|
+
errors={props.errors}
|
|
804
1200
|
setStates={setStates}
|
|
805
1201
|
setFieldValue={props.setFieldValue}
|
|
806
1202
|
setValues={props.setValues}
|
|
@@ -810,16 +1206,18 @@ const BillingInfoContainer = React.memo(
|
|
|
810
1206
|
shouldFetchCountries={shouldFetchCountries}
|
|
811
1207
|
/>
|
|
812
1208
|
<div className={`billing-info-container ${theme}`}>
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
1209
|
+
{!!error && (
|
|
1210
|
+
<SnackbarAlert
|
|
1211
|
+
type="error"
|
|
1212
|
+
isOpen={!!error}
|
|
1213
|
+
message={error || ''}
|
|
1214
|
+
onClose={() => {
|
|
1215
|
+
setError(null)
|
|
1216
|
+
onErrorClose()
|
|
1217
|
+
}}
|
|
1218
|
+
/>
|
|
1219
|
+
)}
|
|
1220
|
+
{!isLoggedIn && !isSinglePageCheckout && (
|
|
823
1221
|
<div className="account-actions-block">
|
|
824
1222
|
<div className="action-item">
|
|
825
1223
|
<div>{accountInfoTitle}</div>
|
|
@@ -855,178 +1253,151 @@ const BillingInfoContainer = React.memo(
|
|
|
855
1253
|
</div>
|
|
856
1254
|
</div>
|
|
857
1255
|
)}
|
|
1256
|
+
{isSinglePageCheckout &&
|
|
1257
|
+
!addOnsIncludedOnInvitation &&
|
|
1258
|
+
eventHasAddons &&
|
|
1259
|
+
eventId ? (
|
|
1260
|
+
<SimpleAddonsContainer
|
|
1261
|
+
{...(addonsProps ?? {})}
|
|
1262
|
+
eventId={eventId}
|
|
1263
|
+
addOnDataWithCustomFields={addOnDataWithCustomFields}
|
|
1264
|
+
configs={configs}
|
|
1265
|
+
onAddOnSelect={onAddOnSelect}
|
|
1266
|
+
/>
|
|
1267
|
+
) : !addOnsIncludedOnInvitation &&
|
|
1268
|
+
includeAddons &&
|
|
1269
|
+
!isSinglePageCheckout ? (
|
|
1270
|
+
<AddonsContainter
|
|
1271
|
+
{...(addonsProps ?? {})}
|
|
1272
|
+
addOnDataWithCustomFields={addOnDataWithCustomFields}
|
|
1273
|
+
configs={configs}
|
|
1274
|
+
onAddOnSelect={onAddOnSelect}
|
|
1275
|
+
/>
|
|
1276
|
+
) : null}
|
|
858
1277
|
{!cardLoading &&
|
|
859
1278
|
_map(dataWithUniqueIds, item => {
|
|
860
1279
|
const { label, labelClassName, fields } = item
|
|
861
1280
|
return (
|
|
862
|
-
<
|
|
1281
|
+
<div key={item.uniqueId} className="billing-info-fields">
|
|
863
1282
|
<p className={labelClassName}>{label}</p>
|
|
864
1283
|
{_map(fields, group => {
|
|
865
1284
|
const { groupClassname, groupItems } = group
|
|
1285
|
+
const filteredGroupItems = filterBillingInfoFields(
|
|
1286
|
+
groupItems,
|
|
1287
|
+
{
|
|
1288
|
+
showDOB: Boolean(showDOB),
|
|
1289
|
+
hideTtfOptIn: Boolean(hideTtfOptIn),
|
|
1290
|
+
hidePhoneField: Boolean(hidePhoneField),
|
|
1291
|
+
flagRequirePhone: Boolean(flagRequirePhone),
|
|
1292
|
+
collectMandatoryWalletAddress: Boolean(
|
|
1293
|
+
collectMandatoryWalletAddress
|
|
1294
|
+
),
|
|
1295
|
+
collectMandatoryJobTitle: Boolean(
|
|
1296
|
+
collectMandatoryJobTitle
|
|
1297
|
+
),
|
|
1298
|
+
collectMandatoryBusinessCategory: Boolean(
|
|
1299
|
+
collectMandatoryBusinessCategory
|
|
1300
|
+
),
|
|
1301
|
+
collectMandatoryCompany: Boolean(collectMandatoryCompany),
|
|
1302
|
+
collectMandatoryInstagram: Boolean(
|
|
1303
|
+
collectMandatoryInstagram
|
|
1304
|
+
),
|
|
1305
|
+
flagFreeTicket: Boolean(flagFreeTicket),
|
|
1306
|
+
hideWalletAddressField: Boolean(hideWalletAddressField),
|
|
1307
|
+
hideJobTitleField: Boolean(hideJobTitleField),
|
|
1308
|
+
hideBusinessCategoryField: Boolean(
|
|
1309
|
+
hideBusinessCategoryField
|
|
1310
|
+
),
|
|
1311
|
+
hideCompanyField: Boolean(hideCompanyField),
|
|
1312
|
+
hideInstagramField,
|
|
1313
|
+
}
|
|
1314
|
+
)
|
|
866
1315
|
return (
|
|
867
1316
|
<React.Fragment key={group.uniqueId}>
|
|
868
1317
|
<div className={groupClassname}>
|
|
869
|
-
{_map(
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
if (el.name === 'data_capture[jobTitle]') {
|
|
890
|
-
if (collectMandatoryJobTitle) {
|
|
891
|
-
el.required = true
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
if (el.name === 'data_capture[businessCategory]') {
|
|
895
|
-
if (collectMandatoryBusinessCategory) {
|
|
896
|
-
el.required = true
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
if (el.name === 'data_capture[company]') {
|
|
900
|
-
if (collectMandatoryCompany) {
|
|
901
|
-
el.required = true
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
if (el.name === 'data_capture[instagram]') {
|
|
905
|
-
if (collectMandatoryInstagram) {
|
|
906
|
-
el.required = true
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
if (
|
|
910
|
-
[
|
|
911
|
-
'street_address',
|
|
912
|
-
'country',
|
|
913
|
-
'state',
|
|
914
|
-
'city',
|
|
915
|
-
].includes(el.name)
|
|
916
|
-
) {
|
|
917
|
-
if (flagFreeTicket) {
|
|
918
|
-
el.required = false
|
|
919
|
-
return false
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
if (
|
|
923
|
-
hideWalletAddressField &&
|
|
924
|
-
(el.name === 'wallet-address-info' ||
|
|
925
|
-
el.name === 'data_capture[wallet_address]')
|
|
926
|
-
) {
|
|
927
|
-
return false
|
|
928
|
-
}
|
|
929
|
-
if (
|
|
930
|
-
hideJobTitleField &&
|
|
931
|
-
el.name === 'data_capture[jobTitle]'
|
|
932
|
-
) {
|
|
933
|
-
return false
|
|
934
|
-
}
|
|
935
|
-
if (
|
|
936
|
-
hideBusinessCategoryField &&
|
|
937
|
-
el.name === 'data_capture[businessCategory]'
|
|
938
|
-
) {
|
|
939
|
-
return false
|
|
940
|
-
}
|
|
941
|
-
if (
|
|
942
|
-
hideCompanyField &&
|
|
943
|
-
el.name === 'data_capture[company]'
|
|
944
|
-
) {
|
|
945
|
-
return false
|
|
946
|
-
}
|
|
947
|
-
if (
|
|
948
|
-
hideInstagramField &&
|
|
949
|
-
(el.name === 'data_capture[instagram]' ||
|
|
950
|
-
el.name === 'instagram-info')
|
|
951
|
-
) {
|
|
952
|
-
return false
|
|
953
|
-
}
|
|
954
|
-
return true
|
|
955
|
-
}),
|
|
956
|
-
element =>
|
|
957
|
-
[
|
|
958
|
-
'password',
|
|
959
|
-
'confirmPassword',
|
|
960
|
-
'password-info',
|
|
961
|
-
].includes(element.name) && isLoggedIn ? null : (
|
|
962
|
-
<React.Fragment key={element.uniqueId}>
|
|
963
|
-
<div
|
|
964
|
-
className={`${element.className} ${
|
|
965
|
-
props?.errors[element.name] || ''
|
|
966
|
-
}`}
|
|
967
|
-
>
|
|
968
|
-
{element.component ? (
|
|
969
|
-
element.component
|
|
1318
|
+
{_map(filteredGroupItems, element =>
|
|
1319
|
+
[
|
|
1320
|
+
'password',
|
|
1321
|
+
'confirmPassword',
|
|
1322
|
+
'password-info',
|
|
1323
|
+
].includes(element.name) && isLoggedIn ? null : (
|
|
1324
|
+
<React.Fragment key={element.uniqueId}>
|
|
1325
|
+
<div
|
|
1326
|
+
className={`${element.className} ${
|
|
1327
|
+
props?.errors[element.name] || ''
|
|
1328
|
+
}`}
|
|
1329
|
+
>
|
|
1330
|
+
{element.component ? (
|
|
1331
|
+
typeof element.component === 'function' ? (
|
|
1332
|
+
renderComponentWithProps(
|
|
1333
|
+
element.component as React.ComponentType<any>,
|
|
1334
|
+
element.name === 'payment_info'
|
|
1335
|
+
? { reviewData }
|
|
1336
|
+
: {}
|
|
1337
|
+
)
|
|
970
1338
|
) : (
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
element.type
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1339
|
+
element.component
|
|
1340
|
+
)
|
|
1341
|
+
) : (
|
|
1342
|
+
<Field
|
|
1343
|
+
{...element}
|
|
1344
|
+
type={
|
|
1345
|
+
element.type === 'radio' ||
|
|
1346
|
+
element.type === 'checkbox'
|
|
1347
|
+
? undefined
|
|
1348
|
+
: element.type
|
|
1349
|
+
}
|
|
1350
|
+
setPhoneValidationIsLoading={
|
|
1351
|
+
element.type === 'phone'
|
|
1352
|
+
? setPhoneValidationIsLoading
|
|
1353
|
+
: undefined
|
|
1354
|
+
}
|
|
1355
|
+
label={getFieldLabel(element, configs)}
|
|
1356
|
+
validate={getValidateFunctions(
|
|
1357
|
+
element,
|
|
1358
|
+
states,
|
|
1359
|
+
props.values,
|
|
1360
|
+
props.errors
|
|
1361
|
+
)}
|
|
1362
|
+
setFieldValue={props.setFieldValue}
|
|
1363
|
+
onBlur={props.handleBlur}
|
|
1364
|
+
component={getFieldComponent(element)}
|
|
1365
|
+
selectOptions={
|
|
1366
|
+
element.name === 'country'
|
|
1367
|
+
? _map(countries, item => ({
|
|
997
1368
|
value: item.id,
|
|
998
1369
|
label: item.name,
|
|
999
1370
|
}))
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1371
|
+
: element.name === 'state'
|
|
1372
|
+
? [
|
|
1373
|
+
{
|
|
1374
|
+
label: element.label,
|
|
1375
|
+
value: '',
|
|
1376
|
+
disabled: true,
|
|
1377
|
+
},
|
|
1378
|
+
...states,
|
|
1379
|
+
]
|
|
1380
|
+
: element.selectOptions || []
|
|
1381
|
+
}
|
|
1382
|
+
theme={theme}
|
|
1383
|
+
defaultCountry={
|
|
1384
|
+
defaultCountry || element.defaultCountry
|
|
1385
|
+
}
|
|
1386
|
+
dateFormat={element.format}
|
|
1387
|
+
isCountryCodeEditable={
|
|
1388
|
+
isCountryCodeEditable
|
|
1389
|
+
}
|
|
1390
|
+
/>
|
|
1391
|
+
)}
|
|
1392
|
+
</div>
|
|
1393
|
+
</React.Fragment>
|
|
1394
|
+
)
|
|
1024
1395
|
)}
|
|
1025
1396
|
</div>
|
|
1026
1397
|
</React.Fragment>
|
|
1027
1398
|
)
|
|
1028
1399
|
})}
|
|
1029
|
-
</
|
|
1400
|
+
</div>
|
|
1030
1401
|
)
|
|
1031
1402
|
})}
|
|
1032
1403
|
{!_isEmpty(ticketHoldersFields.fields) && (
|
|
@@ -1046,7 +1417,7 @@ const BillingInfoContainer = React.memo(
|
|
|
1046
1417
|
{...element}
|
|
1047
1418
|
type={
|
|
1048
1419
|
element.type === 'radio' ||
|
|
1049
|
-
|
|
1420
|
+
element.type === 'checkbox'
|
|
1050
1421
|
? undefined
|
|
1051
1422
|
: element.type
|
|
1052
1423
|
}
|
|
@@ -1077,6 +1448,49 @@ const BillingInfoContainer = React.memo(
|
|
|
1077
1448
|
))}
|
|
1078
1449
|
</div>
|
|
1079
1450
|
)}
|
|
1451
|
+
<div className="payment-section">
|
|
1452
|
+
{isSinglePageCheckout && !orderIsFree && stripePublishableKey && (
|
|
1453
|
+
<PaymentContainer
|
|
1454
|
+
stripePublishableKey={stripePublishableKey}
|
|
1455
|
+
stripeAccountId={stripeAccountId}
|
|
1456
|
+
formTitle="Payment Information"
|
|
1457
|
+
orderInfoLabel=""
|
|
1458
|
+
enableTimer={false}
|
|
1459
|
+
checkoutData={checkoutData}
|
|
1460
|
+
elementsOptions={elementsOptions}
|
|
1461
|
+
paymentElementOptions={{
|
|
1462
|
+
wallets: {
|
|
1463
|
+
applePay:
|
|
1464
|
+
checkoutUpdateData?.additional_payment_information
|
|
1465
|
+
?.stripe_wallets?.applePay || 'never',
|
|
1466
|
+
googlePay:
|
|
1467
|
+
checkoutUpdateData?.additional_payment_information
|
|
1468
|
+
?.stripe_wallets?.googlePay || 'never',
|
|
1469
|
+
},
|
|
1470
|
+
}}
|
|
1471
|
+
onStripeReady={(stripe, elements) => {
|
|
1472
|
+
stripeRef.current = stripe
|
|
1473
|
+
elementsRef.current = elements
|
|
1474
|
+
}}
|
|
1475
|
+
paymentFields={paymentProps.paymentFields || []}
|
|
1476
|
+
onPaymentError={paymentProps.onPaymentError || _identity}
|
|
1477
|
+
handlePayment={paymentProps.handlePayment || _identity}
|
|
1478
|
+
onGetPaymentDataSuccess={
|
|
1479
|
+
paymentProps.onGetPaymentDataSuccess || _identity
|
|
1480
|
+
}
|
|
1481
|
+
onGetPaymentDataError={
|
|
1482
|
+
paymentProps.onGetPaymentDataError || _identity
|
|
1483
|
+
}
|
|
1484
|
+
themeOptions={themeOptions}
|
|
1485
|
+
paymentInfoLabel=""
|
|
1486
|
+
displayPaymentButton={false}
|
|
1487
|
+
hidePaymentForm={false}
|
|
1488
|
+
hideFieldsBlock={true}
|
|
1489
|
+
isSinglePageCheckout={true}
|
|
1490
|
+
/>
|
|
1491
|
+
)}
|
|
1492
|
+
{paymentSectionAddon}
|
|
1493
|
+
</div>
|
|
1080
1494
|
<div className="button-container">
|
|
1081
1495
|
<Button
|
|
1082
1496
|
type="submit"
|
|
@@ -1084,7 +1498,13 @@ const BillingInfoContainer = React.memo(
|
|
|
1084
1498
|
className="login-register-button"
|
|
1085
1499
|
disabled={props.isSubmitting || phoneValidationIsLoading}
|
|
1086
1500
|
>
|
|
1087
|
-
{props.isSubmitting ?
|
|
1501
|
+
{props.isSubmitting ? (
|
|
1502
|
+
<CircularProgress size={26} />
|
|
1503
|
+
) : orderIsFree ? (
|
|
1504
|
+
freeOrderButtonName
|
|
1505
|
+
) : (
|
|
1506
|
+
buttonName
|
|
1507
|
+
)}
|
|
1088
1508
|
</Button>
|
|
1089
1509
|
</div>
|
|
1090
1510
|
</div>
|
|
@@ -1149,6 +1569,7 @@ const BillingInfoContainer = React.memo(
|
|
|
1149
1569
|
onForgotPasswordSuccess={onForgotPasswordSuccess}
|
|
1150
1570
|
onForgotPasswordError={onForgotPasswordError}
|
|
1151
1571
|
showPoweredByImage={showPoweredByImage}
|
|
1572
|
+
displaySuccessMessage
|
|
1152
1573
|
/>
|
|
1153
1574
|
)}
|
|
1154
1575
|
<VerificationPendingModal
|