tf-checkout-react 1.0.77 → 1.0.81

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 (39) hide show
  1. package/dist/api/index.d.ts +1 -0
  2. package/dist/components/billing-info-container/index.d.ts +1 -1
  3. package/dist/components/common/FormikPhoneNumberField.d.ts +1 -1
  4. package/dist/components/countdown/index.d.ts +11 -0
  5. package/dist/components/orderDetailsContainer/ticketsTable.d.ts +13 -1
  6. package/dist/components/paymentContainer/index.d.ts +5 -2
  7. package/dist/components/ticketsContainer/PromoCodeSection.d.ts +2 -1
  8. package/dist/components/ticketsContainer/index.d.ts +10 -1
  9. package/dist/components/waitingList/index.d.ts +1 -2
  10. package/dist/hooks/usePrevious.d.ts +1 -0
  11. package/dist/tf-checkout-react.cjs.development.js +458 -156
  12. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  13. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  14. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  15. package/dist/tf-checkout-react.esm.js +460 -158
  16. package/dist/tf-checkout-react.esm.js.map +1 -1
  17. package/dist/tf-checkout-styles.css +1 -1
  18. package/dist/utils/downloadPDF.d.ts +1 -0
  19. package/dist/utils/index.d.ts +1 -0
  20. package/package.json +2 -1
  21. package/src/api/index.ts +9 -0
  22. package/src/components/billing-info-container/index.tsx +19 -6
  23. package/src/components/common/CheckboxField.tsx +13 -9
  24. package/src/components/common/FormikPhoneNumberField.tsx +2 -1
  25. package/src/components/countdown/index.tsx +89 -0
  26. package/src/components/countdown/style.css +10 -0
  27. package/src/components/loginModal/index.tsx +2 -0
  28. package/src/components/orderDetailsContainer/ticketsTable.tsx +66 -60
  29. package/src/components/paymentContainer/index.tsx +6 -3
  30. package/src/components/stripePayment/index.tsx +3 -3
  31. package/src/components/ticketsContainer/PromoCodeSection.tsx +46 -32
  32. package/src/components/ticketsContainer/TicketsSection.tsx +10 -6
  33. package/src/components/ticketsContainer/index.tsx +191 -70
  34. package/src/components/ticketsContainer/style.css +7 -0
  35. package/src/components/waitingList/index.tsx +3 -9
  36. package/src/components/waitingList/style.css +4 -2
  37. package/src/hooks/usePrevious.tsx +9 -0
  38. package/src/utils/downloadPDF.tsx +30 -0
  39. package/src/utils/index.ts +2 -1
