tf-checkout-react 1.6.6-beta.3 → 1.6.6-beta.31

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.
Files changed (110) hide show
  1. package/README.md +61 -40
  2. package/dist/adapters/customFields.d.ts +1 -0
  3. package/dist/api/checkout.d.ts +1 -0
  4. package/dist/api/common.d.ts +1 -0
  5. package/dist/api/index.d.ts +1 -0
  6. package/dist/api/preRegistrationComplete.d.ts +1 -1
  7. package/dist/components/addonsContainer/AddonComponent.d.ts +5 -1
  8. package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +17 -0
  9. package/dist/components/addonsContainer/index.d.ts +5 -1
  10. package/dist/components/billing-info-container/index.d.ts +8 -1
  11. package/dist/components/billing-info-container/utils.d.ts +25 -1
  12. package/dist/components/common/DatePickerField.d.ts +7 -1
  13. package/dist/components/countdown/index.d.ts +1 -1
  14. package/dist/components/forgotPasswordModal/index.d.ts +2 -1
  15. package/dist/components/myTicketsContainer/index.d.ts +3 -2
  16. package/dist/components/orderDetailsContainer/index.d.ts +7 -1
  17. package/dist/components/paymentContainer/OrderDetails.d.ts +8 -0
  18. package/dist/components/paymentContainer/handlePayment.d.ts +15 -0
  19. package/dist/components/paymentContainer/index.d.ts +10 -5
  20. package/dist/components/preRegistration/FieldsSection.d.ts +7 -1
  21. package/dist/components/preRegistration/PreRegistrationComplete.d.ts +6 -0
  22. package/dist/components/preRegistration/constants.d.ts +2 -2
  23. package/dist/components/preRegistration/index.d.ts +6 -0
  24. package/dist/components/resetPasswordContainer/index.d.ts +2 -2
  25. package/dist/components/stripePayment/index.d.ts +18 -3
  26. package/dist/components/ticketsContainer/InfoIcon.d.ts +5 -0
  27. package/dist/components/ticketsContainer/TicketsSection.d.ts +3 -2
  28. package/dist/components/ticketsContainer/TimeSlotsSection.d.ts +25 -0
  29. package/dist/components/ticketsContainer/index.d.ts +18 -5
  30. package/dist/components/timerWidget/index.d.ts +2 -1
  31. package/dist/constants/index.d.ts +5 -0
  32. package/dist/index.d.ts +4 -1
  33. package/dist/tf-checkout-react.cjs.development.js +5196 -3599
  34. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  35. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  36. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  37. package/dist/tf-checkout-react.esm.js +5199 -3605
  38. package/dist/tf-checkout-react.esm.js.map +1 -1
  39. package/dist/tf-checkout-styles.css +1 -1
  40. package/dist/types/add_on.d.ts +1 -0
  41. package/dist/types/checkoutPageConfigs.d.ts +1 -1
  42. package/dist/types/order-data.d.ts +2 -1
  43. package/dist/utils/auth.d.ts +8 -0
  44. package/dist/utils/customFields.d.ts +11 -0
  45. package/dist/utils/getDomain.d.ts +1 -1
  46. package/dist/utils/index.d.ts +1 -1
  47. package/dist/utils/setConfigs.d.ts +1 -0
  48. package/package.json +3 -2
  49. package/src/adapters/customFields.ts +7 -1
  50. package/src/api/auth.ts +2 -1
  51. package/src/api/checkout.ts +8 -4
  52. package/src/api/common.ts +49 -2
  53. package/src/api/interceptors.ts +7 -23
  54. package/src/api/preRegistrationComplete.ts +1 -1
  55. package/src/api/publicRequest.ts +10 -0
  56. package/src/components/addonsContainer/AddonComponent.tsx +71 -11
  57. package/src/components/addonsContainer/SimpleAddonsContainer.tsx +388 -0
  58. package/src/components/addonsContainer/index.tsx +189 -58
  59. package/src/components/billing-info-container/index.tsx +704 -390
  60. package/src/components/billing-info-container/{utils.ts → utils.tsx} +119 -0
  61. package/src/components/common/CheckboxField/index.tsx +1 -1
  62. package/src/components/common/DatePickerField.tsx +25 -10
  63. package/src/components/common/SnackbarAlert.tsx +32 -34
  64. package/src/components/confirmationContainer/index.tsx +1 -1
  65. package/src/components/countdown/index.tsx +22 -22
  66. package/src/components/delegationsContainer/IssueComponent.tsx +2 -1
  67. package/src/components/forgotPasswordModal/index.tsx +44 -13
  68. package/src/components/loginForm/index.tsx +1 -1
  69. package/src/components/loginModal/index.tsx +2 -2
  70. package/src/components/loginModal/style.css +3 -1
  71. package/src/components/myTicketsContainer/index.tsx +13 -9
  72. package/src/components/orderDetailsContainer/index.tsx +188 -173
  73. package/src/components/paymentContainer/OrderDetails.tsx +170 -0
  74. package/src/components/paymentContainer/handlePayment.ts +86 -0
  75. package/src/components/paymentContainer/index.tsx +253 -226
  76. package/src/components/paymentContainer/style.css +113 -0
  77. package/src/components/preRegistration/FieldsSection.tsx +8 -0
  78. package/src/components/preRegistration/PreRegistrationComplete.tsx +128 -118
  79. package/src/components/preRegistration/PreRegistrationInformations.tsx +21 -15
  80. package/src/components/preRegistration/constants.tsx +10 -4
  81. package/src/components/preRegistration/index.tsx +194 -174
  82. package/src/components/registerForm/constants.tsx +3 -1
  83. package/src/components/registerForm/index.tsx +3 -3
  84. package/src/components/resetPasswordContainer/index.tsx +12 -13
  85. package/src/components/seatMapContainer/TicketsSection.tsx +2 -2
  86. package/src/components/stripePayment/index.tsx +129 -24
  87. package/src/components/ticketsContainer/InfoIcon.tsx +35 -0
  88. package/src/components/ticketsContainer/PromoCodeSection.tsx +34 -28
  89. package/src/components/ticketsContainer/TicketRow.tsx +1 -1
  90. package/src/components/ticketsContainer/TicketsSection.tsx +178 -52
  91. package/src/components/ticketsContainer/TimeSlotsSection.tsx +120 -0
  92. package/src/components/ticketsContainer/index.tsx +209 -99
  93. package/src/components/timerWidget/index.tsx +15 -3
  94. package/src/constants/index.ts +2 -0
  95. package/src/hoc/CustomFields/index.tsx +9 -1
  96. package/src/index.ts +7 -2
  97. package/src/types/add_on.ts +1 -0
  98. package/src/types/api/common.d.ts +27 -0
  99. package/src/types/api/orders.d.ts +19 -3
  100. package/src/types/api/payment.d.ts +5 -2
  101. package/src/types/api/preRegistrationComplete.d.ts +2 -2
  102. package/src/types/checkoutPageConfigs.ts +1 -1
  103. package/src/types/order-data.ts +2 -1
  104. package/src/types/pre-registration-complete.d.ts +6 -1
  105. package/src/utils/auth.ts +32 -0
  106. package/src/utils/cookies.ts +42 -11
  107. package/src/utils/customFields.ts +22 -0
  108. package/src/utils/getDomain.ts +10 -4
  109. package/src/utils/index.ts +1 -1
  110. package/src/utils/setConfigs.ts +3 -1
