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,17 +1,24 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  import './style.css'
2
3
 
3
4
  import CircularProgress from '@mui/material/CircularProgress'
4
5
  import {
6
+ AddressElement,
5
7
  CardCvcElement,
6
8
  CardExpiryElement,
7
9
  CardNumberElement,
8
10
  useElements,
9
11
  useStripe,
10
12
  } from '@stripe/react-stripe-js'
11
- import { StripeCardNumberElementOptions } from '@stripe/stripe-js'
13
+ import {
14
+ Stripe,
15
+ StripeCardNumberElement,
16
+ StripeCardNumberElementOptions,
17
+ StripeError,
18
+ } from '@stripe/stripe-js'
12
19
  import _get from 'lodash/get'
13
20
  import _identity from 'lodash/identity'
14
- import React, { useEffect, useState } from 'react'
21
+ import React, { useCallback, useEffect, useState } from 'react'
15
22
 
16
23
  import { refreshSeatReservation } from '../../api'
17
24
  import { getCurrencySymbolByCurrency } from '../../normalizers'
@@ -20,6 +27,17 @@ import { adaptStripeError } from '../../utils/adaptStripeErrors'
20
27
  import { Checkbox } from '../common/index'
21
28
  import ConfirmModal from '../confirmModal'
22
29
 
