tf-checkout-react 1.6.6 → 1.7.2

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 (137) hide show
  1. package/README.md +401 -59
  2. package/dist/adapters/customFields.d.ts +1 -0
  3. package/dist/api/checkout.d.ts +2 -0
  4. package/dist/api/common.d.ts +1 -0
  5. package/dist/api/index.d.ts +2 -0
  6. package/dist/api/preRegistrationComplete.d.ts +1 -1
  7. package/dist/components/addonsContainer/AddonComponent.d.ts +6 -1
  8. package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +17 -0
  9. package/dist/components/addonsContainer/index.d.ts +6 -1
  10. package/dist/components/billing-info-container/hooks/index.d.ts +3 -0
  11. package/dist/components/billing-info-container/hooks/usePaymentContext.d.ts +5 -0
  12. package/dist/components/billing-info-container/hooks/usePaymentRedirect.d.ts +14 -0
  13. package/dist/components/billing-info-container/hooks/useStripePayment.d.ts +18 -0
  14. package/dist/components/billing-info-container/index.d.ts +13 -2
  15. package/dist/components/billing-info-container/utils.d.ts +26 -1
  16. package/dist/components/common/DatePickerField.d.ts +7 -1
  17. package/dist/components/common/PhoneNumberField.d.ts +1 -1
  18. package/dist/components/confirmationContainer/index.d.ts +4 -1
  19. package/dist/components/countdown/index.d.ts +1 -1
  20. package/dist/components/forgotPasswordModal/index.d.ts +2 -1
  21. package/dist/components/myTicketsContainer/index.d.ts +3 -2
  22. package/dist/components/orderDetailsContainer/index.d.ts +8 -1
  23. package/dist/components/paymentContainer/OrderDetails.d.ts +9 -0
  24. package/dist/components/paymentContainer/handlePayment.d.ts +15 -0
  25. package/dist/components/paymentContainer/index.d.ts +12 -6
  26. package/dist/components/preRegistration/FieldsSection.d.ts +7 -1
  27. package/dist/components/preRegistration/PreRegistrationComplete.d.ts +8 -0
  28. package/dist/components/preRegistration/constants.d.ts +2 -2
  29. package/dist/components/preRegistration/index.d.ts +6 -0
  30. package/dist/components/resetPasswordContainer/index.d.ts +2 -2
  31. package/dist/components/ticketsContainer/InfoIcon.d.ts +5 -0
  32. package/dist/components/ticketsContainer/TicketsSection.d.ts +3 -2
  33. package/dist/components/ticketsContainer/TimeSlotsSection.d.ts +25 -0
  34. package/dist/components/ticketsContainer/index.d.ts +29 -5
  35. package/dist/components/timerWidget/index.d.ts +2 -1
  36. package/dist/constants/index.d.ts +5 -0
  37. package/dist/index.d.ts +4 -1
  38. package/dist/tf-checkout-react.cjs.development.js +11284 -9565
  39. package/dist/tf-checkout-react.cjs.development.js.map +1 -1
  40. package/dist/tf-checkout-react.cjs.production.min.js +1 -1
  41. package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
  42. package/dist/tf-checkout-react.esm.js +11293 -9577
  43. package/dist/tf-checkout-react.esm.js.map +1 -1
  44. package/dist/tf-checkout-styles.css +1 -1
  45. package/dist/types/add_on.d.ts +1 -0
  46. package/dist/types/checkoutPageConfigs.d.ts +1 -1
  47. package/dist/types/order-data.d.ts +3 -1
  48. package/dist/utils/auth.d.ts +8 -0
  49. package/dist/utils/createCheckoutDataBodyWithDefaultHolder.d.ts +1 -0
  50. package/dist/utils/customFields.d.ts +11 -0
  51. package/dist/utils/getDomain.d.ts +1 -1
  52. package/dist/utils/index.d.ts +1 -1
  53. package/dist/utils/setConfigs.d.ts +1 -0
  54. package/package.json +14 -8
  55. package/src/adapters/customFields.ts +7 -1
  56. package/src/api/auth.ts +2 -1
  57. package/src/api/checkout.ts +9 -4
  58. package/src/api/common.ts +49 -2
  59. package/src/api/index.ts +1 -0
  60. package/src/api/interceptors.ts +7 -23
  61. package/src/api/preRegistrationComplete.ts +1 -1
  62. package/src/api/publicRequest.ts +10 -0
  63. package/src/components/addonsContainer/AddonComponent.tsx +96 -11
  64. package/src/components/addonsContainer/SimpleAddonsContainer.tsx +420 -0
  65. package/src/components/addonsContainer/index.tsx +198 -47
  66. package/src/components/billing-info-container/hooks/index.ts +3 -0
  67. package/src/components/billing-info-container/hooks/usePaymentContext.ts +22 -0
  68. package/src/components/billing-info-container/hooks/usePaymentRedirect.ts +147 -0
  69. package/src/components/billing-info-container/hooks/useStripePayment.ts +121 -0
  70. package/src/components/billing-info-container/index.tsx +859 -418
  71. package/src/components/billing-info-container/{utils.ts → utils.tsx} +124 -1
  72. package/src/components/common/CheckboxField/index.tsx +1 -1
  73. package/src/components/common/CustomField.tsx +39 -3
  74. package/src/components/common/DatePickerField.tsx +25 -10
  75. package/src/components/common/PhoneNumberField.tsx +4 -2
  76. package/src/components/common/SnackbarAlert.tsx +32 -34
  77. package/src/components/confirmationContainer/config.ts +3 -3
  78. package/src/components/confirmationContainer/index.tsx +20 -1
  79. package/src/components/confirmationContainer/social-buttons.tsx +5 -3
  80. package/src/components/confirmationContainer/style.css +9 -5
  81. package/src/components/countdown/index.tsx +22 -22
  82. package/src/components/delegationsContainer/IssueComponent.tsx +2 -1
  83. package/src/components/forgotPasswordModal/index.tsx +44 -13
  84. package/src/components/loginForm/index.tsx +1 -1
  85. package/src/components/loginModal/index.tsx +19 -27
  86. package/src/components/loginModal/style.css +3 -1
  87. package/src/components/myTicketsContainer/index.tsx +13 -9
  88. package/src/components/orderDetailsContainer/index.tsx +206 -174
  89. package/src/components/paymentContainer/OrderDetails.tsx +257 -0
  90. package/src/components/paymentContainer/handlePayment.ts +86 -0
  91. package/src/components/paymentContainer/index.tsx +299 -259
  92. package/src/components/paymentContainer/style.css +141 -0
  93. package/src/components/preRegistration/FieldsSection.tsx +8 -0
  94. package/src/components/preRegistration/PreRegistrationComplete.tsx +138 -118
  95. package/src/components/preRegistration/PreRegistrationInformations.tsx +21 -15
  96. package/src/components/preRegistration/constants.tsx +10 -4
  97. package/src/components/preRegistration/index.tsx +233 -179
  98. package/src/components/preRegistration/style.css +3 -0
  99. package/src/components/registerForm/constants.tsx +3 -1
  100. package/src/components/registerForm/index.tsx +3 -3
  101. package/src/components/registerModal/index.tsx +47 -72
  102. package/src/components/resetPasswordContainer/index.tsx +20 -14
  103. package/src/components/seatMapContainer/TicketsSection.tsx +2 -2
  104. package/src/components/signupModal/index.tsx +13 -6
  105. package/src/components/ticketResale/index.tsx +7 -0
  106. package/src/components/ticketsContainer/InfoIcon.tsx +35 -0
  107. package/src/components/ticketsContainer/PromoCodeSection.tsx +34 -28
  108. package/src/components/ticketsContainer/TicketRow.tsx +1 -1
  109. package/src/components/ticketsContainer/TicketsSection.tsx +189 -57
  110. package/src/components/ticketsContainer/TimeSlotsSection.tsx +120 -0
  111. package/src/components/ticketsContainer/index.tsx +268 -106
  112. package/src/components/timerWidget/index.tsx +15 -3
  113. package/src/components/timerWidget/style.css +2 -1
  114. package/src/constants/index.ts +2 -0
  115. package/src/env.ts +14 -6
  116. package/src/hoc/CustomFields/index.tsx +9 -1
  117. package/src/index.ts +7 -2
  118. package/src/types/add_on.ts +1 -0
  119. package/src/types/api/cart.d.ts +8 -0
  120. package/src/types/api/checkout.d.ts +58 -7
  121. package/src/types/api/common.d.ts +30 -0
  122. package/src/types/api/orders.d.ts +19 -3
  123. package/src/types/api/payment.d.ts +6 -2
  124. package/src/types/api/preRegistrationComplete.d.ts +2 -2
  125. package/src/types/checkoutPageConfigs.ts +1 -1
  126. package/src/types/order-data.ts +3 -1
  127. package/src/types/pre-registration-complete.d.ts +6 -1
  128. package/src/utils/auth.ts +32 -0
  129. package/src/utils/cookies.ts +42 -11
  130. package/src/utils/createCheckoutDataBodyWithDefaultHolder.ts +3 -1
  131. package/src/utils/customFields.ts +22 -0
  132. package/src/utils/getDomain.ts +10 -4
  133. package/src/utils/index.ts +1 -1
  134. package/src/utils/setConfigs.ts +3 -1
  135. package/dist/components/stripePayment/index.d.ts +0 -24
  136. package/src/components/stripePayment/index.tsx +0 -281
  137. package/src/components/stripePayment/style.css +0 -60