@@ -1,21 +1,27 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  /* eslint-disable react/no-unescaped-entities */
2
3
 
3
4
  import { CircularProgress } from '@mui/material'
4
5
  import { Form, Formik } from 'formik'
5
6
  import _get from 'lodash/get'
6
7
  import _identity from 'lodash/identity'
7
- import React, { useEffect, useState } from 'react'
8
+ import _map from 'lodash/map'
9
+ import React, { useEffect, useMemo, useState } from 'react'
10
+ import { Tooltip } from 'react-tooltip'
8
11
 
9
12
  import { getAddons, getCart, getCheckoutPageConfigs, postOnCheckout } from '../../api'
13
+ import { FEES_STYLES } from '../../constants'
10
14
  import { currencyNormalizerCreator } from '../../normalizers'
11
15
  import { ICheckoutPageConfigs } from '../../types'
12
16
  import {
17
+ CONFIGS,
13
18
  createCheckoutDataBodyWithDefaultHolder,
14
19
  createMarkup,
15
20
  getQueryVariable,
16
21
  isBrowser,
17
22
  } from '../../utils'
18
23
  import { VerificationPendingModal } from '../idVerificationContainer/VerificationPendingModal'
24
+ import InfoIcon from '../ticketsContainer/InfoIcon'
19
25
  import TimerWidget from '../timerWidget'
20
26
  import { addonsWithGroupsAdapter, cartAdapter } from './adapters'
21
27
  import AddonComponent from './AddonComponent'
