tf-checkout-react 1.2.16 → 1.2.19

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.
@@ -130,7 +130,7 @@ const LogicRunner: FC<{
130
130
  onGetStatesSuccess,
131
131
  onGetStatesError,
132
132
  shouldFetchCountries,
133
- brandOptIn
133
+ brandOptIn,
134
134
  }) => {
135
135
  const prevCountry = useRef(values.country)
136
136
  useEffect(() => {
@@ -176,7 +176,9 @@ const LogicRunner: FC<{
176
176
  street_address: parsedData?.street_address || '',
177
177
  country: parsedData?.country || '1',
178
178
  zip: parsedData?.zip || '',
179
- brand_opt_in: brandOptIn ? brandOptIn : (parsedData?.brand_opt_in || false),
179
+ brand_opt_in: brandOptIn
180
+ ? brandOptIn
181
+ : parsedData?.brand_opt_in || false,
180
182
  city: parsedData?.city || '',
181
183
  confirmPassword: '',
182
184
  password: '',
@@ -197,316 +199,417 @@ const LogicRunner: FC<{
197
199
  return null
198
200
  }
199
201
 
200
- export const BillingInfoContainer = ({
201
- data = [],
202
- ticketHoldersFields = {
203
- id: 1,
204
- fields: [],
205
- },
206
- initialValues = {},
207
- buttonName = 'Submit',
208
- handleSubmit = _identity,
209
- theme = 'light',
210
- onRegisterSuccess = () => {},
211
- onRegisterError = () => {},
212
- onSubmitError = () => {},
213
- onGetCartSuccess = () => {},
214
- onGetCartError = () => {},
215
- onGetCountriesSuccess = () => {},
216
- onGetCountriesError = () => {},
217
- onGetStatesSuccess = () => {},
218
- onGetStatesError = () => {},
219
- onGetProfileDataSuccess = () => {},
220
- onGetProfileDataError = () => {},
221
- onAuthorizeSuccess = () => {},
222
- onAuthorizeError = () => {},
223
- onLogin,
224
- onLoginSuccess = () => {},
225
- isLoggedIn: pIsLoggedIn = false,
226
- accountInfoTitle = '',
227
- hideLogo,
228
- themeOptions,
229
- onErrorClose = () => {},
230
- hideErrorsAlertSection = false,
231
- onSkipBillingPage = () => {},
232
- skipPage = false,
233
- canSkipHolderNames = false,
234
- onForgotPasswordSuccess = () => {},
235
- onForgotPasswordError = () => {},
236
- shouldFetchCountries = true,
237
- onCountdownFinish = () => {},
238
- enableTimer = false,
239
- logo,
240
- showForgotPasswordButton = false,
241
- showSignUpButton = false,
242
- brandOptIn = false,
243
- }: IBillingInfoPage) => {
244
- const themeMui = createTheme(themeOptions)
245
- const isWindowDefined = typeof window !== 'undefined'
246
- const userData =
247
- isWindowDefined && window.localStorage.getItem('user_data')
248
- ? JSON.parse(window.localStorage.getItem('user_data') || '')
249
- : {}
250
- const access_token =
251
- isWindowDefined && window.localStorage.getItem('access_token')
252
- ? window.localStorage.getItem('access_token') || ''
253
- : ''
254
- const [dataWithUniqueIds, setDataWithUniqueIds] = useState<
255
- IBillingInfoData[]
256
- >(data)
257
- const xtfCookie = getCookieByName('X-TF-ECOMMERCE')
258
- const [isLoggedIn, setIsLoggedIn] = useState(!!(pIsLoggedIn || xtfCookie))
259
- const [cartInfoData, setCartInfo] = useState<any>({})
260
- const [countries, setCountries] = useState<any>([])
261
- const [states, setStates] = useState<any>([])
262
- const [showModalLogin, setShowModalLogin] = useState(false)
263
- const [alreadyHasUser, setAlreadyHasUser] = useState(false)
264
- const [userExpired, setUserExpired] = useState(false)
265
- const [showModalSignup, setShowModalSignup] = useState(false)
266
- const [showModalForgotPassword, setShowModalForgotPassword] = useState(false)
267
- const [ticketsQuantity, setTicketsQuantity] = useState<string[]>([])
268
- const [userValues, setUserValues] = useState<any>({
269
- firstName: '',
270
- lastName: '',
271
- email: '',
272
- phone: '',
273
- confirmEmail: '',
274
- holderFirstName: '',
275
- holderLastName: '',
276
- holderAge: '',
277
- city: '',
278
- country: '',
279
- street_address: '',
280
- state: '',
281
- zip: '',
282
- })
283
- const [loading, setLoading] = useState(true)
284
- const [error, setError] = useState(null)
285
- const emailLogged =
286
- _get(userData, 'email', '') || _get(userValues, 'email', '')
287
- const firstNameLogged =
288
- _get(userData, 'first_name', '') || _get(userValues, 'first_name', '')
289
- const lastNameLogged =
290
- _get(userData, 'last_name', '') || _get(userValues, 'last_name', '')
291
- const showDOB = getQueryVariable('age_required') === 'true'
292
- const showTicketHolders = getQueryVariable('names_required') === 'true'
293
- const eventId = getQueryVariable('event_id')
294
- const optedInFieldValue: boolean = brandOptIn
295
- ? brandOptIn : _get(cartInfoData, 'optedIn', false)
296
- const ttfOptIn = Boolean(_get(cartInfoData, 'ttfOptIn', false))
297
- const hideTtfOptIn: boolean = _get(cartInfoData, 'hide_ttf_opt_in', true)
298
- const expirationTime = _get(cartInfoData, 'expiresAt')
299
- const flagRequirePhone = getQueryVariable('phone_required') === 'true'
202
+ export const BillingInfoContainer = React.memo(
203
+ ({
204
+ data = [],
205
+ ticketHoldersFields = {
206
+ id: 1,
207
+ fields: [],
208
+ },
209
+ initialValues = {},
210
+ buttonName = 'Submit',
211
+ handleSubmit = _identity,
212
+ theme = 'light',
213
+ onRegisterSuccess = _identity,
214
+ onRegisterError = _identity,
215
+ onSubmitError = _identity,
216
+ onGetCartSuccess = _identity,
217
+ onGetCartError = _identity,
218
+ onGetCountriesSuccess = _identity,
219
+ onGetCountriesError = _identity,
220
+ onGetStatesSuccess = _identity,
221
+ onGetStatesError = _identity,
222
+ onGetProfileDataSuccess = _identity,
223
+ onGetProfileDataError = _identity,
224
+ onAuthorizeSuccess = _identity,
225
+ onAuthorizeError = _identity,
226
+ onLogin,
227
+ onLoginSuccess = _identity,
228
+ isLoggedIn: pIsLoggedIn = false,
229
+ accountInfoTitle = '',
230
+ hideLogo,
231
+ themeOptions,
232
+ onErrorClose = _identity,
233
+ hideErrorsAlertSection = false,
234
+ onSkipBillingPage = _identity,
235
+ skipPage = false,
236
+ canSkipHolderNames = false,
237
+ onForgotPasswordSuccess = _identity,
238
+ onForgotPasswordError = _identity,
239
+ shouldFetchCountries = true,
240
+ onCountdownFinish = _identity,
241
+ enableTimer = false,
242
+ logo,
243
+ showForgotPasswordButton = false,
244
+ showSignUpButton = false,
245
+ brandOptIn = false,
246
+ }: IBillingInfoPage) => {
247
+ const themeMui = createTheme(themeOptions)
248
+ const isWindowDefined = typeof window !== 'undefined'
249
+ const userData =
250
+ isWindowDefined && window.localStorage.getItem('user_data')
251
+ ? JSON.parse(window.localStorage.getItem('user_data') || '')
252
+ : {}
253
+ const access_token =
254
+ isWindowDefined && window.localStorage.getItem('access_token')
255
+ ? window.localStorage.getItem('access_token') || ''
256
+ : ''
257
+ const [dataWithUniqueIds, setDataWithUniqueIds] = useState<
258
+ IBillingInfoData[]
259
+ >(data)
260
+ const xtfCookie = getCookieByName('X-TF-ECOMMERCE')
261
+ const [isLoggedIn, setIsLoggedIn] = useState(!!(pIsLoggedIn || xtfCookie))
262
+ const [cartInfoData, setCartInfo] = useState<any>({})
263
+ const [countries, setCountries] = useState<any>([])
264
+ const [states, setStates] = useState<any>([])
265
+ const [showModalLogin, setShowModalLogin] = useState(false)
266
+ const [alreadyHasUser, setAlreadyHasUser] = useState(false)
267
+ const [userExpired, setUserExpired] = useState(false)
268
+ const [showModalSignup, setShowModalSignup] = useState(false)
269
+ const [showModalForgotPassword, setShowModalForgotPassword] = useState(
270
+ false
271
+ )
272
+ const [ticketsQuantity, setTicketsQuantity] = useState<string[]>([])
273
+ const [userValues, setUserValues] = useState<any>({
274
+ firstName: '',
275
+ lastName: '',
276
+ email: '',
277
+ phone: '',
278
+ confirmEmail: '',
279
+ holderFirstName: '',
280
+ holderLastName: '',
281
+ holderAge: '',
282
+ city: '',
283
+ country: '',
284
+ street_address: '',
285
+ state: '',
286
+ zip: '',
287
+ })
288
+ const [loading, setLoading] = useState(true)
289
+ const [error, setError] = useState(null)
290
+ const [phoneValidationIsLoading, setPhoneValidationIsLoading] = useState(
291
+ false
292
+ )
293
+ const emailLogged =
294
+ _get(userData, 'email', '') || _get(userValues, 'email', '')
295
+ const firstNameLogged =
296
+ _get(userData, 'first_name', '') || _get(userValues, 'first_name', '')
297
+ const lastNameLogged =
298
+ _get(userData, 'last_name', '') || _get(userValues, 'last_name', '')
299
+ const showDOB = getQueryVariable('age_required') === 'true'
300
+ const showTicketHolders = getQueryVariable('names_required') === 'true'
301
+ const eventId = getQueryVariable('event_id')
302
+ const optedInFieldValue: boolean = brandOptIn
303
+ ? brandOptIn
304
+ : _get(cartInfoData, 'optedIn', false)
305
+ const ttfOptIn = Boolean(_get(cartInfoData, 'ttfOptIn', false))
306
+ const hideTtfOptIn: boolean = _get(cartInfoData, 'hide_ttf_opt_in', true)
307
+ const expirationTime = _get(cartInfoData, 'expiresAt')
308
+ const flagRequirePhone = getQueryVariable('phone_required') === 'true'
300
309
 
301
- // Get prevProps
302
- const prevData = useRef(data)
310
+ // Get prevProps
311
+ const prevData = useRef(data)
303
312
 
304
- useEffect(() => {
305
- const hasUniqueId = _get(dataWithUniqueIds, '[0].uniqueId')
306
- const isEqualData = _isEqual(prevData.current, data)
307
- if (!hasUniqueId || !isEqualData) {
308
- setDataWithUniqueIds(assingUniqueIds(data))
309
- if (!isEqualData) {
310
- prevData.current = data
313
+ useEffect(() => {
314
+ const hasUniqueId = _get(dataWithUniqueIds, '[0].uniqueId')
315
+ const isEqualData = _isEqual(prevData.current, data)
316
+ if (!hasUniqueId || !isEqualData) {
317
+ setDataWithUniqueIds(assingUniqueIds(data))
318
+ if (!isEqualData) {
319
+ prevData.current = data
320
+ }
311
321
  }
312
- }
313
- }, [dataWithUniqueIds, data])
322
+ }, [dataWithUniqueIds, data])
314
323
 
315
- const getQuantity = (cart: any = []) => {
316
- let qty: any = 0
317
- cart.forEach((item: any) => {
318
- qty += +item.quantity
319
- })
320
- return qty
321
- }
322
-
323
- useEffect(() => {
324
- if (pIsLoggedIn !== isLoggedIn || xtfCookie) {
325
- setIsLoggedIn(!!(pIsLoggedIn || xtfCookie))
324
+ const getQuantity = (cart: any = []) => {
325
+ let qty = 0
326
+ cart.forEach((item: any) => {
327
+ qty += +item.quantity
328
+ })
329
+ return qty
326
330
  }
327
- }, [pIsLoggedIn, isLoggedIn, xtfCookie])
328
- //just once
329
- useEffect(() => {
330
- // fetch countries data
331
- const fetchCountries = async () => {
331
+
332
+ useEffect(() => {
333
+ if (pIsLoggedIn !== isLoggedIn || xtfCookie) {
334
+ setIsLoggedIn(!!(pIsLoggedIn || xtfCookie))
335
+ }
336
+ }, [pIsLoggedIn, isLoggedIn, xtfCookie])
337
+ //just once
338
+ useEffect(() => {
339
+ // fetch countries data
340
+ const fetchCountries = async () => {
341
+ try {
342
+ const res = await getCountries()
343
+ setCustomHeader(res)
344
+ setCountries(
345
+ _map(_get(res, 'data.data'), (item, key) => ({
346
+ label: item,
347
+ value: key,
348
+ }))
349
+ )
350
+ onGetCountriesSuccess(res.data)
351
+ } catch (e) {
352
+ if (axios.isAxiosError(e)) {
353
+ onGetCountriesError(e)
354
+ }
355
+ }
356
+ }
357
+ shouldFetchCountries && fetchCountries()
358
+ fetchCart()
359
+ }, [])
360
+ // fetch cart data
361
+ const fetchCart = async () => {
332
362
  try {
333
- const res = await getCountries()
363
+ const res = await getCart()
334
364
  setCustomHeader(res)
335
- setCountries(
336
- _map(_get(res, 'data.data'), (item, key) => ({
337
- label: item,
338
- value: key,
339
- }))
365
+ const cartInfo = _get(res, 'data.data.attributes')
366
+ setCartInfo(cartInfo)
367
+ const { cart = [] } = cartInfo
368
+ setTicketsQuantity(
369
+ new Array(getQuantity(cart)).fill(null).map(() => nanoid())
340
370
  )
341
- onGetCountriesSuccess(res.data)
371
+ onGetCartSuccess(res.data)
342
372
  } catch (e) {
343
373
  if (axios.isAxiosError(e)) {
344
- onGetCountriesError(e)
374
+ onGetCartError(e)
345
375
  }
346
376
  }
347
377
  }
348
- shouldFetchCountries && fetchCountries()
349
- fetchCart()
350
- }, [])
351
- // fetch cart data
352
- const fetchCart = async () => {
353
- try {
354
- const res = await getCart()
355
- setCustomHeader(res)
356
- const cartInfo = _get(res, 'data.data.attributes')
357
- setCartInfo(cartInfo)
358
- const { cart = [] } = cartInfo
359
- setTicketsQuantity(
360
- new Array(getQuantity(cart)).fill(null).map(() => nanoid())
361
- )
362
- onGetCartSuccess(res.data)
363
- } catch (e) {
364
- if (axios.isAxiosError(e)) {
365
- onGetCartError(e)
366
- }
367
- }
368
- }
369
- // fetch user data
370
- const fetchUserData = async (token: string) => {
371
- try {
372
- if ((isWindowDefined && token) || isLoggedIn) {
373
- const userDataResponse = await getProfileData(token)
374
- const profileSpecifiedData = _get(userDataResponse, 'data.data')
375
- const profileDataObj = setLoggedUserData(profileSpecifiedData)
376
- setUserValues({
377
- ...profileDataObj,
378
- firstName: profileDataObj.first_name,
379
- lastName: profileDataObj.last_name,
380
- })
381
- window.localStorage.setItem('user_data', JSON.stringify(profileDataObj))
382
- onGetProfileDataSuccess(userDataResponse.data)
383
- }
384
- } catch (e) {
385
- if (axios.isAxiosError(e)) {
386
- onGetProfileDataError(e)
378
+ // fetch user data
379
+ const fetchUserData = async (token: string) => {
380
+ try {
381
+ if ((isWindowDefined && token) || isLoggedIn) {
382
+ const userDataResponse = await getProfileData(token)
383
+ const profileSpecifiedData = _get(userDataResponse, 'data.data')
384
+ const profileDataObj = setLoggedUserData(profileSpecifiedData)
385
+ setUserValues({
386
+ ...profileDataObj,
387
+ firstName: profileDataObj.first_name,
388
+ lastName: profileDataObj.last_name,
389
+ })
390
+ window.localStorage.setItem(
391
+ 'user_data',
392
+ JSON.stringify(profileDataObj)
393
+ )
394
+ onGetProfileDataSuccess(userDataResponse.data)
395
+ }
396
+ } catch (e) {
397
+ if (axios.isAxiosError(e)) {
398
+ onGetProfileDataError(e)
399
+ }
387
400
  }
388
401
  }
389
- }
390
- useEffect(() => {
391
- fetchUserData(access_token)
392
- }, [access_token, isLoggedIn])
402
+ useEffect(() => {
403
+ fetchUserData(access_token)
404
+ fetchCart()
405
+ }, [access_token, isLoggedIn])
393
406
 
394
- useEffect(() => {
395
- const collectPaymentData = async () => {
396
- if (skipPage && !_isEmpty(ticketsQuantity) && !showDOB) {
397
- setLoading(true)
398
- const checkoutBody = createCheckoutDataBodyWithDefaultHolder(
399
- ticketsQuantity.length,
400
- userData
401
- )
407
+ useEffect(() => {
408
+ const collectPaymentData = async () => {
409
+ if (skipPage && !_isEmpty(ticketsQuantity) && !showDOB) {
410
+ setLoading(true)
411
+ const checkoutBody = createCheckoutDataBodyWithDefaultHolder(
412
+ ticketsQuantity.length,
413
+ userData
414
+ )
402
415
 
403
- try {
404
- const res = await postOnCheckout(checkoutBody, access_token)
405
- removeReferralKey()
406
- onSkipBillingPage(_get(res, 'data.data.attributes'))
416
+ try {
417
+ const res = await postOnCheckout(checkoutBody, access_token)
418
+ removeReferralKey()
419
+ onSkipBillingPage(_get(res, 'data.data.attributes'))
420
+ setLoading(false)
421
+ } catch (e) {
422
+ onSubmitError(e)
423
+ }
424
+ } else {
407
425
  setLoading(false)
408
- } catch (e) {
409
- onSubmitError(e)
410
426
  }
411
- } else {
412
- setLoading(false)
413
427
  }
414
- }
415
- collectPaymentData()
416
- }, [skipPage, ticketsQuantity])
428
+ collectPaymentData()
429
+ }, [skipPage, ticketsQuantity])
417
430
 
418
- const collectCheckoutBody = (
419
- values: Record<string, unknown>,
420
- profileData?: any
421
- ): Record<string, unknown> => {
422
- let checkoutBody = {}
431
+ const collectCheckoutBody = (
432
+ values: Record<string, unknown>,
433
+ profileData?: any
434
+ ): Record<string, unknown> => {
435
+ let checkoutBody = {}
423
436
 
424
- // Auto collect ticket holders name when it was skipped optionally
425
- if (showDOB && !showTicketHolders && canSkipHolderNames) {
426
- checkoutBody = createCheckoutDataBodyWithDefaultHolder(
427
- ticketsQuantity.length,
428
- values,
429
- true,
430
- { emailLogged, firstNameLogged, lastNameLogged }
431
- )
432
- } else {
433
- checkoutBody = createCheckoutDataBody(
434
- ticketsQuantity.length,
435
- values,
436
- {
437
- emailLogged: emailLogged || profileData.email,
438
- firstNameLogged:
439
- firstNameLogged || profileData.first_name || profileData.firstName,
440
- lastNameLogged:
441
- lastNameLogged || profileData.last_name || profileData.lastName,
442
- },
443
- showDOB
444
- )
445
- }
437
+ // Auto collect ticket holders name when it was skipped optionally
438
+ if (showDOB && !showTicketHolders && canSkipHolderNames) {
439
+ checkoutBody = createCheckoutDataBodyWithDefaultHolder(
440
+ ticketsQuantity.length,
441
+ values,
442
+ true,
443
+ { emailLogged, firstNameLogged, lastNameLogged }
444
+ )
445
+ } else {
446
+ checkoutBody = createCheckoutDataBody(
447
+ ticketsQuantity.length,
448
+ values,
449
+ {
450
+ emailLogged: emailLogged || profileData.email,
451
+ firstNameLogged:
452
+ firstNameLogged ||
453
+ profileData.first_name ||
454
+ profileData.firstName,
455
+ lastNameLogged:
456
+ lastNameLogged || profileData.last_name || profileData.lastName,
457
+ },
458
+ showDOB
459
+ )
460
+ }
446
461
 
447
- return checkoutBody
448
- }
462
+ return checkoutBody
463
+ }
449
464
 
450
- const removeReferralKey = () => {
451
- localStorage.removeItem('referral_key')
452
- }
465
+ const removeReferralKey = () => {
466
+ localStorage.removeItem('referral_key')
467
+ }
453
468
 
454
- if (
455
- loading ||
456
- (enableTimer && !expirationTime && typeof window !== 'undefined')
457
- ) {
458
- if (expirationTime === 0) {
459
- // Redirect to homepage (countdown finished and browser reloaded case)
460
- window.location.href = '/'
469
+ if (
470
+ loading ||
471
+ (enableTimer && !expirationTime && typeof window !== 'undefined')
472
+ ) {
473
+ if (expirationTime === 0) {
474
+ // Redirect to homepage (countdown finished and browser reloaded case)
475
+ window.location.href = '/'
476
+ }
461
477
  }
462
- }
463
478
 
464
- return (
465
- <ThemeProvider theme={themeMui}>
466
- {loading && (
467
- <Backdrop
468
- sx={{ color: '#fff', backgroundColor: '#000000bd', zIndex: 1205 }}
469
- open={true}
470
- >
471
- <CircularProgress color="inherit" />
472
- </Backdrop>
473
- )}
474
- {!!expirationTime && enableTimer && (
475
- <TimerWidget
476
- expires_at={expirationTime}
477
- onCountdownFinish={onCountdownFinish}
478
- />
479
- )}
480
- <Formik
481
- initialValues={getInitialValues(
482
- dataWithUniqueIds,
483
- {
484
- ...initialValues,
485
- country: _get(userData, 'country', '') || '1',
486
- state: _get(userData, 'state', '') || '1',
487
- brand_opt_in: optedInFieldValue,
488
- ttf_opt_in: ttfOptIn,
489
- },
490
- userValues
479
+ return (
480
+ <ThemeProvider theme={themeMui}>
481
+ {loading && (
482
+ <Backdrop
483
+ sx={{ color: '#fff', backgroundColor: '#000000bd', zIndex: 1205 }}
484
+ open={true}
485
+ >
486
+ <CircularProgress color="inherit" />
487
+ </Backdrop>
491
488
  )}
492
- enableReinitialize={false}
493
- onSubmit={async (values, formikHelpers) => {
494
- try {
495
- if (isLoggedIn) {
496
- if (access_token) {
497
- const updatedUserData = await getProfileData(access_token)
498
- const profileSpecifiedData = _get(updatedUserData, 'data.data')
499
- const profileDataObj = setLoggedUserData(profileSpecifiedData)
500
- if (isWindowDefined) {
501
- window.localStorage.setItem(
502
- 'user_data',
503
- JSON.stringify(profileDataObj)
489
+ {!!expirationTime && enableTimer && (
490
+ <TimerWidget
491
+ expires_at={expirationTime}
492
+ onCountdownFinish={onCountdownFinish}
493
+ />
494
+ )}
495
+ <Formik
496
+ initialValues={getInitialValues(
497
+ dataWithUniqueIds,
498
+ {
499
+ ...initialValues,
500
+ country: _get(userData, 'country', '') || '1',
501
+ state: _get(userData, 'state', '') || '1',
502
+ brand_opt_in: optedInFieldValue,
503
+ ttf_opt_in: ttfOptIn,
504
+ },
505
+ userValues
506
+ )}
507
+ enableReinitialize={false}
508
+ onSubmit={async (values, formikHelpers) => {
509
+ try {
510
+ if (isLoggedIn) {
511
+ if (access_token) {
512
+ const updatedUserData = await getProfileData(access_token)
513
+ const profileSpecifiedData = _get(
514
+ updatedUserData,
515
+ 'data.data'
504
516
  )
517
+ const profileDataObj = setLoggedUserData(profileSpecifiedData)
518
+ if (isWindowDefined) {
519
+ window.localStorage.setItem(
520
+ 'user_data',
521
+ JSON.stringify(profileDataObj)
522
+ )
523
+ }
524
+ }
525
+
526
+ const checkoutBody = collectCheckoutBody(values, userData)
527
+ const res = await postOnCheckout(checkoutBody, access_token)
528
+ removeReferralKey()
529
+ handleSubmit(
530
+ values,
531
+ formikHelpers as FormikHelpers<any>,
532
+ eventId,
533
+ res
534
+ )
535
+ return
536
+ }
537
+ const checkoutBodyForRegistration = createCheckoutDataBody(
538
+ ticketsQuantity.length,
539
+ values,
540
+ { emailLogged, firstNameLogged, lastNameLogged },
541
+ showDOB
542
+ )
543
+ const bodyFormData = createRegisterFormData(
544
+ values,
545
+ checkoutBodyForRegistration
546
+ )
547
+ try {
548
+ setLoading(true)
549
+ const resRegister = await register(bodyFormData)
550
+ const xtfCookie = _get(resRegister, 'headers.x-tf-ecommerce')
551
+ const accessToken = _get(
552
+ resRegister,
553
+ 'data.data.attributes.access_token'
554
+ )
555
+ const refreshToken = _get(
556
+ resRegister,
557
+ 'data.data.attributes.refresh_token'
558
+ )
559
+ const userProfile = _get(
560
+ resRegister,
561
+ 'data.data.attributes.user_profile'
562
+ )
563
+
564
+ onRegisterSuccess({
565
+ xtfCookie,
566
+ accessToken,
567
+ refreshToken,
568
+ userProfile,
569
+ })
570
+ } catch (e) {
571
+ setLoading(false)
572
+ if (axios.isAxiosError(e)) {
573
+ const error = e?.response?.data?.message
574
+ if (_includes(error, 'You must be aged')) {
575
+ formikHelpers.setFieldError('holderAge', error)
576
+ }
577
+ if (error?.password) {
578
+ formikHelpers.setFieldError('password', error.password)
579
+ formikHelpers.setFieldError(
580
+ 'confirmPassword',
581
+ error.password
582
+ )
583
+ }
584
+ if (error?.email && !onLogin) {
585
+ // False will stand for outside controll
586
+ setAlreadyHasUser(true)
587
+ setShowModalLogin(true)
588
+ }
589
+
590
+ if (
591
+ _includes(error, 'The cart is expired') &&
592
+ !hideErrorsAlertSection
593
+ ) {
594
+ setError(error)
595
+ }
596
+
597
+ onRegisterError(e, values.email)
505
598
  }
599
+ return
600
+ }
601
+ const profileData = await getProfileData()
602
+ const profileSpecifiedData = _get(profileData, 'data.data')
603
+ const profileDataObj = setLoggedUserData(profileSpecifiedData)
604
+ if (isWindowDefined) {
605
+ window.localStorage.setItem(
606
+ 'user_data',
607
+ JSON.stringify(profileDataObj)
608
+ )
506
609
  }
507
610
 
508
- const checkoutBody = collectCheckoutBody(values, userData)
509
- const res = await postOnCheckout(checkoutBody, access_token)
611
+ const checkoutBody = collectCheckoutBody(values, profileDataObj)
612
+ const res = await postOnCheckout(checkoutBody)
510
613
  removeReferralKey()
511
614
  handleSubmit(
512
615
  values,
@@ -514,388 +617,313 @@ export const BillingInfoContainer = ({
514
617
  eventId,
515
618
  res
516
619
  )
517
- return
518
- }
519
- const checkoutBodyForRegistration = createCheckoutDataBody(
520
- ticketsQuantity.length,
521
- values,
522
- { emailLogged, firstNameLogged, lastNameLogged },
523
- showDOB
524
- )
525
- const bodyFormData = createRegisterFormData(
526
- values,
527
- checkoutBodyForRegistration
528
- )
529
- try {
530
- setLoading(true)
531
- const resRegister = await register(bodyFormData)
532
- const xtfCookie = _get(resRegister, 'headers.x-tf-ecommerce')
533
- const accessToken = _get(
534
- resRegister,
535
- 'data.data.attributes.access_token'
536
- )
537
- const refreshToken = _get(
538
- resRegister,
539
- 'data.data.attributes.refresh_token'
540
- )
541
- const userProfile = _get(
542
- resRegister,
543
- 'data.data.attributes.user_profile'
544
- )
545
-
546
- onRegisterSuccess({
547
- xtfCookie,
548
- accessToken,
549
- refreshToken,
550
- userProfile,
551
- })
552
620
  } catch (e) {
553
621
  setLoading(false)
554
622
  if (axios.isAxiosError(e)) {
555
- const error = e?.response?.data?.message
556
- if (_includes(error, 'You must be aged')) {
557
- formikHelpers.setFieldError('holderAge', error)
558
- }
559
- if (error?.password) {
560
- formikHelpers.setFieldError('password', error.password)
561
- formikHelpers.setFieldError('confirmPassword', error.password)
562
- }
563
- if (error?.email && !onLogin) {
564
- // False will stand for outside controll
565
- setAlreadyHasUser(true)
566
- setShowModalLogin(true)
567
- }
568
-
569
- if (
570
- _includes(error, 'The cart is expired') &&
571
- !hideErrorsAlertSection
572
- ) {
573
- setError(error)
623
+ if (e.response?.data.error === 'invalid_token') {
624
+ if (isWindowDefined) {
625
+ window.localStorage.removeItem('user_data')
626
+ window.localStorage.removeItem('access_token')
627
+ setUserExpired(true)
628
+ setShowModalLogin(true)
629
+ }
574
630
  }
575
-
576
- onRegisterError(e, values.email)
577
- }
578
- return
579
- }
580
- const profileData = await getProfileData()
581
- const profileSpecifiedData = _get(profileData, 'data.data')
582
- const profileDataObj = setLoggedUserData(profileSpecifiedData)
583
- if (isWindowDefined) {
584
- window.localStorage.setItem(
585
- 'user_data',
586
- JSON.stringify(profileDataObj)
587
- )
588
- }
589
-
590
- const checkoutBody = collectCheckoutBody(values, profileDataObj)
591
- const res = await postOnCheckout(checkoutBody)
592
- removeReferralKey()
593
- handleSubmit(
594
- values,
595
- formikHelpers as FormikHelpers<any>,
596
- eventId,
597
- res
598
- )
599
- } catch (e) {
600
- setLoading(false)
601
- if (axios.isAxiosError(e)) {
602
- if (e.response?.data.error === 'invalid_token') {
603
- if (isWindowDefined) {
604
- window.localStorage.removeItem('user_data')
605
- window.localStorage.removeItem('access_token')
606
- setUserExpired(true)
607
- setShowModalLogin(true)
631
+ if (e.response?.data.message && !hideErrorsAlertSection) {
632
+ setError(_get(e, 'response.data.message'))
608
633
  }
634
+ onSubmitError(e)
609
635
  }
610
- if (e.response?.data.message && !hideErrorsAlertSection) {
611
- setError(_get(e, 'response.data.message'))
612
- }
613
- onSubmitError(e)
636
+ } finally {
637
+ setLoading(false)
614
638
  }
615
- } finally {
616
- setLoading(false)
617
- }
618
- }}
619
- >
620
- {(props: FormikProps<any>) => (
621
- <Form onSubmit={props.handleSubmit}>
622
- <ErrorFocus />
623
- <LogicRunner
624
- brandOptIn={brandOptIn}
625
- values={props.values}
626
- setStates={setStates}
627
- setFieldValue={props.setFieldValue}
628
- setValues={props.setValues}
629
- setUserValues={setUserValues}
630
- onGetStatesSuccess={onGetStatesSuccess}
631
- onGetStatesError={onGetStatesError}
632
- shouldFetchCountries={shouldFetchCountries}
633
- />
634
- <div className={`billing-info-container ${theme}`}>
635
- <SnackbarAlert
636
- type="error"
637
- isOpen={!!error}
638
- message={error || ''}
639
- onClose={() => {
640
- setError(null)
641
- onErrorClose()
642
- }}
639
+ }}
640
+ >
641
+ {(props: FormikProps<any>) => (
642
+ <Form onSubmit={props.handleSubmit}>
643
+ <ErrorFocus />
644
+ <LogicRunner
645
+ brandOptIn={brandOptIn}
646
+ values={props.values}
647
+ setStates={setStates}
648
+ setFieldValue={props.setFieldValue}
649
+ setValues={props.setValues}
650
+ setUserValues={setUserValues}
651
+ onGetStatesSuccess={onGetStatesSuccess}
652
+ onGetStatesError={onGetStatesError}
653
+ shouldFetchCountries={shouldFetchCountries}
643
654
  />
644
- {!isLoggedIn && (
645
- <div className="account-actions-block">
646
- <div className="action-item">
647
- <div>{accountInfoTitle}</div>
648
- <div>Login & skip ahead:</div>
649
- </div>
650
- <div className="action-item login-block">
651
- <button
652
- className="login-register-button"
653
- type="button"
654
- onClick={() => {
655
- // If outside login needed to skip package login functionallity
656
- if (onLogin) {
657
- onLogin()
658
- } else {
659
- setShowModalLogin(true)
660
- }
661
- }}
662
- >
663
- Login
664
- </button>
665
- {!hideLogo && (
666
- <div className="logo-image-container">
667
- <img
668
- src={
669
- theme === 'dark'
670
- ? 'https://www.ticketfairy.com/resources/images/logo-ttf.svg'
671
- : 'https://www.ticketfairy.com/resources/images/logo-ttf-black.svg'
655
+ <div className={`billing-info-container ${theme}`}>
656
+ <SnackbarAlert
657
+ type="error"
658
+ isOpen={!!error}
659
+ message={error || ''}
660
+ onClose={() => {
661
+ setError(null)
662
+ onErrorClose()
663
+ }}
664
+ />
665
+ {!isLoggedIn && (
666
+ <div className="account-actions-block">
667
+ <div className="action-item">
668
+ <div>{accountInfoTitle}</div>
669
+ <div>Login & skip ahead:</div>
670
+ </div>
671
+ <div className="action-item login-block">
672
+ <button
673
+ className="login-register-button"
674
+ type="button"
675
+ onClick={() => {
676
+ // If outside login needed to skip package login functionallity
677
+ if (onLogin) {
678
+ onLogin()
679
+ } else {
680
+ setShowModalLogin(true)
672
681
  }
673
- alt="nodata"
674
- />
675
- </div>
676
- )}
682
+ }}
683
+ >
684
+ Login
685
+ </button>
686
+ {!hideLogo && (
687
+ <div className="logo-image-container">
688
+ <img
689
+ src={
690
+ theme === 'dark'
691
+ ? 'https://www.ticketfairy.com/resources/images/logo-ttf.svg'
692
+ : 'https://www.ticketfairy.com/resources/images/logo-ttf-black.svg'
693
+ }
694
+ alt="nodata"
695
+ />
696
+ </div>
697
+ )}
698
+ </div>
677
699
  </div>
678
- </div>
679
- )}
680
- {_map(dataWithUniqueIds, item => {
681
- const { label, labelClassName, fields } = item
682
- return (
683
- <React.Fragment key={item.uniqueId}>
684
- <p className={labelClassName}>{label}</p>
685
- {_map(fields, group => {
686
- const { groupClassname, groupItems } = group
687
- return (
688
- <React.Fragment key={group.uniqueId}>
689
- <div className={groupClassname}>
690
- {_map(
691
- groupItems.filter(el => {
692
- if (el.name === 'holderAge' && !showDOB) {
693
- return false
694
- }
695
- if (el.name === 'ttf_opt_in' && hideTtfOptIn) {
696
- return false
697
- }
698
- if (el.name === 'phone') {
699
- el.required = flagRequirePhone
700
- }
701
- return true
702
- }),
703
- element =>
704
- [
705
- 'password',
706
- 'confirmPassword',
707
- 'password-info',
708
- ].includes(element.name) &&
709
- isLoggedIn ? null : (
710
- <React.Fragment key={element.uniqueId}>
711
- <div className={element.className}>
712
- {element.component ? (
713
- element.component
714
- ) : (
715
- <Field
716
- name={element.name}
717
- label={
718
- element.name === 'phone'
719
- ? `${element.label}${
720
- flagRequirePhone
721
- ? ''
722
- : ' (optional)'
723
- } `
724
- : element.label
725
- }
726
- type={element.type}
727
- fill={element.fill}
728
- validate={getValidateFunctions(
729
- element,
730
- states,
731
- props.values
732
- )}
733
- setFieldValue={props.setFieldValue}
734
- onBlur={props.handleBlur}
735
- component={
736
- element.type === 'checkbox'
737
- ? CheckboxField
738
- : element.type === 'select'
739
- ? SelectField
740
- : element.type === 'phone'
741
- ? PhoneNumberField
742
- : element.type === 'date'
743
- ? DatePickerField
744
- : CustomField
745
- }
746
- selectOptions={
747
- element.name === 'country'
748
- ? countries
749
- : element.name === 'state'
750
- ? states
751
- : []
752
- }
753
- theme={theme}
754
- disableDropdown={
755
- element.disableDropdown
756
- }
757
- />
758
- )}
759
- </div>
760
- </React.Fragment>
761
- )
762
- )}
763
- </div>
764
- </React.Fragment>
765
- )
766
- })}
767
- </React.Fragment>
768
- )
769
- })}
770
- {!_isEmpty(ticketHoldersFields.fields) && (
771
- <div className="ticket-holders-fields">
772
- <h2>{ticketHoldersFields.label}</h2>
773
- {_map(ticketsQuantity, (_item, index) => (
774
- <div key={_item}>
775
- <h5>Ticket {index + 1}</h5>
776
- {_map(ticketHoldersFields.fields, group => {
700
+ )}
701
+ {_map(dataWithUniqueIds, item => {
702
+ const { label, labelClassName, fields } = item
703
+ return (
704
+ <React.Fragment key={item.uniqueId}>
705
+ <p className={labelClassName}>{label}</p>
706
+ {_map(fields, group => {
777
707
  const { groupClassname, groupItems } = group
778
708
  return (
779
- <div key={group.id}>
709
+ <React.Fragment key={group.uniqueId}>
780
710
  <div className={groupClassname}>
781
- {_map(groupItems, element => (
782
- <div
783
- className={element.className}
784
- key={element.name}
785
- >
786
- <Field
787
- name={`${element.name}-${index}`}
788
- label={element.label}
789
- type={element.type}
790
- component={
791
- element.type === 'checkbox'
792
- ? CheckboxField
793
- : element.type === 'phone'
794
- ? PhoneNumberField
795
- : CustomField
796
- }
797
- validate={combineValidators(
798
- element.required
799
- ? requiredValidator
800
- : () =>
801
- props.errors[
802
- `${element.name}-${index}`
803
- ],
804
- element.onValidate
805
- ? element.onValidate
806
- : () =>
807
- props.errors[
808
- `${element.name}-${index}`
809
- ]
810
- )}
811
- disableDropdown={element.disableDropdown}
812
- />
813
- </div>
814
- ))}
711
+ {_map(
712
+ groupItems.filter(el => {
713
+ if (el.name === 'holderAge' && !showDOB) {
714
+ return false
715
+ }
716
+ if (
717
+ el.name === 'ttf_opt_in' &&
718
+ hideTtfOptIn
719
+ ) {
720
+ return false
721
+ }
722
+ if (el.name === 'phone') {
723
+ el.required = flagRequirePhone
724
+ }
725
+ return true
726
+ }),
727
+ element =>
728
+ [
729
+ 'password',
730
+ 'confirmPassword',
731
+ 'password-info',
732
+ ].includes(element.name) &&
733
+ isLoggedIn ? null : (
734
+ <React.Fragment key={element.uniqueId}>
735
+ <div className={element.className}>
736
+ {element.component ? (
737
+ element.component
738
+ ) : (
739
+ <Field
740
+ name={element.name}
741
+ label={
742
+ element.name === 'phone'
743
+ ? `${element.label}${
744
+ flagRequirePhone
745
+ ? ''
746
+ : ' (optional)'
747
+ } `
748
+ : element.label
749
+ }
750
+ type={element.type}
751
+ fill={element.fill}
752
+ validate={getValidateFunctions(
753
+ element,
754
+ states,
755
+ props.values
756
+ )}
757
+ setFieldValue={props.setFieldValue}
758
+ onBlur={props.handleBlur}
759
+ component={
760
+ element.type === 'checkbox'
761
+ ? CheckboxField
762
+ : element.type === 'select'
763
+ ? SelectField
764
+ : element.type === 'phone'
765
+ ? PhoneNumberField
766
+ : element.type === 'date'
767
+ ? DatePickerField
768
+ : CustomField
769
+ }
770
+ selectOptions={
771
+ element.name === 'country'
772
+ ? countries
773
+ : element.name === 'state'
774
+ ? states
775
+ : []
776
+ }
777
+ theme={theme}
778
+ disableDropdown={
779
+ element.disableDropdown
780
+ }
781
+ />
782
+ )}
783
+ </div>
784
+ </React.Fragment>
785
+ )
786
+ )}
815
787
  </div>
816
- </div>
788
+ </React.Fragment>
817
789
  )
818
790
  })}
819
- </div>
820
- ))}
791
+ </React.Fragment>
792
+ )
793
+ })}
794
+ {!_isEmpty(ticketHoldersFields.fields) && (
795
+ <div className="ticket-holders-fields">
796
+ <h2>{ticketHoldersFields.label}</h2>
797
+ {_map(ticketsQuantity, (_item, index) => (
798
+ <div key={_item}>
799
+ <h5>Ticket {index + 1}</h5>
800
+ {_map(ticketHoldersFields.fields, group => {
801
+ const { groupClassname, groupItems } = group
802
+ return (
803
+ <div key={group.id}>
804
+ <div className={groupClassname}>
805
+ {_map(groupItems, element => (
806
+ <div
807
+ className={element.className}
808
+ key={element.name}
809
+ >
810
+ <Field
811
+ name={`${element.name}-${index}`}
812
+ label={element.label}
813
+ type={element.type}
814
+ component={
815
+ element.type === 'checkbox'
816
+ ? CheckboxField
817
+ : element.type === 'phone'
818
+ ? PhoneNumberField
819
+ : CustomField
820
+ }
821
+ validate={combineValidators(
822
+ element.required
823
+ ? requiredValidator
824
+ : () =>
825
+ props.errors[
826
+ `${element.name}-${index}`
827
+ ],
828
+ element.onValidate
829
+ ? element.onValidate
830
+ : () =>
831
+ props.errors[
832
+ `${element.name}-${index}`
833
+ ]
834
+ )}
835
+ disableDropdown={element.disableDropdown}
836
+ setPhoneValidationIsLoading={
837
+ setPhoneValidationIsLoading
838
+ }
839
+ />
840
+ </div>
841
+ ))}
842
+ </div>
843
+ </div>
844
+ )
845
+ })}
846
+ </div>
847
+ ))}
848
+ </div>
849
+ )}
850
+ <div className="button-container">
851
+ <Button
852
+ type="submit"
853
+ variant="contained"
854
+ className="login-register-button"
855
+ disabled={props.isSubmitting || phoneValidationIsLoading}
856
+ >
857
+ {props.isSubmitting ? (
858
+ <CircularProgress size={26} />
859
+ ) : (
860
+ buttonName
861
+ )}
862
+ </Button>
821
863
  </div>
822
- )}
823
- <div className="button-container">
824
- <Button
825
- type="submit"
826
- variant="contained"
827
- className="login-register-button"
828
- disabled={props.isSubmitting}
829
- >
830
- {props.isSubmitting ? (
831
- <CircularProgress size={26} />
832
- ) : (
833
- buttonName
834
- )}
835
- </Button>
836
864
  </div>
837
- </div>
838
- </Form>
865
+ </Form>
866
+ )}
867
+ </Formik>
868
+ {showModalLogin && (
869
+ <LoginModal
870
+ logo={logo}
871
+ onClose={() => {
872
+ setShowModalLogin(false)
873
+ }}
874
+ onLogin={() => {
875
+ setShowModalLogin(false)
876
+ setUserExpired(false)
877
+ onLoginSuccess()
878
+ }}
879
+ alreadyHasUser={alreadyHasUser}
880
+ userExpired={userExpired}
881
+ onAuthorizeSuccess={onAuthorizeSuccess}
882
+ onAuthorizeError={onAuthorizeError}
883
+ onGetProfileDataSuccess={(data: any) => {
884
+ fetchCart()
885
+ onGetProfileDataSuccess(data)
886
+ }}
887
+ onGetProfileDataError={onGetProfileDataError}
888
+ showSignUpButton={showSignUpButton}
889
+ showForgotPasswordButton={showForgotPasswordButton}
890
+ onForgotPassword={() => {
891
+ setShowModalLogin(false)
892
+ setShowModalForgotPassword(true)
893
+ }}
894
+ onSignup={() => {
895
+ setShowModalLogin(false)
896
+ setShowModalSignup(true)
897
+ }}
898
+ />
839
899
  )}
840
- </Formik>
841
- {showModalLogin && (
842
- <LoginModal
843
- logo={logo}
844
- onClose={() => {
845
- setShowModalLogin(false)
846
- }}
847
- onLogin={() => {
848
- setShowModalLogin(false)
849
- setUserExpired(false)
850
- onLoginSuccess()
851
- }}
852
- alreadyHasUser={alreadyHasUser}
853
- userExpired={userExpired}
854
- onAuthorizeSuccess={onAuthorizeSuccess}
855
- onAuthorizeError={onAuthorizeError}
856
- onGetProfileDataSuccess={(data: any) => {
857
- fetchCart()
858
- onGetProfileDataSuccess(data)
859
- }}
860
- onGetProfileDataError={onGetProfileDataError}
861
- showSignUpButton={showSignUpButton}
862
- showForgotPasswordButton={showForgotPasswordButton}
863
- onForgotPassword={() => {
864
- setShowModalLogin(false)
865
- setShowModalForgotPassword(true)
866
- }}
867
- onSignup={() => {
868
- setShowModalLogin(false)
869
- setShowModalSignup(true)
870
- }}
871
- />
872
- )}
873
- {showModalSignup && (
874
- <SignupModal
875
- onClose={() => {
876
- setShowModalSignup(false)
877
- }}
878
- onLogin={() => {
879
- setShowModalSignup(false)
880
- setShowModalLogin(true)
881
- }}
882
- onRegisterSuccess={onRegisterSuccess}
883
- onRegisterError={onRegisterError}
884
- />
885
- )}
886
- {showModalForgotPassword && (
887
- <ForgotPasswordModal
888
- onClose={() => {
889
- setShowModalForgotPassword(false)
890
- }}
891
- onLogin={() => {
892
- setShowModalForgotPassword(false)
893
- setShowModalLogin(true)
894
- }}
895
- onForgotPasswordSuccess={onForgotPasswordSuccess}
896
- onForgotPasswordError={onForgotPasswordError}
897
- />
898
- )}
899
- </ThemeProvider>
900
- )
901
- }
900
+ {showModalSignup && (
901
+ <SignupModal
902
+ onClose={() => {
903
+ setShowModalSignup(false)
904
+ }}
905
+ onLogin={() => {
906
+ setShowModalSignup(false)
907
+ setShowModalLogin(true)
908
+ }}
909
+ onRegisterSuccess={onRegisterSuccess}
910
+ onRegisterError={onRegisterError}
911
+ />
912
+ )}
913
+ {showModalForgotPassword && (
914
+ <ForgotPasswordModal
915
+ onClose={() => {
916
+ setShowModalForgotPassword(false)
917
+ }}
918
+ onLogin={() => {
919
+ setShowModalForgotPassword(false)
920
+ setShowModalLogin(true)
921
+ }}
922
+ onForgotPasswordSuccess={onForgotPasswordSuccess}
923
+ onForgotPasswordError={onForgotPasswordError}
924
+ />
925
+ )}
926
+ </ThemeProvider>
927
+ )
928
+ }
929
+ )