tf-checkout-react 1.6.6-beta.35 → 1.6.6-beta.37

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 (40) hide show
  1. package/README.md +353 -32
  2. package/dist/api/index.d.ts +1 -0
  3. package/dist/components/addonsContainer/AddonComponent.d.ts +2 -1
  4. package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +1 -1
  5. package/dist/components/billing-info-container/hooks/index.d.ts +3 -0
  6. package/dist/components/billing-info-container/hooks/usePaymentContext.d.ts +5 -0
  7. package/dist/components/billing-info-container/hooks/usePaymentRedirect.d.ts +14 -0
  8. package/dist/components/billing-info-container/hooks/useStripePayment.d.ts +18 -0
  9. package/dist/components/billing-info-container/index.d.ts +2 -1
  10. package/dist/components/confirmationContainer/index.d.ts +3 -1
  11. package/dist/components/orderDetailsContainer/index.d.ts +2 -1
  12. package/dist/components/paymentContainer/index.d.ts +3 -4
  13. package/dist/components/ticketsContainer/index.d.ts +3 -0
  14. package/dist/tf-checkout-react.cjs.development.js +665 -752
  15. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  16. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  17. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  18. package/dist/tf-checkout-react.esm.js +677 -764
  19. package/dist/tf-checkout-react.esm.js.map +1 -1
  20. package/dist/tf-checkout-styles.css +1 -1
  21. package/dist/types/order-data.d.ts +1 -0
  22. package/package.json +1 -1
  23. package/src/api/index.ts +1 -0
  24. package/src/components/addonsContainer/AddonComponent.tsx +49 -24
  25. package/src/components/addonsContainer/SimpleAddonsContainer.tsx +40 -4
  26. package/src/components/billing-info-container/hooks/index.ts +3 -0
  27. package/src/components/billing-info-container/hooks/usePaymentContext.ts +22 -0
  28. package/src/components/billing-info-container/hooks/usePaymentRedirect.ts +147 -0
  29. package/src/components/billing-info-container/hooks/useStripePayment.ts +121 -0
  30. package/src/components/billing-info-container/index.tsx +175 -135
  31. package/src/components/confirmationContainer/index.tsx +18 -0
  32. package/src/components/orderDetailsContainer/index.tsx +19 -2
  33. package/src/components/paymentContainer/OrderDetails.tsx +1 -1
  34. package/src/components/paymentContainer/index.tsx +109 -101
  35. package/src/components/ticketsContainer/index.tsx +7 -0
  36. package/src/types/api/cart.d.ts +8 -0
  37. package/src/types/order-data.ts +1 -0
  38. package/dist/components/stripePayment/index.d.ts +0 -39
  39. package/src/components/stripePayment/index.tsx +0 -386
  40. package/src/components/stripePayment/style.css +0 -60
package/README.md CHANGED
@@ -3,7 +3,9 @@
3
3
   
4
4
 
5
5
  <details open>
6
- <summary><strong>Table of Contents</strong></summary>
6
+ <summary>
7
+ <strong>Table of Contents</strong>
8
+ </summary>
7
9
 