@@ -1,17 +1,20 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  import './style.css'
2
3
 
3
- import { createTheme, ThemeOptions } from '@mui/material'
4
+ import { ThemeOptions } from '@mui/material'
4
5
  import Alert from '@mui/material/Alert'
5
- import { ThemeProvider } from '@mui/private-theming'
6
+ import { createTheme, ThemeProvider } from '@mui/material/styles'
6
7
  import { CSSProperties } from '@mui/styles'
7
8
  import axios, { AxiosError } from 'axios'
8
9
  import _filter from 'lodash/filter'
9
10
  import _find from 'lodash/find'
11
+ import _flatten from 'lodash/flatten'
10
12
  import _forEach from 'lodash/forEach'
11
13
  import _get from 'lodash/get'
12
14
  import _identity from 'lodash/identity'
13
15
  import _includes from 'lodash/includes'
14
16
  import _isEmpty from 'lodash/isEmpty'
17
+ import _map from 'lodash/map'
15
18
  import _some from 'lodash/some'
16
19
  import moment from 'moment-timezone'
17
20
  import React, { ReactNode, useEffect, useRef, useState } from 'react'
@@ -23,22 +26,22 @@ import {
23
26
  getEvent,
24
27
  getProfileData,
25
28
  getTickets,
26
- logout,
27
29
  postOnCheckout,
28
30
  } from '../../api'