@@ -41,6 +47,11 @@ export interface IAddonContainterProps {
41
47
  onCountdownFinish?: () => void;
42
48
  onPendingVerification?: () => void;
43
49
  samePage?: boolean;
50
+ descriptionTrigger?: 'click' | 'hover' | 'always';
51
+ addOnDataWithCustomFields: any;
52
+ configs: any;
53
+
54
+ onAddOnSelect?: (id: string, value: string, addon: any) => void;
44
55
  }
45
56
 
46
57
  export interface ObjectLiteral {
@@ -60,6 +71,10 @@ export const AddonsContainter = ({
60
71
  onCountdownFinish = _identity,
61
72
  onPendingVerification = _identity,
62
73
  samePage,
74
+ descriptionTrigger = 'click',
75
+ addOnDataWithCustomFields,
76
+ configs,
77
+ onAddOnSelect = _identity,
63
78
  }: IAddonContainterProps) => {
64
79
  const eventId = getQueryVariable('event_id')
65
80
  const [addons, setAddons] = useState<any>([])
@@ -71,6 +86,12 @@ export const AddonsContainter = ({
71
86
  const [cartExpirationTime, setCartExpirationTime] = useState(0)
72
87
  const [pendingVerificationMessage, setPendingVerificationMessage] = useState()
73
88
 
89
+ const [visibleDescription, setVisibleDescription] = useState<string | null>(null)
90
+
91
+ const handleDescriptionToggle = (ticketId: string) => {
92
+ setVisibleDescription(current => (current === ticketId ? null : ticketId))
93
+ }
94
+
74
95
  useEffect(() => {
75
96
  if (samePage) {
76
97
  window.localStorage.removeItem('add_ons')
@@ -227,8 +248,8 @@ export const AddonsContainter = ({
227
248
  total,
228
249
  })
229
250
  } catch (error) {
230
- if (error.response?.data?.data?.hasUnverifiedOrder) {
231
- setPendingVerificationMessage(error.response?.data?.message)
251
+ if ((error as any).response?.data?.data?.hasUnverifiedOrder) {
252
+ setPendingVerificationMessage((error as any).response?.data?.message)
232
253
  } else {
233
254
  onPostCheckoutError(error)
234
255
  onConfirmSelectionError(error)
@@ -260,6 +281,22 @@ export const AddonsContainter = ({
260
281
  window.localStorage.removeItem('add_ons')
261
282
  }
262
283
 
284
+ const initialValues = useMemo(() => {
285
+ const addOnsData: any = {}
286
+ if (addons?.length > 0 && addOnDataWithCustomFields?.fields?.length > 0) {
287
+ _map(addons, addon => {
288
+ _map(addOnDataWithCustomFields.fields, field => {
289
+ const { id, groupItems } = field
290
+ _map(groupItems, item => {
291
+ addOnsData[`${addon.id}-${id}-${item.name}`] = item.value
292
+ })
293
+ })
294
+ })
295
+ }
296
+
297
+ return addOnsData
298
+ }, [addons, addOnDataWithCustomFields])
299
+
263
300
  if (loading) {
264
301
  return (
265
302
  <div className={`${classNamePrefix}_loader`}>
@@ -268,9 +305,13 @@ export const AddonsContainter = ({
268
305
  )
269
306
  }
270
307
 
308
+ if (addons?.length === 0) {
309
+ return null
310
+ }
311
+
271
312
  const params = new URL(`${window.location}`).searchParams
272
- const addOnIsIncluded = params.get("include_add_on") === "true"
273
- const isResale = params.get("resale") === 'true'
313
+ const addOnIsIncluded = params.get('include_add_on') === 'true'
314
+ const isResale = params.get('resale') === 'true'
274
315
 
275
316
  return (
276
317
  <>
@@ -286,40 +327,46 @@ export const AddonsContainter = ({
286
327
  <div className={`${classNamePrefix}_container`}>
287
328
  <div className={`${classNamePrefix}_block`}>
288
329
  <div className={`${classNamePrefix}_line_block`}>
289
- {samePage ? null : <p className={`${classNamePrefix}_info_title`}>Get Your Tickets</p>}
290
- {(
291
- !addons?.length ||
292
- (isResale && addOnIsIncluded)
293
- ) && samePage ? null : <div className={`${classNamePrefix}_title`}>UPGRADES & ADD-ONS</div>}
294
- {samePage ? null : <button
295
- type="button"
296
- className={`${classNamePrefix}_skip`}
297
- onClick={() => {
298
- handleClearAddons()
299
- handleConfirm({}, true)
300
- }}
301
- >
302
- Skip
303
- </button>}
330
+ {samePage ? null : (
331
+ <p className={`${classNamePrefix}_info_title`}>Get Your Tickets</p>
332
+ )}
333
+ {(!addons?.length || (isResale && addOnIsIncluded)) && samePage ? null : (
334
+ <div className={`${classNamePrefix}_title`}>UPGRADES & ADD-ONS</div>
335
+ )}
336
+ {samePage ? null : (
337
+ <button
338
+ type="button"
339
+ className={`${classNamePrefix}_skip`}
340
+ onClick={() => {
341
+ handleClearAddons()
342
+ handleConfirm({}, true)
343
+ }}
344
+ >
345
+ Skip
346
+ </button>
347
+ )}
304
348
  </div>
305
- {(
306
- !addons?.length ||
307
- (isResale && addOnIsIncluded)
308
- ) && samePage ? null : <div className={`${classNamePrefix}_subtitle`}>
309
- PLEASE SELECT FROM THE OPTIONAL ADD-ONS BELOW
310
- </div>}
349
+ {(!addons?.length || (isResale && addOnIsIncluded)) && samePage ? null : (
350
+ <div className={`${classNamePrefix}_subtitle`}>
351
+ PLEASE SELECT FROM THE OPTIONAL ADD-ONS BELOW
352
+ </div>
353
+ )}
311
354
  <Formik
312
- initialValues={{}}
355
+ initialValues={initialValues}
313
356
  onSubmit={values => {
314
357
  handleConfirm(values)
315
358
  }}
316
- validate={samePage ? values => {
317
- if (isBrowser) {
318
- window.localStorage.setItem('add_ons', JSON.stringify(values))
319
- }
320
- } : undefined}
359
+ validate={
360
+ samePage
361
+ ? values => {
362
+ if (isBrowser) {
363
+ window.localStorage.setItem('add_ons', JSON.stringify(values))
364
+ }
365
+ }
366
+ : undefined
367
+ }
321
368
  >
322
- {({ values }) => {
369
+ {({ values, errors, setFieldTouched }) => {
323
370
  const isConfirmDisabled = !isAtLeastOneAddonSelected(values)
324
371
 
325
372
  return (
@@ -327,14 +374,25 @@ export const AddonsContainter = ({
327
374
  <>
328
375
  {(isResale && addOnIsIncluded ? [] : addons).map((addon: any) => {
329
376
  const price = addon.feeIncluded ? addon.price : addon.cost
330
- const isAddonFree = Number(price) === 0
377
+ const isAddonFree = Number(addon?.price) === 0
378
+
379
+ const addOnNormalizedCost = isAddonFree
380
+ ? 'FREE'
381
+ : currencyNormalizerCreator(
382
+ getNormalizedPrice(addon?.cost ?? 0),
383
+ addon.currency
384
+ )
331
385
 
332
386
  const addonNormalizedPrice = isAddonFree
333
387
  ? 'FREE'
334
388
  : currencyNormalizerCreator(
335
- getNormalizedPrice(price),
336
- addon.currency
337
- )
389
+ getNormalizedPrice(
390
+ CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH
391
+ ? addon?.price ?? price
392
+ : price
393
+ ),
394
+ addon.currency
395
+ )
338
396
 
339
397
  return (
340
398
  <div
@@ -351,20 +409,69 @@ export const AddonsContainter = ({
351
409
  <div className={`${classNamePrefix}_product_info_block`}>
352
410
  <div className={`${classNamePrefix}_product_title`}>
353
411
  {addon.name}
412
+ {addon.description && descriptionTrigger !== 'always' && (
413
+ <>
414
+ <span
415
+ aria-hidden
416
+ className="info-icon"
417
+ onClick={
418
+ descriptionTrigger === 'click'
419
+ ? () => handleDescriptionToggle(addon.id)
420
+ : undefined
421
+ }
422
+ onMouseEnter={
423
+ descriptionTrigger === 'hover'
424
+ ? () => setVisibleDescription(addon.id)
425
+ : undefined
426
+ }
427
+ onMouseLeave={
428
+ descriptionTrigger === 'hover'
429
+ ? () => setVisibleDescription(null)
430
+ : undefined
431
+ }
432
+ style={{
433
+ marginLeft: 8,
434
+ cursor: 'pointer',
435
+ display: 'flex',
436
+ }}
437
+ data-tooltip-id={`tooltip-${addon.id}`}
438
+ data-tooltip-content="View Add-On info"
439
+ >
440
+ <InfoIcon size={14} />
441
+ </span>
442
+ <Tooltip id={`tooltip-${addon.id}`} place="top">
443
+ {addon.description || 'No description available'}
444
+ </Tooltip>
445
+ </>
446
+ )}
354
447
  </div>
355
448
  <div className={`${classNamePrefix}_product_price`}>
356
- {addonNormalizedPrice}
357
- {!isAddonFree && (
358
- <span className={`${classNamePrefix}_product_fee`}>
359
- {addon.feeIncluded ? '(incl. Fees)' : '(excl. Fees)'}
360
- </span>
361
- )}
449
+ {CONFIGS.FEES_STYLE === FEES_STYLES.TRADITIONAL
450
+ ? addonNormalizedPrice
451
+ : addOnNormalizedCost}
452
+ {!isAddonFree &&
453
+ CONFIGS.FEES_STYLE === FEES_STYLES.TRADITIONAL && (
454
+ <span className={`${classNamePrefix}_product_fee`}>
455
+ {addon.feeIncluded ? '(incl. Fees)' : '(excl. Fees)'}
456
+ </span>
457
+ )}
458
+ {!isAddonFree &&
459
+ CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH && (
460
+ <>
461
+ <span className={`${classNamePrefix}_product_fee`}>
462
+ {`(${addonNormalizedPrice} with fees)`}
463
+ </span>
464
+ </>
465
+ )}
362
466
  </div>
363
467
  </div>
364
- <div
365
- className={`${classNamePrefix}_product_desc`}
366
- dangerouslySetInnerHTML={createMarkup(addon.description)}
367
- />
468
+ {(visibleDescription === addon.id ||
469
+ descriptionTrigger === 'always') && (
470
+ <div
471
+ className={`${classNamePrefix}_product_desc`}
472
+ dangerouslySetInnerHTML={createMarkup(addon.description)}
473
+ />
474
+ )}
368
475
  <div className={`${classNamePrefix}_product_select_container`}>
369
476
  {addon.variants ? (
370
477
  addon.variants.map((variant: any) => (
@@ -374,9 +481,14 @@ export const AddonsContainter = ({
374
481
  data={variant}
375
482
  selectOptions={addonsOptions[variant.id]}
376
483
  classNamePrefix={classNamePrefix}
377
- handleAddonChange={(id, value) =>
484
+ handleAddonChange={(id, value) => {
485
+ onAddOnSelect(id, value, addon)
378
486
  onFieldChange(id, value, addon)
379
- }
487
+ }}
488
+ addOnDataWithCustomFields={addOnDataWithCustomFields}
489
+ configs={configs}
490
+ values={values}
491
+ errors={errors}
380
492
  />
381
493
  ))
382
494
  ) : (
@@ -386,23 +498,42 @@ export const AddonsContainter = ({
386
498
  data={addon}
387
499
  selectOptions={addonsOptions[addon.id]}
388
500
  classNamePrefix={classNamePrefix}
389
- handleAddonChange={(id, value) =>
501
+ handleAddonChange={(id, value) => {
502
+ onAddOnSelect(id, value, addon)
390
503
  onFieldChange(id, value, addon)
391
- }
504
+
505
+ _map(addOnDataWithCustomFields.fields, fieldGroup => {
506
+ const { id, groupItems } = fieldGroup
507
+ _map(groupItems, field => {
508
+ setFieldTouched(
509
+ `${addon.id}-${id}-${field.name}`,
510
+ true,
511
+ true
512
+ )
513
+ })
514
+ })
515
+ }}
516
+ addOnDataWithCustomFields={addOnDataWithCustomFields}
517
+ configs={configs}
518
+ values={values}
519
+ errors={errors}
392
520
  />
393
521
  )}
394
522
  </div>
395
523
  </div>
396
524
  )
397
525
  })}
398
- {samePage ? null : <button
399
- type="submit"
400
- className={`${isConfirmDisabled ? `${classNamePrefix}_is_disabled` : ''
526
+ {samePage ? null : (
527
+ <button
528
+ type="submit"
529
+ className={`${
530
+ isConfirmDisabled ? `${classNamePrefix}_is_disabled` : ''
401
531
  } ${classNamePrefix}_submit_button`}
402
- disabled={isConfirmDisabled}
403
- >
404
- CONFIRM SELECTION
405
- </button>}
532
+ disabled={isConfirmDisabled}
533
+ >
534
+ CONFIRM SELECTION
535
+ </button>
536
+ )}
406
537
  </>
407
538
  </Form>
408
539
  )