8
10
  - [tf-checkout-react](#tf-checkout-react)
9
11
  - [Code style and formatting](#code-style-and-formatting)
@@ -40,6 +42,7 @@
40
42
  - [Ticket Resale Container](#ticket-resale-container)
41
43
  - [Commands](#commands)
42
44
  - [Rollup](#rollup)
45
+ - [Optimizations](#optimizations)
43
46
  - [TypeScript](#typescript)
44
47
  - [GitHub Actions](#github-actions)
45
48
 
@@ -48,20 +51,20 @@
48
51
  ## Code style and formatting
49
52
 
50
53
  1. **Install Prettier ESLint extension (v5.1.0)**
51
- - VSCode: https://marketplace.visualstudio.com/items?itemName=rvest.vs-code-prettier-eslint
52
- - JetBrains' products: https://blog.jetbrains.com/webstorm/2016/08/using-external-tools/
54
+ - VSCode: <https://marketplace.visualstudio.com/items?itemName=rvest.vs-code-prettier-eslint>
55
+ - JetBrains' products: <https://blog.jetbrains.com/webstorm/2016/08/using-external-tools/>
53
56
  Notes:
54
57
  - The Prettier extension is not required.
55
58
  - The ESLint extension is not required. However, it is needed to have lint errors show while editing your file.
56
59
  2. **Set Prettier ESLint default formatter**
57
60
 
58
61
  - VSCode: Open commands (CMD/Win + Stift + P) -> Format document with -> Configure default formatter
59
- - JetBrains' products: https://blog.jetbrains.com/webstorm/2016/08/using-external-tools/
62
+ - JetBrains' products: <https://blog.jetbrains.com/webstorm/2016/08/using-external-tools/>
60
63
 
61
64
  3. **Enable format on save**
62
65
 
63
66
  - VSCode: Open settings (CMD + ,) -> Search "Format On Save"
64
- - JetBrains' products: https://blog.jetbrains.com/webstorm/2016/08/using-external-tools/
67
+ - JetBrains' products: <https://blog.jetbrains.com/webstorm/2016/08/using-external-tools/>
65
68
 
66
69
  &nbsp;
67
70
 
@@ -73,16 +76,16 @@ This package provides a set of components and functionalities designed to manage
73
76
 
74
77
  - `AccountSettings`: A component for managing user account settings, such as email address and password.
75
78
  - `AddonsContainter`: A component for displaying a list of available add-ons and allowing the user to purchase them.
76
- - `BillingInfoContainer`: A component for managing billing information, such as addresses and ticket holders.
79
+ - `BillingInfoContainer`: A component for managing billing information, such as addresses and ticket holders. Features enhanced field rendering, improved validation, and better user experience.
77
80
  - `ConfirmationContainer`: A component for displaying a confirmation page after a purchase is made.
78
81
  - `IDVerification`: A component for verifying the identity of the user during the checkout process.
79
82
  - `MyTicketsContainer`: A component for displaying a list of purchased orders.
80
83
  - `OrderDetailsContainer`: A component for displaying detailed information about a purchase, such as the ticket types, add-ons and pricing.
81
- - `PaymentContainer`: A component for managing payment processing during the checkout process.
84
+ - `PaymentContainer`: A component for managing payment processing during the checkout process. Includes enhanced Stripe integration, improved payment validation, and better error handling.
82
85
  - `ResetPasswordContainer`: A component for resetting a user's password.
83
86
  - `SeatMapContainer`: A component for displaying and selecting seats on a venue map.
84
87
  - `TicketResaleContainer`: A component for managing the resale of tickets or add-ons by the user.
85
- - `TicketsContainer`: A component for displaying a list of available tickets and allowing the user to purchase them.
88
+ - `TicketsContainer`: A component for displaying a list of available tickets and allowing the user to purchase them. Features optimized API calls, better state management, and enhanced user interactions.
86
89
 
87
90
  Together, these components and functionalities provide a comprehensive set of tools to manage the checkout process and related activities for a TicketFairy-powered event.
88
91
  &nbsp;
@@ -101,13 +104,13 @@ Together, these components and functionalities provide a comprehensive set of to
101
104
 
102
105
  # Installation
103
106
 
104
- ```
107
+ ```bash
105
108
  npm i tf-checkout-react
106
109
  ```
107
110
 
108
111
  or
109
112
 
110
- ```
113
+ ```bash
111
114
  yarn add tf-checkout-react
112
115
  ```
113
116
 
@@ -126,11 +129,13 @@ Project will run under `localhost:3002`. Port can be changed from `package.json`
126
129
 
127
130
  ## Set configuration
128
131
 
129
- In order to make this package work properly, you need to set some configurations, otherwise the default configurations will be used. Currently only configuration which is needed for production, is `BASE_URL`. Other configurations written below are only for development/test environments.
132
+ In order to make this package work properly, you need to set some configurations, otherwise the default configurations will be used.
133
+ Currently only configuration which is needed for production, is `BASE_URL`.
134
+ Other configurations written below are only for development/test environments.
130
135
 
131
136
  Import `setConfigs` function from the package.
132
137
 
133
- ```
138
+ ```js
134
139
  import { setConfigs } from 'tf-checkout-react'
135
140
  ```
136
141
 
@@ -149,15 +154,293 @@ Call it in the root and pass neccesary options. Here are available options:
149
154
 
150
155
  &nbsp;
151
156
 
157
+ # Single Page Checkout Implementation
158
+
159
+ ## Overview
160
+
161
+ While the default implementation uses separate pages for each checkout step (`TicketsContainer` → `BillingInfoContainer` → `PaymentContainer` → `ConfirmationContainer`), the package also supports a **single page checkout flow** where all components are rendered on the same page with conditional visibility and state management.
162
+
163
+ ## Key Differences from Default Flow
164
+
165
+ ### **Default Multi-Page Flow:**
166
+
167
+ - Each component handles its own routing and navigation
168
+ - State is managed through URL parameters and localStorage
169
+ - Components are mounted/unmounted as user navigates
170
+ - Each step is a separate page/route
171
+
172
+ ### **Single Page Flow:**
173
+
174
+ - All components are conditionally rendered on the same page
175
+ - State management requires careful coordination between components
176
+ - Components remain mounted but visibility is controlled
177
+ - Navigation is handled through state changes rather than routing
178
+
179
+ ## Implementation Patterns
180
+
181
+ ### **1. State Management**
182
+
183
+ ```jsx
184
+ import React, { useState } from 'react'
185
+ import {
186
+ TicketsContainer,
187
+ BillingInfoContainer,
188
+ PaymentContainer,
189
+ ConfirmationContainer
190
+ } from 'tf-checkout-react'
191
+
192
+ const SinglePageCheckout = () => {
193
+ const [currentStep, setCurrentStep] = useState('tickets')
194
+ const [checkoutData, setCheckoutData] = useState({})
195
+ const [cartData, setCartData] = useState(null)
196
+
197
+ const handleTicketsSuccess = (data) => {
198
+ setCartData(data)
199
+ setCurrentStep('billing')
200
+ }
201
+
202
+ const handleBillingSuccess = (data) => {
203
+ setCheckoutData(prev => ({ ...prev, billing: data }))
204
+ setCurrentStep('payment')
205
+ }
206
+
207
+ const handlePaymentSuccess = (data) => {
208
+ setCheckoutData(prev => ({ ...prev, payment: data }))
209
+ setCurrentStep('confirmation')
210
+ }
211
+
212
+ return (
213
+ <div className="single-page-checkout">
214
+ {currentStep === 'tickets' && (
215
+ <TicketsContainer
216
+ eventId={eventId}
217
+ onAddToCartSuccess={handleTicketsSuccess}
218
+ // Disable auto-navigation
219
+ enableBillingInfoAutoCreate={false}
220
+ />
221
+ )}
222
+
223
+ {currentStep === 'billing' && (
224
+ <BillingInfoContainer
225
+ handleSubmit={handleBillingSuccess}
226
+ // Skip automatic payment redirect
227
+ skipPage={false}
228
+ />
229
+ )}
230
+
231
+ {currentStep === 'payment' && (
232
+ <PaymentContainer
233
+ checkoutData={checkoutData}
234
+ handlePayment={handlePaymentSuccess}
235
+ />
236
+ )}
237
+
238
+ {currentStep === 'confirmation' && (
239
+ <ConfirmationContainer
240
+ orderHash={checkoutData.payment?.orderHash}
241
+ />
242
+ )}
243
+ </div>
244
+ )
245
+ }
246
+ ```
247
+
248
+ ### **2. Progressive Enhancement Pattern**
249
+
250
+ ```jsx
251
+ const ProgressiveCheckout = () => {
252
+ const [completedSteps, setCompletedSteps] = useState(new Set())
253
+ const [activeStep, setActiveStep] = useState('tickets')
254
+
255
+ const markStepComplete = (step) => {
256
+ setCompletedSteps(prev => new Set([...prev, step]))
257
+ }
258
+
259
+ const isStepAccessible = (step) => {
260
+ const stepOrder = ['tickets', 'billing', 'payment', 'confirmation']
261
+ const stepIndex = stepOrder.indexOf(step)
262
+ const prevStep = stepOrder[stepIndex - 1]
263
+ return stepIndex === 0 || completedSteps.has(prevStep)
264
+ }
265
+
266
+ return (
267
+ <div className="progressive-checkout">
268
+ {/* Step Navigation */}
269
+ <div className="checkout-steps">
270
+ {['tickets', 'billing', 'payment', 'confirmation'].map(step => (
271
+ <button
272
+ key={step}
273
+ disabled={!isStepAccessible(step)}
274
+ className={`step ${activeStep === step ? 'active' : ''} ${completedSteps.has(step) ? 'completed' : ''}`}
275
+ onClick={() => setActiveStep(step)}
276
+ >
277
+ {step.charAt(0).toUpperCase() + step.slice(1)}
278
+ </button>
279
+ ))}
280
+ </div>
281
+
282
+ {/* Component Rendering */}
283
+ <div className="checkout-content">
284
+ {activeStep === 'tickets' && (
285
+ <TicketsContainer
286
+ onAddToCartSuccess={(data) => {
287
+ markStepComplete('tickets')
288
+ setActiveStep('billing')
289
+ }}
290
+ />
291
+ )}
292
+ {/* ... other components */}
293
+ </div>
294
+ </div>
295
+ )
296
+ }
297
+ ```
298
+
299
+ ### **3. Accordion/Collapsible Pattern**
300
+
301
+ ```jsx
302
+ const AccordionCheckout = () => {
303
+ const [openSections, setOpenSections] = useState(new Set(['tickets']))
304
+ const [completedSections, setCompletedSections] = useState(new Set())
305
+
306
+ const toggleSection = (section) => {
307
+ setOpenSections(prev => {
308
+ const newSet = new Set(prev)
309
+ if (newSet.has(section)) {
310
+ newSet.delete(section)
311
+ } else {
312
+ newSet.add(section)
313
+ }
314
+ return newSet
315
+ })
316
+ }
317
+
318
+ return (
319
+ <div className="accordion-checkout">
320
+ <div className="checkout-section">
321
+ <div
322
+ className="section-header"
323
+ onClick={() => toggleSection('tickets')}
324
+ >
325
+ <h3>Select Tickets</h3>
326
+ {completedSections.has('tickets') && <span>✓</span>}
327
+ </div>
328
+ {openSections.has('tickets') && (
329
+ <TicketsContainer
330
+ onAddToCartSuccess={(data) => {
331
+ setCompletedSections(prev => new Set([...prev, 'tickets']))
332
+ setOpenSections(new Set(['billing']))
333
+ }}
334
+ />
335
+ )}
336
+ </div>
337
+
338
+ <div className="checkout-section">
339
+ <div
340
+ className="section-header"
341
+ onClick={() => toggleSection('billing')}
342
+ >
343
+ <h3>Billing Information</h3>
344
+ {completedSections.has('billing') && <span>✓</span>}
345
+ </div>
346
+ {openSections.has('billing') && (
347
+ <BillingInfoContainer
348
+ handleSubmit={(values, helpers, eventId, res) => {
349
+ setCompletedSections(prev => new Set([...prev, 'billing']))
350
+ setOpenSections(new Set(['payment']))
351
+ }}
352
+ />
353
+ )}
354
+ </div>
355
+
356
+ {/* ... other sections */}
357
+ </div>
358
+ )
359
+ }
360
+ ```
361
+
362
+ ## Important Considerations
363
+
364
+ ### **Component Props Modifications**
365
+
366
+ - **`enableBillingInfoAutoCreate: false`** - Prevents automatic navigation to billing page
367
+ - **`skipPage: false`** - Controls whether billing page can be skipped
368
+ - **Custom callback handlers** - Override default navigation behavior
369
+
370
+ ### **State Persistence**
371
+
372
+ ```jsx
373
+ // Save state to localStorage for page refreshes
374
+ useEffect(() => {
375
+ localStorage.setItem('checkoutState', JSON.stringify({
376
+ currentStep,
377
+ checkoutData,
378
+ cartData
379
+ }))
380
+ }, [currentStep, checkoutData, cartData])
381
+
382
+ // Restore state on component mount
383
+ useEffect(() => {
384
+ const savedState = localStorage.getItem('checkoutState')
385
+ if (savedState) {
386
+ const { currentStep, checkoutData, cartData } = JSON.parse(savedState)
387
+ setCurrentStep(currentStep)
388
+ setCheckoutData(checkoutData)
389
+ setCartData(cartData)
390
+ }
391
+ }, [])
392
+ ```
393
+
394
+ ### **Error Handling**
395
+
396
+ ```jsx
397
+ const [errors, setErrors] = useState({})
398
+
399
+ const handleStepError = (step, error) => {
400
+ setErrors(prev => ({ ...prev, [step]: error }))
401
+ // Optionally navigate back to error step
402
+ setCurrentStep(step)
403
+ }
404
+
405
+ // Pass error handlers to each component
406
+ <BillingInfoContainer
407
+ onSubmitError={(error) => handleStepError('billing', error)}
408
+ handleSubmit={handleBillingSuccess}
409
+ />
410
+ ```
411
+
412
+ ### **Timer Coordination**
413
+
414
+ When using timers across multiple components in single page flow:
415
+
416
+ ```jsx
417
+ const [globalTimer, setGlobalTimer] = useState(null)
418
+
419
+ // Share timer state across components
420
+ <TicketsContainer enableTimer={false} />
421
+ <BillingInfoContainer enableTimer={false} />
422
+ <PaymentContainer enableTimer={true} onCountdownFinish={handleTimeout} />
423
+
424
+ // Or implement global timer
425
+ <TimerWidget
426
+ onCountdownFinish={handleGlobalTimeout}
427
+ className="global-timer"
428
+ />
429
+ ```
430
+
431
+ &nbsp;
432
+
152
433
  # Functionalities
153
434
 
154
435
  ## Login
155
436
 
156
437
  The `LoginModal` component is designed to be used inside package to authenticate users. <br /> To use the `LoginModal`, simply include it in your React component and pass in the required **onLogin** and **onClose** callbacks as props.
157
438
 
158
- You can authenticate users from the Billing page too, here you can either provide **onLogin** callback as a prop to the [`BillingInfoContainer`](#billinginfocontainer) component so that you can open your custom component for authentication or you can ommit it and the package inside provided `LoginModal` component will be called and opened.
439
+ You can authenticate users from the Billing page too, here you can either provide **onLogin** callback as a prop to the [`BillingInfoContainer`](#billinginfocontainer) component so that you can open your custom component for authentication or
440
+ you can ommit it and the package inside provided `LoginModal` component will be called and opened.
159
441
 
160
- Package can detect whether a user is logged in or not by checking for the presence of the **X-TF-ECOMMERCE** cookie, which is automatically set by the system when the user successfully logs in. If the **X-TF-ECOMMERCE** cookie is present, the package assumes that the user is logged in and displays the appropriate content.
442
+ Package can detect whether a user is logged in or not by checking for the presence of the **X-TF-ECOMMERCE** cookie, which is automatically set by the system when the user successfully logs in.
443
+ If the **X-TF-ECOMMERCE** cookie is present, the package assumes that the user is logged in and displays the appropriate content.
161
444
 
162
445
  The `LoginModal` component also is used in [`MyTicketsContainer`](#myticketscontainer) and [`TicketsContainer`](#ticketscontainer).
163
446
 
@@ -207,7 +490,10 @@ const MyComponent = () => {
207
490
 
208
491
  The `RegisterModal` component is designed to be used inside package to allows users to register for an account. <br />
209
492
 
210
- When the user submits the form, the component calls the register API function to create the user's account. If account creation is successful, the component then retrieves the user's profile data. The **onGetProfileDataSuccess** and **onGetProfileDataError** callbacks are then called depending on whether the profile data retrieval succeeds or fails. If profile data retrieval succeeds, the component maps the profile data to a format used by the application and saves the resulting data to the browser's localStorage. Finally, the **onClose** callback is called to close the modal.
493
+ When the user submits the form, the component calls the register API function to create the user's account.
494
+ If account creation is successful, the component then retrieves the user's profile data. The **onGetProfileDataSuccess** and **onGetProfileDataError** callbacks are then called depending on whether the profile data retrieval succeeds or fails.
495
+ If profile data retrieval succeeds, the component maps the profile data to a format used by the application and saves the resulting data to the browser's localStorage.
496
+ Finally, the **onClose** callback is called to close the modal.
211
497
 
212
498
  <details open>
213
499
  <summary><b>Register Modal Props Interface:</b></summary>
@@ -226,7 +512,9 @@ When the user submits the form, the component calls the register API function to
226
512
 
227
513
  ## Forgot Password
228
514
 
229
- The `ForgotPasswordModal` component is a modal dialog for users to reset their passwords. To use it, simply import the component, manage its open state, and provide callback functions for closing the modal, navigating back to the login page or component, handling successful password reset requests, and handling errors in password reset requests. Optionally, you can also display a "Powered By" image within the modal by setting the **showPoweredByImage** prop to true.
515
+ The `ForgotPasswordModal` component is a modal dialog for users to reset their passwords.
516
+ To use it, simply import the component, manage its open state, and provide callback functions for closing the modal, navigating back to the login page or component, handling successful password reset requests, and handling errors in password reset requests.
517
+ Optionally, you can also display a "Powered By" image within the modal by setting the **showPoweredByImage** prop to true.
230
518
 
231
519
  <details open>
232
520
  <summary><b>Forgot Password Modal Props Interface:</b></summary>
@@ -244,7 +532,8 @@ The `ForgotPasswordModal` component is a modal dialog for users to reset their p
244
532
 
245
533
  ## Promo Code
246
534
 
247
- The `PromoCodeSection` is a React component for handling promo code input, validation, and displaying success or error messages. It accepts various props to control its appearance and behavior, such as the promo code value, validation status, input visibility, and callback functions for updating the state which you can see in the below provided table.
535
+ The `PromoCodeSection` is a React component for handling promo code input, validation, and displaying success or error messages.
536
+ It accepts various props to control its appearance and behavior, such as the promo code value, validation status, input visibility, and callback functions for updating the state which you can see in the below provided table.
248
537
 
249
538
  To use this component, simply import it and include it in your JSX with the required props, managing the component's state and callback functions in the parent component as needed.
250
539
 
@@ -275,9 +564,12 @@ To use this component, simply import it and include it in your JSX with the requ
275
564
 
276
565
  ## Access Code
277
566
 
278
- The `AccessCodeSection` is a React component designed for handling access code input and submission. It allows users to enter an access code and triggers an update to the ticket information based on the submitted access code. The component accepts a set of props to manage the access code value and provide callback functions for updating the state which you can see in below table.
567
+ The `AccessCodeSection` is a React component designed for handling access code input and submission.
568
+ It allows users to enter an access code and triggers an update to the ticket information based on the submitted access code.
569
+ The component accepts a set of props to manage the access code value and provide callback functions for updating the state which you can see in below table.
279
570
 
280
- To integrate the `AccessCodeSection` component, import it into your JSX and provide the required props, such as the access code value, and callback functions for updating the state. Make sure to manage the component's state and callback functions within the parent component as needed. <br />
571
+ To integrate the `AccessCodeSection` component, import it into your JSX and provide the required props, such as the access code value, and callback functions for updating the state.
572
+ Make sure to manage the component's state and callback functions within the parent component as needed. <br />
281
573
 
282
574
  ### **Note that package automatically calls component in [`TicketsContainer`](#ticketscontainer)**
283
575
 
@@ -298,7 +590,9 @@ To integrate the `AccessCodeSection` component, import it into your JSX and prov
298
590
 
299
591
  ## Waiting List
300
592
 
301
- The `WaitingList` component is a React component designed to handle user registration for a waiting list. It displays a form that allows users to input their information, including first name, last name, email, ticket type, and quantity. Upon submission, the component adds the user to the waiting list and displays a success message.
593
+ The `WaitingList` component is a React component designed to handle user registration for a waiting list.
594
+ It displays a form that allows users to input their information, including first name, last name, email, ticket type, and quantity.
595
+ Upon submission, the component adds the user to the waiting list and displays a success message.
302
596
 
303
597
  ### **Note that package automatically calls component in [`TicketsContainer`](#ticketscontainer)**
304
598
 
@@ -343,18 +637,27 @@ The **"Get Tickets"** button which name is also customizable, allows the user to
343
637
  Other buttons can be displayed to handle various actions, such as viewing the user's orders or logging out.
344
638
 
345
639
  Tickets component provides a section for entering an [Access Code](#access-code) or [Promo Code](#promo-code) that applies a discount to the ticket price or hide/unhide some tickets via [Access Code](#access-code).<br />
346
- It also containes `WaitingLsit` that manages and displays waiting list functionality for the event.<br />
640
+ It also contains `WaitingList` that manages and displays waiting list functionality for the event.<br />
347
641
  Props interface partially extends [Promo Code Props Interface](#promo-code), [Access Code Props Interface](#access-code), [Waiting List Props Interface](#waiting-list).
348
642
 
349
643
  Tickets component displays a list of the top influencers who have promoted the event.
350
644
 
645
+ **Recent Improvements:**
646
+
647
+ - Fixed duplicate API calls issue by optimizing useEffect dependencies
648
+ - Enhanced error handling and loading states
649
+ - Improved time slot management for events
650
+ - Better integration with promo codes and access codes
651
+ - Optimized component re-rendering patterns
652
+
351
653
  Tickets component is flexible and customizable, allowing for different layouts and behaviors depending on the event's requirements.
352
654
 
353
655
  **_Example of usage_**:
354
656
 
355
657
  ```jsx
356
658
  import { TicketsContainer } from 'tf-checkout-react'
357
- ;<TicketsContainer
659
+
660
+ <TicketsContainer
358
661
  theme="light"
359
662
  eventId={event?.id}
360
663
  handleNotInvitedModalClose={() => {}}
@@ -451,7 +754,15 @@ Add-Ons component will retrieve and show a list of add-ons corresponding to sele
451
754
 
452
755
  The component is responsible for managing the billing information during the checkout process. It provides a form that allows users to enter their billing information, including addresses and ticket holders' information.
453
756
 
454
- Component includes also phone field, which validation functionality is provided by Twilio and integrated into the component. It provides an additional layer of verification and security during the ticket purchase process.
757
+ Component includes phone field validation functionality provided by Twilio, which adds an additional layer of verification and security during the ticket purchase process.
758
+
759
+ **Recent Improvements:**
760
+
761
+ - Enhanced architecture with better separation of concerns
762
+ - Improved form validation and error handling
763
+ - Better TypeScript typing throughout the component
764
+ - Optimized API call patterns to prevent duplicate requests
765
+ - Enhanced field rendering system for better customization
455
766
 
456
767
  Props interface extends [Login Modal Interface](#login), [Register Modal Interface](#register), [Forgot Password Modal Interface](#forgot-password).
457
768
 
@@ -501,6 +812,14 @@ Props interface extends [Login Modal Interface](#login), [Register Modal Interfa
501
812
 
502
813
  The component provides a form for users to enter their payment information and checkout. It accepts various props to customize the form and handle the checkout process.
503
814
 
815
+ **Recent Improvements:**
816
+
817
+ - Enhanced Stripe integration with better error handling
818
+ - Improved payment field validation and user feedback
819
+ - Better handling of payment method creation and confirmation
820
+ - Enhanced payment plan support with improved UI
821
+ - Optimized payment flow for better user experience
822
+
504
823
  <details open>
505
824
 
506
825
  | Property | Type | Required | Default Value | Description |
@@ -657,8 +976,8 @@ Container renders information about accepting or declining of resold tickets. It
657
976
  <details open>
658
977
  <summary><small id="1">1. Share buttons</small></summary>
659
978
 
660
- ```
661
- IShareButton {
979
+ ```ts
980
+ interface IShareButton {
662
981
  mainLabel: string;
663
982
  subLabel: string;
664
983
  platform: string;
@@ -666,7 +985,7 @@ IShareButton {
666
985
  }
667
986
  ```
668
987
 
669
- ```
988
+ ```yaml
670
989
  Default share options if `showDefaultShareButtons` is true, are: "Share on Facebook", "Tweet to your Followers", "Message friends on Facebook" and "Message friends on WhatsApp".
671
990
  ```
672
991
 
@@ -675,15 +994,15 @@ Default share options if `showDefaultShareButtons` is true, are: "Share on Faceb
675
994
  <details open>
676
995
  <summary><small id="2">2. Confirmation Labels</small></summary>
677
996
 
678
- ```
679
- IConfirmationLabels {
997
+ ```ts
998
+ interface IConfirmationLabels {
680
999
  confirmationTitle?: string;
681
1000
  confirmationMain?: string;
682
1001
  confirmationHelper?: string
683
1002
  }
684
1003
  ```
685
1004
 
686
- ```
1005
+ ```js
687
1006
  const defaultConfirmationLabels = {
688
1007
  confirmationTitle = "Your Tickets are Confirmed!",
689
1008
  confirmationMain = "Your tickets are available in My Tickets section",
@@ -696,7 +1015,7 @@ const defaultConfirmationLabels = {
696
1015
  <details open>
697
1016
  <summary><small id="3">3. Tickets table columns</small></summary>
698
1017
 
699
- ```
1018
+ ```ts
700
1019
  interface ITicketsTableColumns {
701
1020
  id?: string | number;
702
1021
  key: keyof ITicketTypes & keyof IActionColumns;
@@ -709,7 +1028,7 @@ interface IActionColumns {
709
1028
  }
710
1029
  ```
711
1030
 
712
- ```
1031
+ ```ts
713
1032
  const defaultTicketsTableColumns = [
714
1033
  { key: 'ticket_type', label: 'Ticket Type' },
715
1034
  { key: 'holder_name', label: 'Ticket Holder' },
@@ -747,7 +1066,7 @@ To do a one-off build, use `npm run build` or `yarn build`.
747
1066
 
748
1067
  &nbsp;
749
1068
 
750
- ### Rollup
1069
+ ## Rollup
751
1070
 
752
1071
  TSDX uses [Rollup](https://rollupjs.org) as a bundler and generates multiple rollup configs for various module formats and build settings. See [Optimizations](#optimizations) for details.
753
1072
 
@@ -763,3 +1082,5 @@ Two actions are added by default:
763
1082
 
764
1083
  - `main` which installs deps w/ cache, lints, tests, and builds on all pushes against a Node and OS matrix
765
1084
  - `size` which comments cost comparison of your library on every pull request using [`size-limit`](https://github.com/ai/size-limit)
1085
+
1086
+ ## Optimizations
@@ -42,6 +42,7 @@ export interface AttributesConfig {
42
42
  collect_mandatory_instagram: boolean;
43
43
  collect_optional_instagram: boolean;
44
44
  skip_billing_page: boolean;
45
+ cart: ICart[];
45
46
  }
46
47
  export interface ConfigsData {
47
48
  attributes: AttributesConfig;
@@ -8,6 +8,7 @@ interface IAddonComponentProps {
8
8
  configs: any;
9
9
  values: any;
10
10
  errors: any;
11
+ onCustomFieldChange?: (addon: any, groupId: string | number, fieldName: string, value: any) => void;
11
12
  }
12
- declare const AddonComponent: ({ classNamePrefix, data, selectOptions, handleAddonChange, addOnDataWithCustomFields, configs, values, errors, }: IAddonComponentProps) => JSX.Element;
13
+ declare const AddonComponent: ({ classNamePrefix, data, selectOptions, handleAddonChange, addOnDataWithCustomFields, configs, values, errors, onCustomFieldChange, }: IAddonComponentProps) => JSX.Element;
13
14
  export default AddonComponent;
@@ -7,7 +7,7 @@ export interface ISimpleAddonContainerProps {
7
7
  addOnDataWithCustomFields: any;
8
8
  configs: any;
9
9
  eventId: string;
10
- onAddOnSelect?: (id: string, value: string, addon: any) => void;
10
+ onAddOnSelect?: (id: string, value: string, addon: any, fieldUpdates: any) => void;
11
11
  handleConfirm?: (values: any) => void;
12
12
  }
13
13
  export interface ObjectLiteral {
@@ -0,0 +1,3 @@
1
+ export { usePaymentRedirect } from './usePaymentRedirect';
2
+ export { useStripePayment } from './useStripePayment';
3
+ export { usePaymentContext } from './usePaymentContext';
@@ -0,0 +1,5 @@
1
+ export declare const usePaymentContext: () => {
2
+ storePaymentContext: (context: any) => void;
3
+ getPaymentContext: () => any;
4
+ clearPaymentContext: () => void;
5
+ };
@@ -0,0 +1,14 @@
1
+ /// <reference types="react" />
2
+ import { Stripe } from '@stripe/stripe-js';
3
+ import { FormikHelpers } from 'formik';
4
+ interface UsePaymentRedirectProps {
5
+ stripeRef: React.MutableRefObject<Stripe | null>;
6
+ setError: (error: string | null) => void;
7
+ setLoading: (loading: boolean) => void;
8
+ removeReferralKey: () => void;
9
+ removeAdditionalConfigs: () => void;
10
+ handleSubmit: (values: any, formikHelpers: FormikHelpers<any>, eventId: any, checkoutResponse: any, checkoutUpdateResponse: any, paymentResponse: any) => void;
11
+ isBrowser: boolean;
12
+ }
13
+ export declare const usePaymentRedirect: ({ stripeRef, setError, setLoading, removeReferralKey, removeAdditionalConfigs, handleSubmit, isBrowser, }: UsePaymentRedirectProps) => void;
14
+ export {};
@@ -0,0 +1,18 @@
1
+ /// <reference types="react" />
2
+ import { FormikHelpers } from 'formik';
3
+ interface PaymentData {
4
+ attributes: any;
5
+ isFreeTickets: boolean;
6
+ updatedOrderData: any;
7
+ eventId: string;
8
+ }
9
+ interface UseStripePaymentProps {
10
+ stripeRef: any;
11
+ elementsRef: React.MutableRefObject<any>;
12
+ setError: (error: string | null) => void;
13
+ isBrowser: boolean;
14
+ }
15
+ export declare const useStripePayment: ({ stripeRef, elementsRef, setError, isBrowser, }: UseStripePaymentProps) => {
16
+ processPayment: (paymentDataResponse: any, values: any, formikHelpers: FormikHelpers<any>, checkoutResponse: any, checkoutUpdateResponse: any, paymentData: PaymentData) => Promise<null>;
17
+ };
18
+ export {};
@@ -1,9 +1,9 @@
1
- /// <reference types="react" />
2
1
  import './style.css';
3
2
  import { ThemeOptions } from '@mui/material';
4
3
  import { CSSProperties } from '@mui/styles';
5
4
  import { AxiosError } from 'axios';
6
5
  import { FormikHelpers, FormikValues } from 'formik';
6
+ import React from 'react';
7
7
  import { IBillingInfoData } from '../../types';
8
8
  import { IAddonContainterProps } from '../addonsContainer';
9
9
  import { IPaymentPage } from '../paymentContainer';
@@ -63,6 +63,7 @@ export interface IBillingInfoPage {
63
63
  addOnDataWithCustomFields?: any;
64
64
  isSinglePageCheckout?: boolean;
65
65
  paymentProps?: Partial<IPaymentPage>;
66
+ paymentSectionAddon?: React.ReactNode;
66
67
  }
67
68
  declare const WithCustomFieldsBillingInfoContainer: (props: any) => JSX.Element;
68
69
  export { WithCustomFieldsBillingInfoContainer as BillingInfoContainer };