30
+ interface PaymentFieldsData {
31
+ billing_info: {
32
+ city?: string;
33
+ street_address?: string;
34
+ state?: string;
35
+ };
36
+ postalCode?: string;
37
+ disableZipSection?: boolean;
38
+ cardComplete?: boolean;
39
+ }
40
+
23
41
  const options: StripeCardNumberElementOptions = {
24
42
  style: {
25
43
  base: {
@@ -51,11 +69,21 @@ export interface ICheckoutForm {
51
69
  isLoading: any;
52
70
  handleSetLoading: (loading: any) => void;
53
71
  conditions: any;
54
- disableZipSection: boolean;
72
+ disableZipSection?: boolean;
55
73
  paymentButtonText?: string;
56
74
  forPaymentPlan?: boolean;
57
75
  orderId?: string;
58
76
  hasSeatMapActions: boolean;
77
+ enableAddressElement?: boolean;
78
+ collectPaymentMethodOnly?: boolean;
79
+ displayPaymentButton?: boolean;
80
+ onPaymentFieldsUpdate?: (
81
+ error: any,
82
+ paymentFieldsData: PaymentFieldsData,
83
+ stripe: Stripe | null,
84
+ card: StripeCardNumberElement | null
85
+ ) => void;
86
+ stripeCardError?: StripeError | null;
59
87
  }
60
88
 
61
89
  interface AddressTypes {
@@ -81,13 +109,20 @@ const CheckoutForm = ({
81
109
  paymentButtonText,
82
110
  forPaymentPlan = false,
83
111
  hasSeatMapActions = false,
112
+ enableAddressElement = false,
113
+ displayPaymentButton = true,
114
+ onPaymentFieldsUpdate = _identity,
115
+ stripeCardError = null,
84
116
  }: ICheckoutForm) => {
85
117
  const stripe = useStripe()
86
118
  const elements = useElements()
87
119
  const [postalCode, setPostalCode] = useState<any>('')
88
- const [stripeError, setStripeError] = useState<any>(null)
120
+ const [stripeError, setStripeError] = useState<StripeError | null>(
121
+ stripeCardError || null
122
+ )
89
123
  const [checkboxes, setCheckboxes] = useState<any>([])
90
124
  const [allowSubmit, setAllowSubmit] = useState(false)
125
+ const [cardElementComplete, setCardElementComplete] = useState(false)
91
126
  const eventId = getQueryVariable('event_id') || ''
92
127
 
93
128
  const handleSubmit = async (event: React.SyntheticEvent) => {
@@ -96,7 +131,7 @@ const CheckoutForm = ({
96
131
  event.preventDefault()
97
132
 
98
133
  if (!postalCode && !disableZipSection) {
99
- setStripeError({ message: 'Please enter your zip code.' })
134
+ setStripeError({ message: 'Please enter your zip code.' } as StripeError)
100
135
  handleSetLoading(false)
101
136
  return
102
137
  }
@@ -176,9 +211,43 @@ const CheckoutForm = ({
176
211
  setPostalCode(e.target.value)
177
212
  }
178
213
 
214
+ // Pass payment fields data to parent component for validation and payment method creation
215
+ const notifyPaymentFieldsUpdate = useCallback(() => {
216
+ if (!onPaymentFieldsUpdate || !elements) return
217
+
218
+ const paymentFieldsData = {
219
+ billing_info,
220
+ postalCode,
221
+ disableZipSection,
222
+ cardComplete: cardElementComplete,
223
+ }
224
+
225
+ const card = elements.getElement(CardNumberElement)
226
+ // Pass the fields data to parent component
227
+ // Parent will handle validation and payment method creation when Stripe is ready
228
+ onPaymentFieldsUpdate(null, paymentFieldsData, stripe, card)
229
+ }, [
230
+ onPaymentFieldsUpdate,
231
+ billing_info,
232
+ postalCode,
233
+ disableZipSection,
234
+ cardElementComplete,
235
+ stripe,
236
+ elements,
237
+ ])
238
+
239
+ const handleCardChange = (event: any) => {
240
+ setCardElementComplete(event.complete)
241
+
242
+ // Notify parent about field changes when card is complete and payment button is hidden
243
+ if (event.complete && !displayPaymentButton) {
244
+ notifyPaymentFieldsUpdate()
245
+ }
246
+ }
247
+
179
248
  useEffect(() => {
180
249
  if (typeof window !== 'undefined') {
181
- const userData = JSON.parse(window.localStorage.getItem('user_data') || '')
250
+ const userData = JSON.parse(window.localStorage.getItem('user_data') || '{}')
182
251
  const zipCode = _get(userData, 'zip', '')
183
252
  zipCode && setPostalCode(zipCode)
184
253
  }
@@ -199,6 +268,19 @@ const CheckoutForm = ({
199
268
  }
200
269
  }, [checkboxes])
201
270
 
271
+ // Notify parent when payment fields change (for cases when payment button is hidden)
272
+ useEffect(() => {
273
+ if (!displayPaymentButton && postalCode && cardElementComplete) {
274
+ notifyPaymentFieldsUpdate()
275
+ }
276
+ }, [postalCode, displayPaymentButton, cardElementComplete, notifyPaymentFieldsUpdate])
277
+
278
+ useEffect(() => {
279
+ if (stripeCardError) {
280
+ setStripeError(stripeCardError)
281
+ }
282
+ }, [stripeCardError])
283
+
202
284
  const buttonIsDiabled = !stripe || !!error || isLoading || !allowSubmit
203
285
  return (
204
286
  <div className="stripe_payment_container">
@@ -209,17 +291,29 @@ const CheckoutForm = ({
209
291
  setStripeError(null)
210
292
  onSubmit(stripeError)
211
293
  }}
212
- message={stripeError?.message}
294
+ message={stripeError?.message || ''}
213
295
  />
214
296
  )}
215
297
  <form onSubmit={handleSubmit}>
216
298
  <div className="card_form_inner">
299
+ {enableAddressElement && (
300
+ <div className="card_number_element">
301
+ <span className="card_label_text">Card holder name</span>
302
+ <AddressElement
303
+ options={{ ...options, ...stripeCardOptions, mode: 'billing' }}
304
+ onReady={_identity}
305
+ onChange={handleCardChange}
306
+ onBlur={_identity}
307
+ onFocus={_identity}
308
+ />
309
+ </div>
310
+ )}
217
311
  <div className="card_number_element">
218
312
  <span className="card_label_text">Card number</span>
219
313
  <CardNumberElement
220
314
  options={{ ...options, ...stripeCardOptions }}
221
315
  onReady={_identity}
222
- onChange={_identity}
316
+ onChange={handleCardChange}
223
317
  onBlur={_identity}
224
318
  onFocus={_identity}
225
319
  />
@@ -227,11 +321,17 @@ const CheckoutForm = ({
227
321
  <div className="elements">
228
322
  <div className="expiration_element">
229
323
  <span className="card_label_text">Expiration date</span>
230
- <CardExpiryElement options={{ ...options, ...stripeCardOptions }} />
324
+ <CardExpiryElement
325
+ options={{ ...options, ...stripeCardOptions }}
326
+ onChange={handleCardChange}
327
+ />
231
328
  </div>
232
329
  <div className="cvc_element">
233
330
  <span className="card_label_text">CVC</span>
234
- <CardCvcElement options={{ ...options, ...stripeCardOptions }} />
331
+ <CardCvcElement
332
+ options={{ ...options, ...stripeCardOptions }}
333
+ onChange={handleCardChange}
334
+ />
235
335
  </div>
236
336
  </div>
237
337
  {!disableZipSection && (
@@ -259,20 +359,25 @@ const CheckoutForm = ({
259
359
  </div>
260
360
  </div>
261
361
  ))}
262
- <div
263
- className={`payment_button ${buttonIsDiabled ? 'disabled-payment-button' : ''}`}
264
- >
265
- <button disabled={buttonIsDiabled} type="submit">
266
- {isLoading ? (
267
- <CircularProgress size={26} />
268
- ) : forPaymentPlan ? (
269
- 'Confirm Payment Plan'
270
- ) : (
271
- `${paymentButtonText ? paymentButtonText : 'Pay'
272
- } ${getCurrencySymbolByCurrency(currency)}${total}`
273
- )}
274
- </button>
275
- </div>
362
+ {displayPaymentButton && (
363
+ <div
364
+ className={`payment_button ${
365
+ buttonIsDiabled ? 'disabled-payment-button' : ''
366
+ }`}
367
+ >
368
+ <button disabled={buttonIsDiabled} type="submit">
369
+ {isLoading ? (
370
+ <CircularProgress size={26} />
371
+ ) : forPaymentPlan ? (
372
+ 'Confirm Payment Plan'
373
+ ) : (
374
+ `${
375
+ paymentButtonText ? paymentButtonText : 'Pay'
376
+ } ${getCurrencySymbolByCurrency(currency)}${total}`
377
+ )}
378
+ </button>
379
+ </div>
380
+ )}
276
381
  </form>
277
382
  </div>
278
383
  )
@@ -0,0 +1,35 @@
1
+ import React from "react"
2
+
3
+ const InfoIcon = ({ size = 17 }) => (
4
+ <svg
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ width={size}
7
+ height={size}
8
+ viewBox="0 0 17 17"
9
+ fill="none"
10
+ >
11
+ <circle
12
+ cx="8.5"
13
+ cy="8.5"
14
+ r="8"
15
+ stroke="black"
16
+ strokeWidth="1"
17
+ />
18
+ <rect
19
+ x="7.5"
20
+ y="4"
21
+ width="2"
22
+ height="2"
23
+ fill="black"
24
+ />
25
+ <rect
26
+ x="7.5"
27
+ y="7"
28
+ width="2"
29
+ height="5"
30
+ fill="black"
31
+ />
32
+ </svg>
33
+ )
34
+
35
+ export default InfoIcon
@@ -33,38 +33,39 @@ export const PromoCodeSection = ({
33
33
  showAlertIcons
34
34
  }: IPromoCodeSectionProps) => {
35
35
  const isPromoCodeHasValue = !!code.trim()
36
+ const appliedPromoCode = window?.localStorage?.getItem('appliedPromoCode')
36
37
 
37
38
  const renderInputField = () => (
39
+ <div className="promo-code-block">
38
40
  <div className="promo-code-block">
39
- <div className="promo-code-block">
40
- <p className="promo-code-text">Promo code</p>
41
- </div>
42
- <input
43
- className="promo-code-input"
44
- placeholder=""
45
- onChange={e => {
46
- setCode(e.target.value)
47
- }}
48
- onKeyPress={event => {
49
- if (event.key === 'Enter' && isPromoCodeHasValue) {
50
- setShowPromoInput(false)
51
- updateTickets(true, 'promo')
52
- }
53
- }}
54
- />
55
- <Button
56
- className="promo-submit-button"
57
- onClick={() => {
58
- if (isPromoCodeHasValue) {
59
- setShowPromoInput(false)
60
- updateTickets(true, 'promo')
61
- }
62
- }}
63
- >
64
- APPLY
65
- </Button>
41
+ <p className="promo-code-text">Promo code</p>
66
42
  </div>
67
- )
43
+ <input
44
+ className="promo-code-input"
45
+ placeholder=""
46
+ onChange={e => {
47
+ setCode(e.target.value)
48
+ }}
49
+ onKeyPress={event => {
50
+ if (event.key === 'Enter' && isPromoCodeHasValue) {
51
+ setShowPromoInput(false)
52
+ updateTickets(true, 'promo')
53
+ }
54
+ }}
55
+ />
56
+ <Button
57
+ className="promo-submit-button"
58
+ onClick={() => {
59
+ if (isPromoCodeHasValue) {
60
+ setShowPromoInput(false)
61
+ updateTickets(true, 'promo')
62
+ }
63
+ }}
64
+ >
65
+ APPLY
66
+ </Button>
67
+ </div>
68
+ )
68
69
 
69
70
  return (
70
71
  <div>
@@ -81,6 +82,11 @@ export const PromoCodeSection = ({
81
82
  <p className="promo-code-success">PROMO CODE APPLIED SUCCESSFULLY</p>
82
83
  </div>
83
84
  ) : null}
85
+ {codeIsApplied ? (
86
+ <div className="alert-info">
87
+ <p className="promo-code-success">PROMO CODE: {appliedPromoCode}</p>
88
+ </div>
89
+ ) : null}
84
90
  {codeIsInvalid ? (
85
91
  <div className="alert-info fail">
86
92
  {showAlertIcons && (
@@ -83,7 +83,7 @@ export const TicketRow = ({
83
83
  // ticketTier.soldOut === false --> means that ticket is in the stock
84
84
  const isSoldOut =
85
85
  ticketTier.sold_out ||
86
- !ticketTier.displayTicket ||
86
+ !(ticketTier.displayTicket || ticketTier.slotGroupId) ||
87
87
  ticketTier.soldOut ||
88
88
  ticketTier.soldOut === false
89
89