29
- import { getPreRegistrationInfluancers } from '../../api/preRegistrationComplete'
31
+ import { getTimeSlotsByDate } from '../../api/common'
32
+ import { getPreRegistrationInfluencers } from '../../api/preRegistrationComplete'
30
33
  import { X_TF_ECOMMERCE } from '../../constants'
31
34
  import { useCookieListener } from '../../hooks/useCookieListener'
32
35
  import { useLocalStorageListener } from '../../hooks/useLocalStorageListener'
33
36
  import { usePixel } from '../../hooks/usePixel'
34
37
  import {
35
38
  createCheckoutDataBodyWithDefaultHolder,
36
- deleteCookieByName,
37
39
  getCookieByName,
38
40
  getQueryVariable,
39
41
  isBrowser,
40
42
  setLoggedUserData,
41
43
  } from '../../utils'
44
+ import { logoutUser } from '../../utils/auth'
42
45
  import { Loader } from '../common/index'
43
46
  import { PoweredBy } from '../common/PoweredBy'
44
47
  import ConfirmModal from '../confirmModal'
@@ -46,10 +49,29 @@ import Countdown from '../countdown'
46
49
  import { VerificationPendingModal } from '../idVerificationContainer/VerificationPendingModal'
47
50
  import { LoginModal } from '../loginModal'
48
51
  import WaitingList from '../waitingList'
52
+ import { PreRegistration } from '../preRegistration'
49
53
  import { AccessCodeSection } from './AccessCodeSection'
50
54
  import { PromoCodeSection } from './PromoCodeSection'
51
55
  import { ReferralLogic } from './ReferralLogic'
52
56
  import { TicketsSection } from './TicketsSection'
57
+ import TimeSlotsSection from './TimeSlotsSection'
58
+
59
+ const checkUserPreregistration = (preregisteredUsers: IInfluencerData[]) => {
60
+ const isWindowDefined = typeof window !== 'undefined'
61
+ const userDataString = isWindowDefined ? window.localStorage.getItem('user_data') : ''
62
+ let isPreregisteredUser = false
63
+ if (userDataString) {
64
+ const user = JSON.parse(userDataString)
65
+ isPreregisteredUser = _some(preregisteredUsers, item => item.email === user?.email)
66
+ }
67
+ return isPreregisteredUser
68
+ }
69
+
70
+ interface TimeSlotsAttributes {
71
+ ValidPromoCode: boolean;
72
+ is_access_code: boolean;
73
+ isPromotionsEnabled: boolean;
74
+ }
53
75
 