@@ -9,7 +9,7 @@ export interface IPromoCodeSectionProps {
9
9
  showPromoInput: boolean;
10
10
  isPromotionsEnabled: boolean;
11
11
  isAllTicketsSoldOut: boolean;
12
-
12
+ isAccessCodeEnabled?: boolean;
13
13
  setPromoCode: (value: string) => void;
14
14
  setPromoCodeUpdated: (value: string) => void;
15
15
  setShowPromoInput: (value: boolean) => void;
@@ -20,11 +20,49 @@ export const PromoCodeSection = ({
20
20
  promoCodeIsApplied,
21
21
  showPromoInput,
22
22
  isPromotionsEnabled,
23
- isAllTicketsSoldOut,
24
23
  setPromoCode,
25
24
  setPromoCodeUpdated,
26
25
  setShowPromoInput,
26
+ isAccessCodeEnabled,
27
27
  }: IPromoCodeSectionProps) => {
28
+ const isPromoCodeHasValue = !!promoCode.trim()
29
+
30
+ const renderInputField = () => {
31
+ return (
32
+ <div className="promo-code-block">
33
+ <div className="promo-code-block">
34
+ <p className="promo-code-text">
35
+ { isAccessCodeEnabled ? 'Access code required' : 'Promo code'}
36
+ </p>
37
+
38
+ </div>
39
+ <input
40
+ className="promo-code-input"
41
+ placeholder=""
42
+ onChange={e => {
43
+ setPromoCode(e.target.value)
44
+ }}
45
+ onKeyPress={event => {
46
+ if (event.key === 'Enter' && isPromoCodeHasValue) {
47
+ setPromoCodeUpdated(promoCode)
48
+ setShowPromoInput(false)
49
+ }
50
+ }}
51
+ />
52
+ <Button
53
+ className="promo-submit-button"
54
+ onClick={() => {
55
+ if (isPromoCodeHasValue) {
56
+ setPromoCodeUpdated(promoCode)
57
+ setShowPromoInput(false)
58
+ }
59
+ }}
60
+ >
61
+ {isAccessCodeEnabled ? 'ENTER' : 'APPLY'}
62
+ </Button>
63
+ </div>
64
+ )
65
+ }
28
66
 
29
67
  return (
30
68
  <div >
@@ -34,39 +72,13 @@ export const PromoCodeSection = ({
34
72
  src={getImage('done.svg')}
35
73
  preProcessor={(code) => code.replace(/fill=".*?"/g, 'fill="currentColor"')}
36
74
  />
37
- <p>PROMO CODE APPLIED SUCCESSFULLY</p>
75
+ <p className="promo-code-success">PROMO CODE APPLIED SUCCESSFULLY</p>
38
76
  </div>
39
77
  ) : null}
40
78
  {showPromoInput && (
41
- <div className="promo-code-block">
42
- <input
43
- placeholder="Promo Code"
44
- onChange={e => {
45
- setPromoCode(e.target.value)
46
- }}
47
- onKeyPress={event => {
48
- if (event.key === 'Enter') {
49
- setPromoCodeUpdated(promoCode)
50
- }
51
- }}
52
- />
53
- <Button
54
- className="promo-apply-button"
55
- placeholder="Promo Code"
56
- onClick={() => {
57
- setPromoCodeUpdated(promoCode)
58
- }}
59
- >
60
- Apply
61
- </Button>
62
- </div>
79
+ renderInputField()
63
80
  )}
64
- {isPromotionsEnabled && !showPromoInput && isAllTicketsSoldOut && (
65
- <p className="promo-code-text">
66
- Access code needed
67
- </p>
68
- )}
69
- {isPromotionsEnabled && !showPromoInput ? (
81
+ {isPromotionsEnabled && !showPromoInput && !isAccessCodeEnabled ? (
70
82
  <Button
71
83
  className="promo-code-button"
72
84
  placeholder="Promo Codes"
@@ -76,7 +88,9 @@ export const PromoCodeSection = ({
76
88
  >
77
89
  Got a promo code? Click here
78
90
  </Button>
79
- ) : null}
91
+ ) : !isPromotionsEnabled && !showPromoInput && isAccessCodeEnabled && !promoCodeIsApplied ? renderInputField() :
92
+ null
93
+ }
80
94
  </div>
81
95
  )
82
96
  }
@@ -66,12 +66,16 @@ export const TicketsSection = ({
66
66
  className="event-detail__tier-state"
67
67
  style={{ minWidth: 55 }}
68
68
  >
69
- <TicketRow
70
- ticketTier={ticket}
71
- prevTicketTier={arr[i - 1]}
72
- selectedTickets={selectedTickets}
73
- handleTicketSelect={ticketSelect}
74
- />
69
+ {ticket.salesStarted ? (
70
+ <TicketRow
71
+ ticketTier={ticket}
72
+ prevTicketTier={arr[i - 1]}
73
+ selectedTickets={selectedTickets}
74
+ handleTicketSelect={ticketSelect}
75
+ />
76
+ ) : (
77
+ <p className='ticket-not-started-message'>Sales not started</p>
78
+ )}
75
79
  </div>
76
80
  </div>
77
81
  </div>
@@ -4,6 +4,7 @@ import './style.css'
4
4
 
5
5
  import {
6
6
  getTickets,
7
+ getEvent,
7
8
  addToCart,
8
9
  setCustomHeader,
9
10
  postOnCheckout,
@@ -18,7 +19,12 @@ import jwt_decode from 'jwt-decode'
18
19
  import { TicketsSection } from './TicketsSection'
19
20
  import WaitingList from '../waitingList'
20
21
  import { PromoCodeSection } from './PromoCodeSection'
22
+ import { LoginModal } from '../loginModal'
23
+ import Countdown from '../countdown'
21
24
  import { createCheckoutDataBodyWithDefaultHolder } from '../../utils'
25
+ import { ThemeProvider } from '@mui/private-theming'
26
+ import { createTheme, ThemeOptions } from '@mui/material'
27
+ import { CSSProperties } from '@mui/styles'
22
28
 
23
29
  function Loader() {
24
30
  return (
@@ -44,10 +50,14 @@ export interface IGetTickets {
44
50
  onAddToCartError: (e: AxiosError) => void;
45
51
  onGetTicketsSuccess: (response: any) => void;
46
52
  onGetTicketsError: (e: AxiosError) => void;
53
+ onLoginSuccess: () => void;
47
54
 
48
55
  theme?: 'light' | 'dark';
49
56
  queryPromoCode?: string;
50
57
  isPromotionsEnabled?: boolean;
58
+ themeOptions?: ThemeOptions & { input?: CSSProperties; checkbox?: CSSProperties }
59
+ isAccessCodeEnabled?: boolean;
60
+ hideSessionButtons?: boolean;
51
61
  }
52
62
 
53
63
  export interface ITicket {
@@ -60,6 +70,7 @@ export interface ISelectedTickets {
60
70
  }
61
71
 
62
72
  export const TicketsContainer = ({
73
+ onLoginSuccess,
63
74
  getTicketsLabel,
64
75
  eventId,
65
76
  onAddToCartSuccess,
@@ -70,11 +81,20 @@ export const TicketsContainer = ({
70
81
  theme = 'light',
71
82
  queryPromoCode = '',
72
83
  isPromotionsEnabled = true,
84
+ themeOptions,
85
+ isAccessCodeEnabled = false,
86
+ hideSessionButtons = false
73
87
  }: IGetTickets) => {
74
88
  const [selectedTickets, setSelectedTickets] = useState(
75
89
  {} as ISelectedTickets
76
90
  )
91
+ const isWindowDefined = typeof window !== 'undefined'
92
+ const [isLogged, setIsLogged] = useState(
93
+ isWindowDefined ? !!window.localStorage.getItem('access_token') : false
94
+ )
95
+ const [showLoginModal, setShowLoginModal] = React.useState(false)
77
96
  const [tickets, setTickets] = useState([] as ITicket[])
97
+ const [event, setEvent] = useState<any>(null)
78
98
  const [showWaitingList, setShowWaitingList] = useState(false)
79
99
  const [isLoading, setIsLoading] = useState(false)
80
100
  const [handleBookIsLoading, setHandleBookIsLoading] = useState(false)
@@ -97,29 +117,60 @@ export const TicketsContainer = ({
97
117
  }, [])
98
118
 
99
119
  useEffect(() => {
100
- async function getTicketsApi() {
101
- try {
102
- setIsLoading(true)
103
- const response = await getTickets(eventId, promoCodeUpdated)
104
- if (response.data.success) {
105
- setCustomHeader(response)
106
- const attributes = _get(response, 'data.data.attributes')
107
- setPromoCodeIsApplied(attributes.ValidPromoCode)
108
- setTickets(_get(attributes, 'tickets'))
109
- setShowWaitingList(attributes.showWaitingList)
110
- onGetTicketsSuccess(response.data)
111
- }
112
- } catch (e) {
113
- if (axios.isAxiosError(e)) {
114
- onGetTicketsError(e)
115
- }
116
- } finally {
117
- setIsLoading(false)
118
- }
119
- }
120
120
  getTicketsApi()
121
121
  }, [eventId, promoCodeUpdated])
122
122
 
123
+ const handleLogout = () => {
124
+ if (isWindowDefined) {
125
+ window.localStorage.removeItem('access_token')
126
+ window.localStorage.removeItem('user_data')
127
+ setIsLogged(false)
128
+ const event = new window.CustomEvent('tf-logout')
129
+ window.document.dispatchEvent(event)
130
+ }
131
+ }
132
+
133
+ const handleExternalLogin = () => {
134
+ setIsLogged(true)
135
+ }
136
+ const handleOnClose = () => {
137
+ setShowLoginModal(false)
138
+ }
139
+ const handleOnLogin = () => {
140
+ setShowLoginModal(false)
141
+ setIsLogged(true)
142
+ if (onLoginSuccess) {
143
+ onLoginSuccess()
144
+ }
145
+ }
146
+
147
+ async function getTicketsApi() {
148
+ try {
149
+ setIsLoading(true)
150
+ const response = await getTickets(eventId, promoCodeUpdated)
151
+ const eventResponse = await getEvent(eventId)
152
+ if (response.data.success) {
153
+ setCustomHeader(response)
154
+ const attributes = _get(response, 'data.data.attributes')
155
+ setPromoCodeIsApplied(attributes.ValidPromoCode)
156
+ setTickets(_get(attributes, 'tickets'))
157
+ setShowWaitingList(attributes.showWaitingList)
158
+ onGetTicketsSuccess(response.data)
159
+ setPromoCode('')
160
+ }
161
+ if (eventResponse.data.success) {
162
+ const event = _get(eventResponse, 'data.data.attributes')
163
+ setEvent(event)
164
+ }
165
+ } catch (e) {
166
+ if (axios.isAxiosError(e)) {
167
+ onGetTicketsError(e)
168
+ }
169
+ } finally {
170
+ setIsLoading(false)
171
+ }
172
+ }
173
+
123
174
  const handleTicketSelect = (key: string, value: number | string) => {
124
175
  setSelectedTickets(prevState => {
125
176
  if (Object.keys(prevState)[0] !== key && !value) {
@@ -131,6 +182,12 @@ export const TicketsContainer = ({
131
182
  })
132
183
  }
133
184
 
185
+ const handleOrdersClick = () => {
186
+ if (isWindowDefined) {
187
+ window.location.href = '/orders'
188
+ }
189
+ }
190
+
134
191
  const handleBook = async () => {
135
192
  setHandleBookIsLoading(true)
136
193
  const ticket =
@@ -218,63 +275,127 @@ export const TicketsContainer = ({
218
275
  }
219
276
  }
220
277
 
278
+ const updateTickets = () => {
279
+ getTicketsApi()
280
+ }
281
+
221
282
  const isAllTicketsSoldOut = !_some(
222
283
  tickets,
223
284
  item => !(item.sold_out || item.soldOut)
224
285
  )
225
286
 
287
+ const themeMui = createTheme(themeOptions)
288
+
289
+ useEffect(() => {
290
+ isWindowDefined &&
291
+ window.document.addEventListener('custom-logout', handleLogout)
292
+ return () => {
293
+ isWindowDefined &&
294
+ window.document.removeEventListener('custom-logout', handleLogout)
295
+ }
296
+ }, [])
297
+
298
+ useEffect(() => {
299
+ isWindowDefined &&
300
+ window.document.addEventListener('custom-login', handleExternalLogin)
301
+ return () => {
302
+ isWindowDefined &&
303
+ window.document.removeEventListener(
304
+ 'custom-login',
305
+ handleExternalLogin
306
+ )
307
+ }
308
+ }, [])
309
+
226
310
  return (
227
- <div className={`get-tickets-page ${theme}`} style={contentStyle}>
228
- {isLoading ? (
229
- <Loader />
230
- ) : (
231
- <div>
232
- <TicketsSection
233
- ticketsList={tickets}
234
- selectedTickets={selectedTickets}
235
- handleTicketSelect={handleTicketSelect}
236
- promoCodeIsApplied={promoCodeIsApplied}
237
- />
238
- {showWaitingList && (
239
- <WaitingList
240
- tickets={tickets}
241
- eventId={eventId}
311
+ <ThemeProvider theme={themeMui}>
312
+ <div className={`get-tickets-page ${theme}`} style={contentStyle}>
313
+ {isLoading ? (
314
+ <Loader />
315
+ ) : (
316
+ <div>
317
+ <TicketsSection
318
+ ticketsList={tickets}
319
+ selectedTickets={selectedTickets}
320
+ handleTicketSelect={handleTicketSelect}
321
+ promoCodeIsApplied={promoCodeIsApplied}
322
+ />
323
+ {event?.salesEnded ? (
324
+ <p>Sales for this event are closed.</p>
325
+ ) : event?.salesStart ? (
326
+ <Countdown
327
+ startDate={event.salesStart}
328
+ timezone={event.timezone}
329
+ title="Sales start in:"
330
+ message="No tickets are currently available for this event."
331
+ callback={updateTickets}
332
+ />
333
+ ) : null}
334
+ {showWaitingList && event.salesStarted && (
335
+ <WaitingList tickets={tickets} eventId={eventId} />
336
+ )}
337
+ <PromoCodeSection
338
+ promoCode={promoCode}
339
+ promoCodeIsApplied={promoCodeIsApplied}
340
+ showPromoInput={showPromoInput}
341
+ setPromoCode={setPromoCode}
342
+ setPromoCodeUpdated={setPromoCodeUpdated}
343
+ setShowPromoInput={setShowPromoInput}
242
344
  isPromotionsEnabled={isPromotionsEnabled}
345
+ isAccessCodeEnabled={isAccessCodeEnabled}
346
+ isAllTicketsSoldOut={isAllTicketsSoldOut}
243
347
  />
244
- )}
245
- <PromoCodeSection
246
- promoCode={promoCode}
247
- promoCodeIsApplied={promoCodeIsApplied}
248
- showPromoInput={showPromoInput}
249
- setPromoCode={setPromoCode}
250
- setPromoCodeUpdated={setPromoCodeUpdated}
251
- setShowPromoInput={setShowPromoInput}
252
- isPromotionsEnabled={isPromotionsEnabled}
253
- isAllTicketsSoldOut={isAllTicketsSoldOut}
254
- />
255
- {!isAllTicketsSoldOut && (
256
- <Button
257
- aria-hidden={true}
258
- className={`book-button ${
259
- handleBookIsLoading ||
260
- _isEmpty(selectedTickets) ||
261
- Object.values(selectedTickets)[0] === 0
262
- ? 'disabled'
263
- : ''
264
- }`}
265
- onClick={
266
- !handleBookIsLoading &&
267
- !_isEmpty(selectedTickets) &&
268
- Object.values(selectedTickets)[0] > 0
269
- ? handleBook
270
- : () => {}
271
- }
272
- >
273
- {getTicketsLabel || 'GET TICKETS'}
274
- </Button>
275
- )}
276
- </div>
277
- )}
278
- </div>
348
+ {!isAllTicketsSoldOut && (
349
+ <Button
350
+ aria-hidden={true}
351
+ className={`book-button ${
352
+ handleBookIsLoading ||
353
+ _isEmpty(selectedTickets) ||
354
+ Object.values(selectedTickets)[0] === 0
355
+ ? 'disabled'
356
+ : ''
357
+ }`}
358
+ onClick={
359
+ !handleBookIsLoading &&
360
+ !_isEmpty(selectedTickets) &&
361
+ Object.values(selectedTickets)[0] > 0
362
+ ? handleBook
363
+ : () => {}
364
+ }
365
+ >
366
+ {getTicketsLabel || 'GET TICKETS'}
367
+ </Button>
368
+ )}
369
+ {isLogged && !hideSessionButtons ? (
370
+ <div className="session-wrapper">
371
+ <span className="session-container">
372
+ <Button
373
+ variant="outline-light"
374
+ className="session-buttons"
375
+ onClick={handleOrdersClick}
376
+ >
377
+ My Orders
378
+ </Button>
379
+ </span>
380
+ <span className="session-container">
381
+ <Button
382
+ variant="outline-light"
383
+ className="session-buttons"
384
+ onClick={handleLogout}
385
+ >
386
+ Log out
387
+ </Button>
388
+ </span>
389
+ </div>
390
+ ) : (
391
+ ''
392
+ )}
393
+ </div>
394
+ )}
395
+ {showLoginModal ? (
396
+ <LoginModal onClose={handleOnClose} onLogin={handleOnLogin} />
397
+ ) : null}
398
+ </div>
399
+ </ThemeProvider>
279
400
  )
280
401
  }
@@ -108,6 +108,13 @@ body {
108
108
  text-transform: uppercase;
109
109
  }
110
110
 
111
+ .event-detail__tier-state .ticket-not-started-message {
112
+ color: #000000;
113
+ text-transform: initial;
114
+ width: 50px;
115
+ text-align: left;
116
+ }
117
+
111
118
  .promo-code-block input {
112
119
  font-size: 14px;
113
120
  padding: 1px 8px;
@@ -16,7 +16,6 @@ import './style.css'
16
16
  interface WaitingListProps {
17
17
  tickets: any;
18
18
  eventId: number;
19
- isPromotionsEnabled: boolean;
20
19
  }
21
20
 
22
21
  interface WaitingListFields {
@@ -35,7 +34,7 @@ const generateQuantity = (n: number) => {
35
34
  return quantityList
36
35
  }
37
36
 
38
- const WaitingList = ({ tickets = {}, eventId, isPromotionsEnabled }: WaitingListProps) => {
37
+ const WaitingList = ({ tickets = {}, eventId }: WaitingListProps) => {
39
38
  const [showSuccessMessage, setShowSuccessMessage] = useState(false)
40
39
  const [loading, setLoading] = useState(false)
41
40
  const ticketTypesList = Object.values(tickets).map((d: any) => ({
@@ -68,16 +67,11 @@ const WaitingList = ({ tickets = {}, eventId, isPromotionsEnabled }: WaitingList
68
67
  <div className="waiting-list">
69
68
  {showSuccessMessage ? (
70
69
  <div className="success-message">
71
- <p className="added-success-message">{`You've been added to the waiting list!`}</p>
72
- <p>{`You'll be notified if tickets become available.`}</p>
70
+ <p className="added-success-message">You've been added to the waiting list!</p>
71
+ <p>You'll be notified if tickets become available.</p>
73
72
  </div>
74
73
  ) : (
75
74
  <>
76
- {!isPromotionsEnabled && (
77
- <p className="no-tickets-text">
78
- No tickets are currently available for this event.
79
- </p>
80
- )}
81
75
  <h2>WAITING LIST</h2>
82
76
  <Formik
83
77
  initialValues={{
@@ -10,8 +10,9 @@
10
10
  .waiting-list .waiting-list-button:hover {
11
11
  background-color: #505050;
12
12
  }
13
- .waiting-list .success-message h3 {
14
- margin: 10px 0;
13
+ .waiting-list .success-message {
14
+ text-align: center;
15
+ margin-bottom: 15px;
15
16
  }
16
17
  .waiting-list .success-message p {
17
18
  margin: 0;
@@ -22,4 +23,5 @@
22
23
  }
23
24
  .waiting-list .added-success-message {
24
25
  font-size: 22px;
26
+ margin-bottom: 10px;
25
27
  }
@@ -0,0 +1,9 @@
1
+ import { useEffect, useRef } from "react"
2
+
3
+ export const usePrevious = <T extends unknown>(value: T): T | undefined => {
4
+ const ref = useRef<T>()
5
+ useEffect(() => {
6
+ ref.current = value
7
+ })
8
+ return ref.current
9
+ }
@@ -0,0 +1,30 @@
1
+ export const downloadPDF = (pdfUrl: string) => {
2
+ if (typeof window === 'undefined') return
3
+
4
+ const accessToken: string | null = localStorage.getItem('access_token')
5
+
6
+ if (!accessToken) return
7
+
8
+ fetch(pdfUrl, {
9
+ headers: {
10
+ Authorization: `Bearer ${accessToken}`,
11
+ },
12
+ })
13
+ .then(async response => {
14
+ const blobValue = await response.blob()
15
+ const fileNameHeader = response.headers.get("content-disposition") || ''
16
+ const fileName = fileNameHeader.split('"')[1]
17
+ return { blobValue, fileName }
18
+ })
19
+ .then(({ blobValue, fileName }) => {
20
+ if (!fileName) return
21
+ const file = new Blob([blobValue], { type: 'application/pdf' })
22
+ const fileURL = URL.createObjectURL(file)
23
+ const link = document.createElement('a')
24
+ link.href = fileURL
25
+ link.setAttribute('download', fileName)
26
+ document.body.appendChild(link)
27
+ link.click()
28
+ document.body.removeChild(link)
29
+ })
30
+ }
@@ -1,4 +1,5 @@
1
1
  export { setConfigs, CONFIGS } from './setConfigs'
2
2
  export { getQueryVariable } from './getQueryVariable'
3
3
  export { ErrorFocus } from './formikErrorFocus'
4
- export { createCheckoutDataBodyWithDefaultHolder } from './createCheckoutDataBodyWithDefaultHolder'
4
+ export { downloadPDF } from './downloadPDF'
5
+ export { createCheckoutDataBodyWithDefaultHolder } from './createCheckoutDataBodyWithDefaultHolder'