54
76
  interface CartSuccess {
55
77
  skip_billing_page: boolean;
@@ -57,6 +79,9 @@ interface CartSuccess {
57
79
  hash?: string | number;
58
80
  total?: string | number;
59
81
  hasAddOn?: boolean;
82
+ eventSlug?: string;
83
+ cart?: ICart[];
84
+ currencySymbol?: string;
60
85
  }
61
86
 
62
87
  export interface IGetTickets {
@@ -65,12 +90,16 @@ export interface IGetTickets {
65
90
  getTicketsLabel?: string;
66
91
  contentStyle?: React.CSSProperties;
67
92
  onAddToCartError: (e: AxiosError) => void;
68
- onGetTicketsSuccess: (response: any) => void;
93
+ onGetTicketsSuccess: (response: {
94
+ data: { attributes: { tickets: ITicketData[] } };
95
+ }) => void;
69
96
  onGetTicketsPress: () => void;
70
97
  onGetTicketsError: (e: AxiosError) => void;
71
98
  onLogoutSuccess: () => void;
72
99
  onLogoutError: (e: AxiosError) => void;
73
- onGetProfileDataSuccess: (response: any) => void;
100
+ onGetProfileDataSuccess: (response: {
101
+ data: { attributes: { [key: string]: string | number | boolean | null } };
102
+ }) => void;
74
103
  onGetProfileDataError: (e: AxiosError) => void;
75
104
  onLoginSuccess: () => void;
76
105
  handleNotInvitedModalClose: () => void;
@@ -90,7 +119,7 @@ export interface IGetTickets {
90
119
  sortBySoldOut?: boolean;
91
120
  disableCountdownLeadingZero?: boolean;
92
121
  isLoggedIn?: boolean;
93
- actionsSectionComponent?: any;
122
+ actionsSectionComponent?: ReactNode;
94
123
  ticketsHeaderComponent?: ReactNode;
95
124
  hideTicketsHeader?: boolean;
96
125
  tableTicketsHeaderComponent?: ReactNode;
@@ -101,10 +130,19 @@ export interface IGetTickets {
101
130
  showPoweredByImage?: boolean;
102
131
  promoText?: string;
103
132
  showGroupNameBlock?: boolean;
104
- currencySybmol?: string;
133
+ currencySymbol?: string;
105
134
  onReserveButtonClick?: () => void;
106
135
  onPendingVerification?: () => void;
107
136
  showAlertIcons?: boolean;
137
+ submitMode?: 'auto' | 'click';
138
+ onPreRegistrationSuccess?: (response: any) => void;
139
+ onPreRegistrationError?: (e: AxiosError) => void;
140
+ onPreRegistrationGetCountriesSuccess?: (res: any) => void;
141
+ onPreRegistrationGetCountriesError?: (e: AxiosError) => void;
142
+ onForgotPasswordSuccess?: (res: any) => void;
143
+ onForgotPasswordError?: (e: AxiosError) => void;
144
+ showForgotPasswordButton?: boolean;
145
+ logo?: string;
108
146
  }
109
147
 
110
148
  export interface ITicket {
@@ -159,13 +197,20 @@ export const TicketsContainer = ({
159
197
  showPoweredByImage = false,
160
198
  promoText,
161
199
  showGroupNameBlock = false,
162
- currencySybmol = '',
200
+ currencySymbol = '',
163
201
  onReserveButtonClick = _identity,
164
202
  onPendingVerification = _identity,
165
203
  showAlertIcons = true,
204
+ onPreRegistrationSuccess = _identity,
205
+ onPreRegistrationError = _identity,
206
+ onPreRegistrationGetCountriesSuccess = _identity,
207
+ onPreRegistrationGetCountriesError = _identity,
208
+ onForgotPasswordSuccess = _identity,
209
+ onForgotPasswordError = _identity,
210
+ showForgotPasswordButton = false,
211
+ logo,
166
212
  }: IGetTickets) => {
167
213
  const [selectedTickets, setSelectedTickets] = useState({} as ISelectedTickets)
168
- const isWindowDefined = typeof window !== 'undefined'
169
214
  const [isLogged, setIsLogged] = useState(Boolean(getCookieByName(X_TF_ECOMMERCE)))
170
215
  const [showLoginModal, setShowLoginModal] = useState(false)
171
216
  const [tickets, setTickets] = useState([] as ITicketData[])
@@ -180,19 +225,31 @@ export const TicketsContainer = ({
180
225
  const [codeIsInvalid, setCodeIsInvalid] = useState(false)
181
226
  const [showAccessCodeSection, setShowAccessCodeSection] = useState(isAccessCodeEnabled)
182
227
  const [showPromoCodeSection, setShowPromoCodeSection] = useState(isPromotionsEnabled)
183
- const [error, setError] = useState(null)
228
+ const [error, setError] = useState<string | null>(null)
184
229
  const [isNotInvitedError, setIsNotInvitedError] = useState('')
185
230
  const [isInvalidLinkError, setIsInvalidLinkError] = useState('')
186
231
  const [pendingVerificationMessage, setPendingVerificationMessage] = useState()
187
- const [preregistereds, setPreregistereds] = useState([] as Array<IInfluancerData>)
232
+ const [preregisteredUsers, setPreregisteredUsers] = useState(
233
+ [] as Array<IInfluencerData>
234
+ )
188
235
  const [ticketsNotAvailableModalOpen, setTicketsNotAvailableModalOpen] = useState(false)
189
- const [isPreregistred, setIsPreregisred] = useState(checkUserPreregistration())
236
+ const [isPreregistered, setIsPreregistered] = useState(
237
+ checkUserPreregistration(preregisteredUsers)
238
+ )
190
239
  const ticketsContainerRef = useRef<HTMLDivElement>(null)
191
240
  const pageUrl = isBrowser ? window.location.href.split('?')[0] : ''
241
+ const isTimeSlotEvent = event?.isTimeSlotEvent
242
+ const [availableDates, setAvailableDates] = useState<string[]>([])
243
+ const [selectedDate, setSelectedDate] = useState<string | null>(null)
244
+ const [timeSlotGroups, setTimeSlotGroups] = useState<{ [key: string]: any[] }>({})
245
+
192
246
  useCookieListener(X_TF_ECOMMERCE, value => setIsLogged(Boolean(value)))
193
247
  useLocalStorageListener('user_data', (user: any) => {
194
- const isPreregistredUser = _some(preregistereds, item => item.email === user?.email)
195
- setIsPreregisred(isPreregistredUser)
248
+ const isPreregisteredUser = _some(
249
+ preregisteredUsers,
250
+ item => item.email === user?.email
251
+ )
252
+ setIsPreregistered(isPreregisteredUser)
196
253
  })
197
254
  usePixel(eventId, { pageUrl })
198
255
 
@@ -203,20 +260,21 @@ export const TicketsContainer = ({
203
260
  useEffect(() => {
204
261
  if (eventId) {
205
262
  getTicketsApi()
206
- fetchPreregisteredsData()
263
+ fetchPreregisteredData()
207
264
  }
265
+ // eslint-disable-next-line react-hooks/exhaustive-deps
208
266
  }, [eventId])
209
267
 
210
268
  useEffect(() => {
211
- setIsPreregisred(checkUserPreregistration())
212
- }, [preregistereds])
269
+ setIsPreregistered(checkUserPreregistration(preregisteredUsers))
270
+ }, [preregisteredUsers])
213
271
 
214
272
  useEffect(() => {
215
273
  if (isLogged) {
216
274
  fetchUserData()
217
275
  .then(res => {
218
276
  window.localStorage.setItem('user_data', JSON.stringify(res))
219
- onGetProfileDataSuccess(res)
277
+ onGetProfileDataSuccess({ data: { attributes: res } })
220
278
  })
221
279
  .catch(e => {
222
280
  if (axios.isAxiosError(e)) {
@@ -226,20 +284,9 @@ export const TicketsContainer = ({
226
284
  }
227
285
  }, [isLogged])
228
286
 
229
- const handleLogout = async () => {
230
- try {
231
- await logout()
232
- onLogoutSuccess()
233
- if (isBrowser) {
234
- window.localStorage.removeItem('user_data')
235
- setIsLogged(false)
236
- const event = new window.CustomEvent('tf-logout')
237
- deleteCookieByName('X-TF-ECOMMERCE')
238
- window.document.dispatchEvent(event)
239
- }
240
- } catch (e) {
241
- onLogoutError(e)
242
- }
287
+
288
+ const handleLogout = () => {
289
+ logoutUser({ onLogoutError, onLogoutSuccess, setIsLogged })
243
290
  }
244
291
 
245
292
  const handleExternalLogin = () => {
@@ -258,23 +305,58 @@ export const TicketsContainer = ({
258
305
  }
259
306
  }
260
307
 
261
- async function getTicketsApi(isUpdateingCode?: boolean, type?: string) {
308
+ const getTimeSlots = async (date: string | null, type?: string): Promise<void> => {
309
+ if (!date) {
310
+ setShowPromoCodeSection(false)
311
+ return
312
+ }
313
+
262
314
  try {
263
- isUpdateingCode ? setCodeIsLoading(true) : setIsLoading(true)
264
- const previewKey = getQueryVariable('pk') || undefined
265
- const response = await getTickets(eventId, code, previewKey)
266
- const eventResponse = await getEvent(eventId, previewKey)
267
- if (response.success) {
268
- const attributes = response?.data?.attributes
269
- type === 'promo' && setCodeIsApplied(attributes.ValidPromoCode)
270
- type === 'promo' && setCodeIsInvalid(!attributes.ValidPromoCode)
271
- setTickets(attributes.tickets)
272
- setShowWaitingList(attributes.showWaitingList)
273
- onGetTicketsSuccess(response.data)
315
+ const timeSlotsResponse = await getTimeSlotsByDate(
316
+ eventId,
317
+ moment(date).format('YYYY-MM-DD'),
318
+ code
319
+ )
320
+
321
+ const groupedTickets: any = {}
322
+ _map(timeSlotsResponse.data.attributes.timeslots, (timeslots, date) => {
323
+ const dateKeyChunks = date.split('-')
324
+ const dateKey = [dateKeyChunks[0], dateKeyChunks[1], dateKeyChunks[2]].join('-')
325
+
326
+ _forEach(timeslots, ticketList => {
327
+ if (!groupedTickets[dateKey]) {
328
+ groupedTickets[dateKey] = []
329
+ }
330
+ groupedTickets[dateKey] = groupedTickets[dateKey].concat(ticketList)
331
+ })
332
+ })
333
+
334
+ setTimeSlotGroups(groupedTickets)
335
+ setShowPromoCodeSection(true)
336
+
337
+ const attributes: TimeSlotsAttributes = timeSlotsResponse?.data?.attributes
338
+
339
+ if (type === 'promo') {
340
+ setCodeIsApplied(attributes.ValidPromoCode)
341
+ setCodeIsInvalid(!attributes.ValidPromoCode)
274
342
  setCode('')
343
+ window.localStorage.setItem('appliedPromoCode', code)
275
344
  setShowAccessCodeSection(attributes.is_access_code)
276
345
  setShowPromoCodeSection(attributes.isPromotionsEnabled)
277
346
  }
347
+ } catch (error) {}
348
+ }
349
+
350
+ async function getTicketsApi(isUpdatingCode?: boolean, type?: string) {
351
+ try {
352
+ if (isUpdatingCode) {
353
+ setCodeIsLoading(true)
354
+ } else {
355
+ setIsLoading(true)
356
+ }
357
+
358
+ const previewKey = getQueryVariable('pk') || undefined
359
+ const eventResponse = await getEvent(eventId, previewKey)
278
360
  if (eventResponse.success) {
279
361
  const event = eventResponse.data.attributes
280
362
  setEvent(event)
@@ -282,11 +364,36 @@ export const TicketsContainer = ({
282
364
  if (event.country && isBrowser) {
283
365
  window.localStorage.setItem('eventCountry', event.country)
284
366
  }
367
+
368
+ if (event.isTimeSlotEvent) {
369
+ getTimeSlots(selectedDate, code)
370
+ // For timeslots we shouldn't fetch all tickets at once
371
+ setAvailableDates(event?.timeslotSettings?.availableDates ?? [])
372
+ return
373
+ }
374
+ }
375
+
376
+ const response = await getTickets(eventId, code, previewKey)
377
+
378
+ if (response.success) {
379
+ const attributes = response?.data?.attributes
380
+ type === 'promo' && setCodeIsApplied(attributes.ValidPromoCode)
381
+ type === 'promo' && setCodeIsInvalid(!attributes.ValidPromoCode)
382
+ setTickets(attributes.tickets)
383
+ setShowWaitingList(attributes.showWaitingList)
384
+ onGetTicketsSuccess({
385
+ data: { attributes: { tickets: response.data.attributes.tickets } },
386
+ })
387
+ setCode('')
388
+ window.localStorage.setItem('appliedPromoCode', code)
389
+ setShowAccessCodeSection(attributes.is_access_code)
390
+ setShowPromoCodeSection(attributes.isPromotionsEnabled)
285
391
  }
286
392
  } catch (e) {
287
393
  if (axios.isAxiosError(e)) {
288
394
  onGetTicketsError(e)
289
- setError(_get(e, 'response.data.message'))
395
+ setError(_get(e, 'response.data.message', ''))
396
+ window.localStorage.removeItem('appliedPromoCode')
290
397
  }
291
398
  } finally {
292
399
  setIsLoading(false)
@@ -294,15 +401,15 @@ export const TicketsContainer = ({
294
401
  }
295
402
  }
296
403
 
297
- async function fetchPreregisteredsData() {
404
+ async function fetchPreregisteredData() {
298
405
  try {
299
- const preregistrationData = await getPreRegistrationInfluancers({
406
+ const preregistrationData = await getPreRegistrationInfluencers({
300
407
  eventId,
301
408
  })
302
- setPreregistereds(preregistrationData.data.attributes.influencers)
409
+ setPreregisteredUsers(preregistrationData.data.attributes.influencers)
303
410
  } catch (error) {
304
411
  if (axios.isAxiosError(error)) {
305
- setError(_get(error, 'response.data.message'))
412
+ setError(_get(error, 'response.data.message', ''))
306
413
  }
307
414
  }
308
415
  }
@@ -320,16 +427,6 @@ export const TicketsContainer = ({
320
427
  })
321
428
  }
322
429
 
323
- function checkUserPreregistration() {
324
- const userDataString = isWindowDefined ? window.localStorage.getItem('user_data') : ''
325
- let isPreregistredUser = false
326
- if (userDataString) {
327
- const user = JSON.parse(userDataString)
328
- isPreregistredUser = _some(preregistereds, item => item.email === user?.email)
329
- }
330
- return isPreregistredUser
331
- }
332
-
333
430
  const handleOrdersClick = () => {
334
431
  if (isBrowser) {
335
432
  window.location.href = ordersPath ?? '/orders'
@@ -341,13 +438,17 @@ export const TicketsContainer = ({
341
438
  }
342
439
 
343
440
  const handleBook = async () => {
441
+ const timeSlotTickets = _flatten(_map(timeSlotGroups, slots => slots))
442
+
344
443
  setHandleBookIsLoading(true)
345
- const ticket = _find(tickets, item => selectedTickets[item.id] > 0) || ({} as ITicket)
444
+ const ticket = event?.isTimeSlotEvent
445
+ ? _find(timeSlotTickets || [], item => Number(selectedTickets[item.id]) > 0) ||
446
+ ({} as ITicket)
447
+ : _find(tickets, item => Number(selectedTickets[item.id]) > 0) || ({} as ITicket)
346
448
  const optionName = _get(ticket, 'optionName')
347
449
  const ticketId = _get(ticket, 'id')
348
- const isTableType = _get(ticket, 'isTable', false)
349
450
  const productCartQuantity = +selectedTickets[ticket.id]
350
- const ticketQuantity = isTableType ? 1 : +selectedTickets[ticket.id]
451
+ const ticketQuantity = +selectedTickets[ticket.id]
351
452
 
352
453
  const data: ICartRequestData = {
353
454
  attributes: {
@@ -375,12 +476,13 @@ export const TicketsContainer = ({
375
476
  const pageConfigsDataResponse = enableAddOns
376
477
  ? await getCheckoutPageConfigs()
377
478
  : {
378
- status: 200,
379
- data: { attributes: _get(result, 'data.attributes') },
380
- }
479
+ status: 200,
480
+ data: { attributes: _get(result, 'data.attributes') },
481
+ }
381
482
 
382
- if (result.status === 200 && pageConfigsDataResponse.status === 200) {
383
- const pageConfigsData = _get(pageConfigsDataResponse, 'data.attributes') || {}
483
+ if (pageConfigsDataResponse.status === 200) {
484
+ const pageConfigsData: any =
485
+ _get(pageConfigsDataResponse, 'data.attributes') || {}
384
486
 
385
487
  const skipBillingPage = pageConfigsData.skip_billing_page ?? false
386
488
  const hasAddOn = pageConfigsData.has_add_on ?? false
@@ -390,12 +492,13 @@ export const TicketsContainer = ({
390
492
  let total: string | number | undefined = ''
391
493
 
392
494
  isBrowser && window.localStorage.removeItem('add_ons')
495
+ isBrowser && window.localStorage.removeItem('checkoutAdditionalConfigs')
393
496
 
394
497
  if (skipBillingPage && !hasAddOn) {
395
498
  // Get user data for checkout data
396
499
  const userData =
397
500
  isBrowser && window.localStorage.getItem('user_data')
398
- ? JSON.parse(window.localStorage.getItem('user_data') || '')
501
+ ? JSON.parse(window.localStorage.getItem('user_data') || '{}')
399
502
  : {}
400
503
 
401
504
  const checkoutBody = createCheckoutDataBodyWithDefaultHolder(
@@ -417,11 +520,15 @@ export const TicketsContainer = ({
417
520
  hash,
418
521
  total,
419
522
  hasAddOn,
523
+ eventSlug: event?.slug,
524
+ cart: pageConfigsDataResponse.data.attributes.cart,
525
+ currencySymbol: event?.currency.symbol,
420
526
  })
421
527
  }
422
528
  } catch (e) {
423
- if (e.response?.data?.data?.hasUnverifiedOrder) {
424
- setPendingVerificationMessage(e.response?.data?.message)
529
+ const errorResponse: any = _get(e, 'response', {})
530
+ if (errorResponse?.data?.data?.hasUnverifiedOrder) {
531
+ setPendingVerificationMessage(errorResponse?.data?.message)
425
532
  } else if (axios.isAxiosError(e)) {
426
533
  onAddToCartError(e)
427
534
  const message = _get(e, 'response.data.message', '')
@@ -447,8 +554,8 @@ export const TicketsContainer = ({
447
554
  }
448
555
  }
449
556
 
450
- const updateTickets = (isUpdateingCode?: boolean, type?: string) => {
451
- getTicketsApi(isUpdateingCode, type)
557
+ const updateTickets = (isUpdatingCode?: boolean, type?: string) => {
558
+ getTicketsApi(isUpdatingCode, type)
452
559
  }
453
560
 
454
561
  const fetchUserData = async () => {
@@ -458,11 +565,15 @@ export const TicketsContainer = ({
458
565
  return profileDataObj
459
566
  }
460
567
 
461
- const isTicketOnSale = _some(
462
- tickets,
463
- item =>
464
- (item.salesStarted || event?.presalesStarted) && !item.salesEnded && !item.soldOut
465
- )
568
+ const isTicketOnSale = event?.isTimeSlotEvent
569
+ ? true
570
+ : _some(
571
+ tickets,
572
+ item =>
573
+ (item.salesStarted || event?.presalesStarted) &&
574
+ !item.salesEnded &&
575
+ !item.soldOut
576
+ )
466
577
 
467
578
  const eventHasTickets = !_isEmpty(tickets)
468
579
  const isSalesClosed = event?.salesEnded
@@ -483,7 +594,7 @@ export const TicketsContainer = ({
483
594
  if (
484
595
  !handleBookIsLoading &&
485
596
  !_isEmpty(selectedTickets) &&
486
- Object.values(selectedTickets)[0] > 0
597
+ Number(Object.values(selectedTickets)[0]) > 0
487
598
  ) {
488
599
  handleBook()
489
600
  } else {
@@ -519,10 +630,10 @@ export const TicketsContainer = ({
519
630
 
520
631
  const wrappedActionsSectionComponent = React.isValidElement(ActionsSectionComponent)
521
632
  ? React.cloneElement(ActionsSectionComponent as React.ReactElement<any>, {
522
- handleGetTicketClick,
523
- isTicketOnSale,
524
- isTicketAvailable,
525
- })
633
+ handleGetTicketClick,
634
+ isTicketOnSale,
635
+ isTicketAvailable,
636
+ })
526
637
  : null
527
638
 
528
639
  const externalUrl = event?.redirectUrl
@@ -564,16 +675,24 @@ export const TicketsContainer = ({
564
675
  )}. \n If you pre-registered, log into your account first to buy your pre-sale ticket.`
565
676
 
566
677
  const tableTickets = _filter(tickets, (ticket: any) => ticket.isTable)
567
- const ordinarTickets = {} as ITicket
678
+ const ordinaryTickets = {} as ITicket
568
679
  _forEach(tickets, (ticket: any, key: string) => {
569
680
  if (!ticket.isTable) {
570
- ordinarTickets[key] = ticket
681
+ ordinaryTickets[key] = ticket
571
682
  }
572
683
  })
684
+
685
+
686
+ // Check if event is in pre-registration mode
687
+ const isPreRegistrationMode =
688
+ event?.preregEnabled &&
689
+ event?.preregStarted &&
690
+ !event?.preregEnded
691
+
573
692
  return (
574
693
  <ThemeProvider theme={themeMui}>
575
694
  {!isLoading && <ReferralLogic eventId={eventId} />}
576
- <div className={`get-tickets-page ${theme}`} style={contentStyle}>
695
+ <div className={`get-tickets-page ${theme} open-ground`} style={contentStyle}>
577
696
  {isInvalidLinkError && (
578
697
  <ConfirmModal
579
698
  message={isInvalidLinkError}
@@ -588,7 +707,7 @@ export const TicketsContainer = ({
588
707
  message={isNotInvitedError}
589
708
  onClose={() => onClose('notInvited')}
590
709
  onConfirm={() => onClose('notInvited')}
591
- // loading={removeFromResaleLoading}
710
+ // loading={removeFromResaleLoading}
592
711
  />
593
712
  )}
594
713
  {error && (
@@ -611,12 +730,50 @@ export const TicketsContainer = ({
611
730
  )}
612
731
  {isLoading ? (
613
732
  <Loader />
733
+ ) : isPreRegistrationMode ? (
734
+ <PreRegistration
735
+ eventId={eventId}
736
+ isPreregistrationStarted={event?.preregStarted}
737
+ logo={logo}
738
+ showForgotPasswordButton={showForgotPasswordButton}
739
+ onClose={() => {}}
740
+ onLogin={onLoginSuccess}
741
+ onLoginButtonClick={() => {}}
742
+ onLoginSuccess={onLoginSuccess}
743
+ onConfirmationSuccess={onPreRegistrationSuccess}
744
+ onConfirmationError={onPreRegistrationError}
745
+ onGetCountriesSuccess={onPreRegistrationGetCountriesSuccess}
746
+ onGetCountriesError={onPreRegistrationGetCountriesError}
747
+ onForgotPasswordSuccess={onForgotPasswordSuccess}
748
+ onForgotPasswordError={onForgotPasswordError}
749
+ themeOptions={themeOptions}
750
+ />
614
751
  ) : (
615
- <div ref={ticketsContainerRef}>
616
- {!isSalesClosed && (
752
+ <div ref={ticketsContainerRef} className="tickets-section-container">
753
+ {isTimeSlotEvent && (
754
+ <TimeSlotsSection
755
+ event={event}
756
+ eventId={eventId}
757
+ availableDates={availableDates}
758
+ selectedDate={selectedDate}
759
+ setSelectedDate={setSelectedDate}
760
+ timeSlotGroups={timeSlotGroups}
761
+ setTimeSlotGroups={setTimeSlotGroups}
762
+ selectedTickets={selectedTickets}
763
+ handleTicketSelect={handleTicketSelect}
764
+ sortBySoldOut={sortBySoldOut}
765
+ ticketsHeaderComponent={ticketsHeaderComponent}
766
+ hideTicketsHeader={hideTicketsHeader}
767
+ showGroupNameBlock={showGroupNameBlock}
768
+ currencySymbol={currencySymbol}
769
+ isSeatMapAllowed={isSeatMapAllowed}
770
+ getTimeSlots={getTimeSlots}
771
+ />
772
+ )}
773
+ {!isSalesClosed && !isTimeSlotEvent && (
617
774
  <TicketsSection
618
775
  event={event}
619
- ticketsList={ordinarTickets}
776
+ ticketsList={ordinaryTickets}
620
777
  tableTickets={tableTickets}
621
778
  selectedTickets={selectedTickets}
622
779
  handleTicketSelect={handleTicketSelect}
@@ -624,15 +781,17 @@ export const TicketsContainer = ({
624
781
  ticketsHeaderComponent={ticketsHeaderComponent}
625
782
  tableTicketsHeaderComponent={tableTicketsHeaderComponent}
626
783
  hideTableTicketsHeader={hideTableTicketsHeader || _isEmpty(tableTickets)}
627
- hideTicketsHeader={hideTicketsHeader || _isEmpty(ordinarTickets)}
784
+ hideTicketsHeader={hideTicketsHeader || _isEmpty(ordinaryTickets)}
628
785
  showGroupNameBlock={showGroupNameBlock}
629
- currencySybmol={currencySybmol}
786
+ currencySymbol={currencySymbol}
630
787
  isSeatMapAllowed={isSeatMapAllowed}
631
788
  />
632
789
  )}
633
790
  {externalUrl ? null : isSalesClosed ? (
634
791
  <p
635
- className={`event-closed-message ${!isLoggedIn ? 'event-closed-on-bottom' : ''}`}
792
+ className={`event-closed-message ${
793
+ !isLoggedIn ? 'event-closed-on-bottom' : ''
794
+ }`}
636
795
  >
637
796
  Sales for this event are closed.
638
797
  </p>
@@ -648,13 +807,16 @@ export const TicketsContainer = ({
648
807
  isLoggedIn={isLoggedIn}
649
808
  />
650
809
  ) : null}
651
- {showWaitingList && event.salesStarted && !hideWaitingList && (
652
- <WaitingList
653
- tickets={ordinarTickets}
654
- eventId={eventId}
655
- defaultMaxQuantity={event.waitingListMaxQuantity}
656
- />
657
- )}
810
+ {event?.enableWaitingList &&
811
+ showWaitingList &&
812
+ event.salesStarted &&
813
+ !hideWaitingList && (
814
+ <WaitingList
815
+ tickets={ordinaryTickets}
816
+ eventId={eventId}
817
+ defaultMaxQuantity={event.waitingListMaxQuantity}
818
+ />
819
+ )}
658
820
  {codeIsLoading ? (
659
821
  <Loader />
660
822
  ) : isSalesClosed ? null : showAccessCodeSection ? (
@@ -682,16 +844,16 @@ export const TicketsContainer = ({
682
844
  {canShowGetTicketBtn() && (
683
845
  <Button
684
846
  aria-hidden={true}
685
- className={`book-button
686
- ${bookButtonIsDisabled ? 'disabled' : ''}
847
+ className={`book-button
848
+ ${bookButtonIsDisabled ? 'disabled' : ''}
687
849
  ${isButtonScrollable ? 'is-scrollable' : ''}
688
850
  ${!isLoggedIn ? 'on-bottom' : ''}
689
851
  `}
690
852
  onClick={
691
853
  event?.salesStart &&
692
- event?.presalesStarted &&
693
- !event?.presalesEnded &&
694
- (!isPreregistred || !isLogged)
854
+ event?.presalesStarted &&
855
+ !event?.presalesEnded &&
856
+ (!isPreregistered || !isLogged)
695
857
  ? handleNotAvailableTicketsClick
696
858
  : handleGetTicketClick
697
859
  }