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.
- package/README.md +61 -40
- package/dist/adapters/customFields.d.ts +1 -0
- package/dist/api/checkout.d.ts +1 -0
- package/dist/api/common.d.ts +1 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/preRegistrationComplete.d.ts +1 -1
- package/dist/components/addonsContainer/AddonComponent.d.ts +5 -1
- package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +17 -0
- package/dist/components/addonsContainer/index.d.ts +5 -1
- package/dist/components/billing-info-container/index.d.ts +8 -1
- package/dist/components/billing-info-container/utils.d.ts +25 -1
- package/dist/components/common/DatePickerField.d.ts +7 -1
- package/dist/components/countdown/index.d.ts +1 -1
- package/dist/components/forgotPasswordModal/index.d.ts +2 -1
- package/dist/components/myTicketsContainer/index.d.ts +3 -2
- package/dist/components/orderDetailsContainer/index.d.ts +7 -1
- package/dist/components/paymentContainer/OrderDetails.d.ts +8 -0
- package/dist/components/paymentContainer/handlePayment.d.ts +15 -0
- package/dist/components/paymentContainer/index.d.ts +10 -5
- package/dist/components/preRegistration/FieldsSection.d.ts +7 -1
- package/dist/components/preRegistration/PreRegistrationComplete.d.ts +6 -0
- package/dist/components/preRegistration/constants.d.ts +2 -2
- package/dist/components/preRegistration/index.d.ts +6 -0
- package/dist/components/resetPasswordContainer/index.d.ts +2 -2
- package/dist/components/stripePayment/index.d.ts +18 -3
- package/dist/components/ticketsContainer/InfoIcon.d.ts +5 -0
- package/dist/components/ticketsContainer/TicketsSection.d.ts +3 -2
- package/dist/components/ticketsContainer/TimeSlotsSection.d.ts +25 -0
- package/dist/components/ticketsContainer/index.d.ts +18 -5
- package/dist/components/timerWidget/index.d.ts +2 -1
- package/dist/constants/index.d.ts +5 -0
- package/dist/index.d.ts +4 -1
- package/dist/tf-checkout-react.cjs.development.js +5196 -3599
- package/dist/tf-checkout-react.cjs.development.js.map +1 -1
- package/dist/tf-checkout-react.cjs.production.min.js +1 -1
- package/dist/tf-checkout-react.cjs.production.min.js.map +1 -1
- package/dist/tf-checkout-react.esm.js +5199 -3605
- package/dist/tf-checkout-react.esm.js.map +1 -1
- package/dist/tf-checkout-styles.css +1 -1
- package/dist/types/add_on.d.ts +1 -0
- package/dist/types/checkoutPageConfigs.d.ts +1 -1
- package/dist/types/order-data.d.ts +2 -1
- package/dist/utils/auth.d.ts +8 -0
- package/dist/utils/customFields.d.ts +11 -0
- package/dist/utils/getDomain.d.ts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/setConfigs.d.ts +1 -0
- package/package.json +3 -2
- package/src/adapters/customFields.ts +7 -1
- package/src/api/auth.ts +2 -1
- package/src/api/checkout.ts +8 -4
- package/src/api/common.ts +49 -2
- package/src/api/interceptors.ts +7 -23
- package/src/api/preRegistrationComplete.ts +1 -1
- package/src/api/publicRequest.ts +10 -0
- package/src/components/addonsContainer/AddonComponent.tsx +71 -11
- package/src/components/addonsContainer/SimpleAddonsContainer.tsx +388 -0
- package/src/components/addonsContainer/index.tsx +189 -58
- package/src/components/billing-info-container/index.tsx +704 -390
- package/src/components/billing-info-container/{utils.ts → utils.tsx} +119 -0
- package/src/components/common/CheckboxField/index.tsx +1 -1
- package/src/components/common/DatePickerField.tsx +25 -10
- package/src/components/common/SnackbarAlert.tsx +32 -34
- package/src/components/confirmationContainer/index.tsx +1 -1
- package/src/components/countdown/index.tsx +22 -22
- package/src/components/delegationsContainer/IssueComponent.tsx +2 -1
- package/src/components/forgotPasswordModal/index.tsx +44 -13
- package/src/components/loginForm/index.tsx +1 -1
- package/src/components/loginModal/index.tsx +2 -2
- package/src/components/loginModal/style.css +3 -1
- package/src/components/myTicketsContainer/index.tsx +13 -9
- package/src/components/orderDetailsContainer/index.tsx +188 -173
- package/src/components/paymentContainer/OrderDetails.tsx +170 -0
- package/src/components/paymentContainer/handlePayment.ts +86 -0
- package/src/components/paymentContainer/index.tsx +253 -226
- package/src/components/paymentContainer/style.css +113 -0
- package/src/components/preRegistration/FieldsSection.tsx +8 -0
- package/src/components/preRegistration/PreRegistrationComplete.tsx +128 -118
- package/src/components/preRegistration/PreRegistrationInformations.tsx +21 -15
- package/src/components/preRegistration/constants.tsx +10 -4
- package/src/components/preRegistration/index.tsx +194 -174
- package/src/components/registerForm/constants.tsx +3 -1
- package/src/components/registerForm/index.tsx +3 -3
- package/src/components/resetPasswordContainer/index.tsx +12 -13
- package/src/components/seatMapContainer/TicketsSection.tsx +2 -2
- package/src/components/stripePayment/index.tsx +129 -24
- package/src/components/ticketsContainer/InfoIcon.tsx +35 -0
- package/src/components/ticketsContainer/PromoCodeSection.tsx +34 -28
- package/src/components/ticketsContainer/TicketRow.tsx +1 -1
- package/src/components/ticketsContainer/TicketsSection.tsx +178 -52
- package/src/components/ticketsContainer/TimeSlotsSection.tsx +120 -0
- package/src/components/ticketsContainer/index.tsx +209 -99
- package/src/components/timerWidget/index.tsx +15 -3
- package/src/constants/index.ts +2 -0
- package/src/hoc/CustomFields/index.tsx +9 -1
- package/src/index.ts +7 -2
- package/src/types/add_on.ts +1 -0
- package/src/types/api/common.d.ts +27 -0
- package/src/types/api/orders.d.ts +19 -3
- package/src/types/api/payment.d.ts +5 -2
- package/src/types/api/preRegistrationComplete.d.ts +2 -2
- package/src/types/checkoutPageConfigs.ts +1 -1
- package/src/types/order-data.ts +2 -1
- package/src/types/pre-registration-complete.d.ts +6 -1
- package/src/utils/auth.ts +32 -0
- package/src/utils/cookies.ts +42 -11
- package/src/utils/customFields.ts +22 -0
- package/src/utils/getDomain.ts +10 -4
- package/src/utils/index.ts +1 -1
- package/src/utils/setConfigs.ts +3 -1
|
@@ -1,17 +1,20 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
2
|
import './style.css'
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
+
import { ThemeOptions } from '@mui/material'
|
|
4
5
|
import Alert from '@mui/material/Alert'
|
|
5
|
-
import { ThemeProvider } from '@mui/
|
|
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 {
|
|
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'
|
|
@@ -50,6 +53,24 @@ import { AccessCodeSection } from './AccessCodeSection'
|
|
|
50
53
|
import { PromoCodeSection } from './PromoCodeSection'
|
|
51
54
|
import { ReferralLogic } from './ReferralLogic'
|
|
52
55
|
import { TicketsSection } from './TicketsSection'
|
|
56
|
+
import TimeSlotsSection from './TimeSlotsSection'
|
|
57
|
+
|
|
58
|
+
const checkUserPreregistration = (preregisteredUsers: IInfluencerData[]) => {
|
|
59
|
+
const isWindowDefined = typeof window !== 'undefined'
|
|
60
|
+
const userDataString = isWindowDefined ? window.localStorage.getItem('user_data') : ''
|
|
61
|
+
let isPreregisteredUser = false
|
|
62
|
+
if (userDataString) {
|
|
63
|
+
const user = JSON.parse(userDataString)
|
|
64
|
+
isPreregisteredUser = _some(preregisteredUsers, item => item.email === user?.email)
|
|
65
|
+
}
|
|
66
|
+
return isPreregisteredUser
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface TimeSlotsAttributes {
|
|
70
|
+
ValidPromoCode: boolean;
|
|
71
|
+
is_access_code: boolean;
|
|
72
|
+
isPromotionsEnabled: boolean;
|
|
73
|
+
}
|
|
53
74
|
|
|
54
75
|
interface CartSuccess {
|
|
55
76
|
skip_billing_page: boolean;
|
|
@@ -57,6 +78,7 @@ interface CartSuccess {
|
|
|
57
78
|
hash?: string | number;
|
|
58
79
|
total?: string | number;
|
|
59
80
|
hasAddOn?: boolean;
|
|
81
|
+
eventSlug?: string;
|
|
60
82
|
}
|
|
61
83
|
|
|
62
84
|
export interface IGetTickets {
|
|
@@ -65,12 +87,16 @@ export interface IGetTickets {
|
|
|
65
87
|
getTicketsLabel?: string;
|
|
66
88
|
contentStyle?: React.CSSProperties;
|
|
67
89
|
onAddToCartError: (e: AxiosError) => void;
|
|
68
|
-
onGetTicketsSuccess: (response:
|
|
90
|
+
onGetTicketsSuccess: (response: {
|
|
91
|
+
data: { attributes: { tickets: ITicketData[] } };
|
|
92
|
+
}) => void;
|
|
69
93
|
onGetTicketsPress: () => void;
|
|
70
94
|
onGetTicketsError: (e: AxiosError) => void;
|
|
71
95
|
onLogoutSuccess: () => void;
|
|
72
96
|
onLogoutError: (e: AxiosError) => void;
|
|
73
|
-
onGetProfileDataSuccess: (response:
|
|
97
|
+
onGetProfileDataSuccess: (response: {
|
|
98
|
+
data: { attributes: { [key: string]: string | number | boolean | null } };
|
|
99
|
+
}) => void;
|
|
74
100
|
onGetProfileDataError: (e: AxiosError) => void;
|
|
75
101
|
onLoginSuccess: () => void;
|
|
76
102
|
handleNotInvitedModalClose: () => void;
|
|
@@ -90,7 +116,7 @@ export interface IGetTickets {
|
|
|
90
116
|
sortBySoldOut?: boolean;
|
|
91
117
|
disableCountdownLeadingZero?: boolean;
|
|
92
118
|
isLoggedIn?: boolean;
|
|
93
|
-
actionsSectionComponent?:
|
|
119
|
+
actionsSectionComponent?: ReactNode;
|
|
94
120
|
ticketsHeaderComponent?: ReactNode;
|
|
95
121
|
hideTicketsHeader?: boolean;
|
|
96
122
|
tableTicketsHeaderComponent?: ReactNode;
|
|
@@ -101,7 +127,7 @@ export interface IGetTickets {
|
|
|
101
127
|
showPoweredByImage?: boolean;
|
|
102
128
|
promoText?: string;
|
|
103
129
|
showGroupNameBlock?: boolean;
|
|
104
|
-
|
|
130
|
+
currencySymbol?: string;
|
|
105
131
|
onReserveButtonClick?: () => void;
|
|
106
132
|
onPendingVerification?: () => void;
|
|
107
133
|
showAlertIcons?: boolean;
|
|
@@ -159,13 +185,12 @@ export const TicketsContainer = ({
|
|
|
159
185
|
showPoweredByImage = false,
|
|
160
186
|
promoText,
|
|
161
187
|
showGroupNameBlock = false,
|
|
162
|
-
|
|
188
|
+
currencySymbol = '',
|
|
163
189
|
onReserveButtonClick = _identity,
|
|
164
190
|
onPendingVerification = _identity,
|
|
165
191
|
showAlertIcons = true,
|
|
166
192
|
}: IGetTickets) => {
|
|
167
193
|
const [selectedTickets, setSelectedTickets] = useState({} as ISelectedTickets)
|
|
168
|
-
const isWindowDefined = typeof window !== 'undefined'
|
|
169
194
|
const [isLogged, setIsLogged] = useState(Boolean(getCookieByName(X_TF_ECOMMERCE)))
|
|
170
195
|
const [showLoginModal, setShowLoginModal] = useState(false)
|
|
171
196
|
const [tickets, setTickets] = useState([] as ITicketData[])
|
|
@@ -180,19 +205,31 @@ export const TicketsContainer = ({
|
|
|
180
205
|
const [codeIsInvalid, setCodeIsInvalid] = useState(false)
|
|
181
206
|
const [showAccessCodeSection, setShowAccessCodeSection] = useState(isAccessCodeEnabled)
|
|
182
207
|
const [showPromoCodeSection, setShowPromoCodeSection] = useState(isPromotionsEnabled)
|
|
183
|
-
const [error, setError] = useState(null)
|
|
208
|
+
const [error, setError] = useState<string | null>(null)
|
|
184
209
|
const [isNotInvitedError, setIsNotInvitedError] = useState('')
|
|
185
210
|
const [isInvalidLinkError, setIsInvalidLinkError] = useState('')
|
|
186
211
|
const [pendingVerificationMessage, setPendingVerificationMessage] = useState()
|
|
187
|
-
const [
|
|
212
|
+
const [preregisteredUsers, setPreregisteredUsers] = useState(
|
|
213
|
+
[] as Array<IInfluencerData>
|
|
214
|
+
)
|
|
188
215
|
const [ticketsNotAvailableModalOpen, setTicketsNotAvailableModalOpen] = useState(false)
|
|
189
|
-
const [
|
|
216
|
+
const [isPreregistered, setIsPreregistered] = useState(
|
|
217
|
+
checkUserPreregistration(preregisteredUsers)
|
|
218
|
+
)
|
|
190
219
|
const ticketsContainerRef = useRef<HTMLDivElement>(null)
|
|
191
220
|
const pageUrl = isBrowser ? window.location.href.split('?')[0] : ''
|
|
221
|
+
const isTimeSlotEvent = event?.isTimeSlotEvent
|
|
222
|
+
const [availableDates, setAvailableDates] = useState<string[]>([])
|
|
223
|
+
const [selectedDate, setSelectedDate] = useState<string | null>(null)
|
|
224
|
+
const [timeSlotGroups, setTimeSlotGroups] = useState<{ [key: string]: any[] }>({})
|
|
225
|
+
|
|
192
226
|
useCookieListener(X_TF_ECOMMERCE, value => setIsLogged(Boolean(value)))
|
|
193
227
|
useLocalStorageListener('user_data', (user: any) => {
|
|
194
|
-
const
|
|
195
|
-
|
|
228
|
+
const isPreregisteredUser = _some(
|
|
229
|
+
preregisteredUsers,
|
|
230
|
+
item => item.email === user?.email
|
|
231
|
+
)
|
|
232
|
+
setIsPreregistered(isPreregisteredUser)
|
|
196
233
|
})
|
|
197
234
|
usePixel(eventId, { pageUrl })
|
|
198
235
|
|
|
@@ -203,20 +240,20 @@ export const TicketsContainer = ({
|
|
|
203
240
|
useEffect(() => {
|
|
204
241
|
if (eventId) {
|
|
205
242
|
getTicketsApi()
|
|
206
|
-
|
|
243
|
+
fetchPreregisteredData()
|
|
207
244
|
}
|
|
208
|
-
}, [eventId])
|
|
245
|
+
}, [eventId, isTimeSlotEvent])
|
|
209
246
|
|
|
210
247
|
useEffect(() => {
|
|
211
|
-
|
|
212
|
-
}, [
|
|
248
|
+
setIsPreregistered(checkUserPreregistration(preregisteredUsers))
|
|
249
|
+
}, [preregisteredUsers])
|
|
213
250
|
|
|
214
251
|
useEffect(() => {
|
|
215
252
|
if (isLogged) {
|
|
216
253
|
fetchUserData()
|
|
217
254
|
.then(res => {
|
|
218
255
|
window.localStorage.setItem('user_data', JSON.stringify(res))
|
|
219
|
-
onGetProfileDataSuccess(res)
|
|
256
|
+
onGetProfileDataSuccess({ data: { attributes: res } })
|
|
220
257
|
})
|
|
221
258
|
.catch(e => {
|
|
222
259
|
if (axios.isAxiosError(e)) {
|
|
@@ -226,20 +263,8 @@ export const TicketsContainer = ({
|
|
|
226
263
|
}
|
|
227
264
|
}, [isLogged])
|
|
228
265
|
|
|
229
|
-
const handleLogout =
|
|
230
|
-
|
|
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
|
-
}
|
|
266
|
+
const handleLogout = () => {
|
|
267
|
+
logoutUser({ onLogoutError, onLogoutSuccess, setIsLogged })
|
|
243
268
|
}
|
|
244
269
|
|
|
245
270
|
const handleExternalLogin = () => {
|
|
@@ -258,23 +283,58 @@ export const TicketsContainer = ({
|
|
|
258
283
|
}
|
|
259
284
|
}
|
|
260
285
|
|
|
261
|
-
async
|
|
286
|
+
const getTimeSlots = async (date: string | null, type?: string): Promise<void> => {
|
|
287
|
+
if (!date) {
|
|
288
|
+
setShowPromoCodeSection(false)
|
|
289
|
+
return
|
|
290
|
+
}
|
|
291
|
+
|
|
262
292
|
try {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
293
|
+
const timeSlotsResponse = await getTimeSlotsByDate(
|
|
294
|
+
eventId,
|
|
295
|
+
moment(date).format('YYYY-MM-DD'),
|
|
296
|
+
code
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
const groupedTickets: any = {}
|
|
300
|
+
_map(timeSlotsResponse.data.attributes.timeslots, (timeslots, date) => {
|
|
301
|
+
const dateKeyChunks = date.split('-')
|
|
302
|
+
const dateKey = [dateKeyChunks[0], dateKeyChunks[1], dateKeyChunks[2]].join('-')
|
|
303
|
+
|
|
304
|
+
_forEach(timeslots, ticketList => {
|
|
305
|
+
if (!groupedTickets[dateKey]) {
|
|
306
|
+
groupedTickets[dateKey] = []
|
|
307
|
+
}
|
|
308
|
+
groupedTickets[dateKey] = groupedTickets[dateKey].concat(ticketList)
|
|
309
|
+
})
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
setTimeSlotGroups(groupedTickets)
|
|
313
|
+
setShowPromoCodeSection(true)
|
|
314
|
+
|
|
315
|
+
const attributes: TimeSlotsAttributes = timeSlotsResponse?.data?.attributes
|
|
316
|
+
|
|
317
|
+
if (type === 'promo') {
|
|
318
|
+
setCodeIsApplied(attributes.ValidPromoCode)
|
|
319
|
+
setCodeIsInvalid(!attributes.ValidPromoCode)
|
|
274
320
|
setCode('')
|
|
321
|
+
window.localStorage.setItem('appliedPromoCode', code)
|
|
275
322
|
setShowAccessCodeSection(attributes.is_access_code)
|
|
276
323
|
setShowPromoCodeSection(attributes.isPromotionsEnabled)
|
|
277
324
|
}
|
|
325
|
+
} catch (error) {}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async function getTicketsApi(isUpdatingCode?: boolean, type?: string) {
|
|
329
|
+
try {
|
|
330
|
+
if (isUpdatingCode) {
|
|
331
|
+
setCodeIsLoading(true)
|
|
332
|
+
} else {
|
|
333
|
+
setIsLoading(true)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const previewKey = getQueryVariable('pk') || undefined
|
|
337
|
+
const eventResponse = await getEvent(eventId, previewKey)
|
|
278
338
|
if (eventResponse.success) {
|
|
279
339
|
const event = eventResponse.data.attributes
|
|
280
340
|
setEvent(event)
|
|
@@ -282,11 +342,36 @@ export const TicketsContainer = ({
|
|
|
282
342
|
if (event.country && isBrowser) {
|
|
283
343
|
window.localStorage.setItem('eventCountry', event.country)
|
|
284
344
|
}
|
|
345
|
+
|
|
346
|
+
if (event.isTimeSlotEvent) {
|
|
347
|
+
getTimeSlots(selectedDate, code)
|
|
348
|
+
// For timeslots we shouldn't fetch all tickets at once
|
|
349
|
+
setAvailableDates(event?.timeslotSettings?.availableDates ?? [])
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const response = await getTickets(eventId, code, previewKey)
|
|
355
|
+
|
|
356
|
+
if (response.success) {
|
|
357
|
+
const attributes = response?.data?.attributes
|
|
358
|
+
type === 'promo' && setCodeIsApplied(attributes.ValidPromoCode)
|
|
359
|
+
type === 'promo' && setCodeIsInvalid(!attributes.ValidPromoCode)
|
|
360
|
+
setTickets(attributes.tickets)
|
|
361
|
+
setShowWaitingList(attributes.showWaitingList)
|
|
362
|
+
onGetTicketsSuccess({
|
|
363
|
+
data: { attributes: { tickets: response.data.attributes.tickets } },
|
|
364
|
+
})
|
|
365
|
+
setCode('')
|
|
366
|
+
window.localStorage.setItem('appliedPromoCode', code)
|
|
367
|
+
setShowAccessCodeSection(attributes.is_access_code)
|
|
368
|
+
setShowPromoCodeSection(attributes.isPromotionsEnabled)
|
|
285
369
|
}
|
|
286
370
|
} catch (e) {
|
|
287
371
|
if (axios.isAxiosError(e)) {
|
|
288
372
|
onGetTicketsError(e)
|
|
289
|
-
setError(_get(e, 'response.data.message'))
|
|
373
|
+
setError(_get(e, 'response.data.message', ''))
|
|
374
|
+
window.localStorage.removeItem('appliedPromoCode')
|
|
290
375
|
}
|
|
291
376
|
} finally {
|
|
292
377
|
setIsLoading(false)
|
|
@@ -294,15 +379,15 @@ export const TicketsContainer = ({
|
|
|
294
379
|
}
|
|
295
380
|
}
|
|
296
381
|
|
|
297
|
-
async function
|
|
382
|
+
async function fetchPreregisteredData() {
|
|
298
383
|
try {
|
|
299
|
-
const preregistrationData = await
|
|
384
|
+
const preregistrationData = await getPreRegistrationInfluencers({
|
|
300
385
|
eventId,
|
|
301
386
|
})
|
|
302
|
-
|
|
387
|
+
setPreregisteredUsers(preregistrationData.data.attributes.influencers)
|
|
303
388
|
} catch (error) {
|
|
304
389
|
if (axios.isAxiosError(error)) {
|
|
305
|
-
setError(_get(error, 'response.data.message'))
|
|
390
|
+
setError(_get(error, 'response.data.message', ''))
|
|
306
391
|
}
|
|
307
392
|
}
|
|
308
393
|
}
|
|
@@ -320,16 +405,6 @@ export const TicketsContainer = ({
|
|
|
320
405
|
})
|
|
321
406
|
}
|
|
322
407
|
|
|
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
408
|
const handleOrdersClick = () => {
|
|
334
409
|
if (isBrowser) {
|
|
335
410
|
window.location.href = ordersPath ?? '/orders'
|
|
@@ -341,8 +416,13 @@ export const TicketsContainer = ({
|
|
|
341
416
|
}
|
|
342
417
|
|
|
343
418
|
const handleBook = async () => {
|
|
419
|
+
const timeSlotTickets = _flatten(_map(timeSlotGroups, slots => slots))
|
|
420
|
+
|
|
344
421
|
setHandleBookIsLoading(true)
|
|
345
|
-
const ticket =
|
|
422
|
+
const ticket = event?.isTimeSlotEvent
|
|
423
|
+
? _find(timeSlotTickets || [], item => Number(selectedTickets[item.id]) > 0) ||
|
|
424
|
+
({} as ITicket)
|
|
425
|
+
: _find(tickets, item => Number(selectedTickets[item.id]) > 0) || ({} as ITicket)
|
|
346
426
|
const optionName = _get(ticket, 'optionName')
|
|
347
427
|
const ticketId = _get(ticket, 'id')
|
|
348
428
|
const isTableType = _get(ticket, 'isTable', false)
|
|
@@ -375,12 +455,13 @@ export const TicketsContainer = ({
|
|
|
375
455
|
const pageConfigsDataResponse = enableAddOns
|
|
376
456
|
? await getCheckoutPageConfigs()
|
|
377
457
|
: {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
458
|
+
status: 200,
|
|
459
|
+
data: { attributes: _get(result, 'data.attributes') },
|
|
460
|
+
}
|
|
381
461
|
|
|
382
|
-
if (
|
|
383
|
-
const pageConfigsData =
|
|
462
|
+
if (pageConfigsDataResponse.status === 200) {
|
|
463
|
+
const pageConfigsData: any =
|
|
464
|
+
_get(pageConfigsDataResponse, 'data.attributes') || {}
|
|
384
465
|
|
|
385
466
|
const skipBillingPage = pageConfigsData.skip_billing_page ?? false
|
|
386
467
|
const hasAddOn = pageConfigsData.has_add_on ?? false
|
|
@@ -395,7 +476,7 @@ export const TicketsContainer = ({
|
|
|
395
476
|
// Get user data for checkout data
|
|
396
477
|
const userData =
|
|
397
478
|
isBrowser && window.localStorage.getItem('user_data')
|
|
398
|
-
? JSON.parse(window.localStorage.getItem('user_data') || '')
|
|
479
|
+
? JSON.parse(window.localStorage.getItem('user_data') || '{}')
|
|
399
480
|
: {}
|
|
400
481
|
|
|
401
482
|
const checkoutBody = createCheckoutDataBodyWithDefaultHolder(
|
|
@@ -417,11 +498,13 @@ export const TicketsContainer = ({
|
|
|
417
498
|
hash,
|
|
418
499
|
total,
|
|
419
500
|
hasAddOn,
|
|
501
|
+
eventSlug: event?.slug,
|
|
420
502
|
})
|
|
421
503
|
}
|
|
422
504
|
} catch (e) {
|
|
423
|
-
|
|
424
|
-
|
|
505
|
+
const errorResponse: any = _get(e, 'response', {})
|
|
506
|
+
if (errorResponse?.data?.data?.hasUnverifiedOrder) {
|
|
507
|
+
setPendingVerificationMessage(errorResponse?.data?.message)
|
|
425
508
|
} else if (axios.isAxiosError(e)) {
|
|
426
509
|
onAddToCartError(e)
|
|
427
510
|
const message = _get(e, 'response.data.message', '')
|
|
@@ -447,8 +530,8 @@ export const TicketsContainer = ({
|
|
|
447
530
|
}
|
|
448
531
|
}
|
|
449
532
|
|
|
450
|
-
const updateTickets = (
|
|
451
|
-
getTicketsApi(
|
|
533
|
+
const updateTickets = (isUpdatingCode?: boolean, type?: string) => {
|
|
534
|
+
getTicketsApi(isUpdatingCode, type)
|
|
452
535
|
}
|
|
453
536
|
|
|
454
537
|
const fetchUserData = async () => {
|
|
@@ -458,11 +541,15 @@ export const TicketsContainer = ({
|
|
|
458
541
|
return profileDataObj
|
|
459
542
|
}
|
|
460
543
|
|
|
461
|
-
const isTicketOnSale =
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
544
|
+
const isTicketOnSale = event?.isTimeSlotEvent
|
|
545
|
+
? true
|
|
546
|
+
: _some(
|
|
547
|
+
tickets,
|
|
548
|
+
item =>
|
|
549
|
+
(item.salesStarted || event?.presalesStarted) &&
|
|
550
|
+
!item.salesEnded &&
|
|
551
|
+
!item.soldOut
|
|
552
|
+
)
|
|
466
553
|
|
|
467
554
|
const eventHasTickets = !_isEmpty(tickets)
|
|
468
555
|
const isSalesClosed = event?.salesEnded
|
|
@@ -483,7 +570,7 @@ export const TicketsContainer = ({
|
|
|
483
570
|
if (
|
|
484
571
|
!handleBookIsLoading &&
|
|
485
572
|
!_isEmpty(selectedTickets) &&
|
|
486
|
-
Object.values(selectedTickets)[0] > 0
|
|
573
|
+
Number(Object.values(selectedTickets)[0]) > 0
|
|
487
574
|
) {
|
|
488
575
|
handleBook()
|
|
489
576
|
} else {
|
|
@@ -519,10 +606,10 @@ export const TicketsContainer = ({
|
|
|
519
606
|
|
|
520
607
|
const wrappedActionsSectionComponent = React.isValidElement(ActionsSectionComponent)
|
|
521
608
|
? React.cloneElement(ActionsSectionComponent as React.ReactElement<any>, {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
609
|
+
handleGetTicketClick,
|
|
610
|
+
isTicketOnSale,
|
|
611
|
+
isTicketAvailable,
|
|
612
|
+
})
|
|
526
613
|
: null
|
|
527
614
|
|
|
528
615
|
const externalUrl = event?.redirectUrl
|
|
@@ -564,16 +651,17 @@ export const TicketsContainer = ({
|
|
|
564
651
|
)}. \n If you pre-registered, log into your account first to buy your pre-sale ticket.`
|
|
565
652
|
|
|
566
653
|
const tableTickets = _filter(tickets, (ticket: any) => ticket.isTable)
|
|
567
|
-
const
|
|
654
|
+
const ordinaryTickets = {} as ITicket
|
|
568
655
|
_forEach(tickets, (ticket: any, key: string) => {
|
|
569
656
|
if (!ticket.isTable) {
|
|
570
|
-
|
|
657
|
+
ordinaryTickets[key] = ticket
|
|
571
658
|
}
|
|
572
659
|
})
|
|
660
|
+
|
|
573
661
|
return (
|
|
574
662
|
<ThemeProvider theme={themeMui}>
|
|
575
663
|
{!isLoading && <ReferralLogic eventId={eventId} />}
|
|
576
|
-
<div className={`get-tickets-page ${theme}`} style={contentStyle}>
|
|
664
|
+
<div className={`get-tickets-page ${theme} open-ground`} style={contentStyle}>
|
|
577
665
|
{isInvalidLinkError && (
|
|
578
666
|
<ConfirmModal
|
|
579
667
|
message={isInvalidLinkError}
|
|
@@ -588,7 +676,7 @@ export const TicketsContainer = ({
|
|
|
588
676
|
message={isNotInvitedError}
|
|
589
677
|
onClose={() => onClose('notInvited')}
|
|
590
678
|
onConfirm={() => onClose('notInvited')}
|
|
591
|
-
|
|
679
|
+
// loading={removeFromResaleLoading}
|
|
592
680
|
/>
|
|
593
681
|
)}
|
|
594
682
|
{error && (
|
|
@@ -612,11 +700,31 @@ export const TicketsContainer = ({
|
|
|
612
700
|
{isLoading ? (
|
|
613
701
|
<Loader />
|
|
614
702
|
) : (
|
|
615
|
-
<div ref={ticketsContainerRef}>
|
|
616
|
-
{
|
|
703
|
+
<div ref={ticketsContainerRef} className="tickets-section-container">
|
|
704
|
+
{isTimeSlotEvent && (
|
|
705
|
+
<TimeSlotsSection
|
|
706
|
+
event={event}
|
|
707
|
+
eventId={eventId}
|
|
708
|
+
availableDates={availableDates}
|
|
709
|
+
selectedDate={selectedDate}
|
|
710
|
+
setSelectedDate={setSelectedDate}
|
|
711
|
+
timeSlotGroups={timeSlotGroups}
|
|
712
|
+
setTimeSlotGroups={setTimeSlotGroups}
|
|
713
|
+
selectedTickets={selectedTickets}
|
|
714
|
+
handleTicketSelect={handleTicketSelect}
|
|
715
|
+
sortBySoldOut={sortBySoldOut}
|
|
716
|
+
ticketsHeaderComponent={ticketsHeaderComponent}
|
|
717
|
+
hideTicketsHeader={hideTicketsHeader}
|
|
718
|
+
showGroupNameBlock={showGroupNameBlock}
|
|
719
|
+
currencySymbol={currencySymbol}
|
|
720
|
+
isSeatMapAllowed={isSeatMapAllowed}
|
|
721
|
+
getTimeSlots={getTimeSlots}
|
|
722
|
+
/>
|
|
723
|
+
)}
|
|
724
|
+
{!isSalesClosed && !isTimeSlotEvent && (
|
|
617
725
|
<TicketsSection
|
|
618
726
|
event={event}
|
|
619
|
-
ticketsList={
|
|
727
|
+
ticketsList={ordinaryTickets}
|
|
620
728
|
tableTickets={tableTickets}
|
|
621
729
|
selectedTickets={selectedTickets}
|
|
622
730
|
handleTicketSelect={handleTicketSelect}
|
|
@@ -624,15 +732,17 @@ export const TicketsContainer = ({
|
|
|
624
732
|
ticketsHeaderComponent={ticketsHeaderComponent}
|
|
625
733
|
tableTicketsHeaderComponent={tableTicketsHeaderComponent}
|
|
626
734
|
hideTableTicketsHeader={hideTableTicketsHeader || _isEmpty(tableTickets)}
|
|
627
|
-
hideTicketsHeader={hideTicketsHeader || _isEmpty(
|
|
735
|
+
hideTicketsHeader={hideTicketsHeader || _isEmpty(ordinaryTickets)}
|
|
628
736
|
showGroupNameBlock={showGroupNameBlock}
|
|
629
|
-
|
|
737
|
+
currencySymbol={currencySymbol}
|
|
630
738
|
isSeatMapAllowed={isSeatMapAllowed}
|
|
631
739
|
/>
|
|
632
740
|
)}
|
|
633
741
|
{externalUrl ? null : isSalesClosed ? (
|
|
634
742
|
<p
|
|
635
|
-
className={`event-closed-message ${
|
|
743
|
+
className={`event-closed-message ${
|
|
744
|
+
!isLoggedIn ? 'event-closed-on-bottom' : ''
|
|
745
|
+
}`}
|
|
636
746
|
>
|
|
637
747
|
Sales for this event are closed.
|
|
638
748
|
</p>
|
|
@@ -650,7 +760,7 @@ export const TicketsContainer = ({
|
|
|
650
760
|
) : null}
|
|
651
761
|
{showWaitingList && event.salesStarted && !hideWaitingList && (
|
|
652
762
|
<WaitingList
|
|
653
|
-
tickets={
|
|
763
|
+
tickets={ordinaryTickets}
|
|
654
764
|
eventId={eventId}
|
|
655
765
|
defaultMaxQuantity={event.waitingListMaxQuantity}
|
|
656
766
|
/>
|
|
@@ -682,16 +792,16 @@ export const TicketsContainer = ({
|
|
|
682
792
|
{canShowGetTicketBtn() && (
|
|
683
793
|
<Button
|
|
684
794
|
aria-hidden={true}
|
|
685
|
-
className={`book-button
|
|
686
|
-
${bookButtonIsDisabled ? 'disabled' : ''}
|
|
795
|
+
className={`book-button
|
|
796
|
+
${bookButtonIsDisabled ? 'disabled' : ''}
|
|
687
797
|
${isButtonScrollable ? 'is-scrollable' : ''}
|
|
688
798
|
${!isLoggedIn ? 'on-bottom' : ''}
|
|
689
799
|
`}
|
|
690
800
|
onClick={
|
|
691
801
|
event?.salesStart &&
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
802
|
+
event?.presalesStarted &&
|
|
803
|
+
!event?.presalesEnded &&
|
|
804
|
+
(!isPreregistered || !isLogged)
|
|
695
805
|
? handleNotAvailableTicketsClick
|
|
696
806
|
: handleGetTicketClick
|
|
697
807
|
}
|
|
@@ -3,6 +3,7 @@ import './style.css'
|
|
|
3
3
|
import _identity from 'lodash/identity'
|
|
4
4
|
import React, { memo, useState } from 'react'
|
|
5
5
|
import Countdown from 'react-countdown'
|
|
6
|
+
import ReactDOM from 'react-dom'
|
|
6
7
|
import SVG from 'react-inlinesvg'
|
|
7
8
|
|
|
8
9
|
import Cross from '../../assets/images/cross.svg'
|
|
@@ -12,6 +13,7 @@ export interface ITimerWidgetPage {
|
|
|
12
13
|
expires_at: number;
|
|
13
14
|
buyLoading?: boolean;
|
|
14
15
|
onCountdownFinish?: () => void;
|
|
16
|
+
container?: string;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export interface IRenderer {
|
|
@@ -25,6 +27,7 @@ const TimerWidget = ({
|
|
|
25
27
|
expires_at,
|
|
26
28
|
buyLoading,
|
|
27
29
|
onCountdownFinish = _identity,
|
|
30
|
+
container,
|
|
28
31
|
}: ITimerWidgetPage) => {
|
|
29
32
|
const [showTimer, setShowTimer] = useState(true)
|
|
30
33
|
|
|
@@ -59,9 +62,9 @@ const TimerWidget = ({
|
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
|
|
65
|
+
const timerComponent = (
|
|
63
66
|
<div className="timer">
|
|
64
|
-
<div className="close-icon" onClick={hideTimer}>
|
|
67
|
+
<div aria-hidden className="close-icon" onClick={hideTimer}>
|
|
65
68
|
<SVG src={Cross} width="10" height="10" fill="#fff" />
|
|
66
69
|
</div>
|
|
67
70
|
<div className="toast-message">
|
|
@@ -79,7 +82,16 @@ const TimerWidget = ({
|
|
|
79
82
|
</p>
|
|
80
83
|
</div>
|
|
81
84
|
</div>
|
|
82
|
-
)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return showTimer && !!expires_at
|
|
88
|
+
? container
|
|
89
|
+
? ReactDOM.createPortal(
|
|
90
|
+
timerComponent,
|
|
91
|
+
document.querySelector(container) as HTMLElement
|
|
92
|
+
)
|
|
93
|
+
: timerComponent
|
|
94
|
+
: null
|
|
83
95
|
}
|
|
84
96
|
|
|
85
97
|
export default memo(TimerWidget)
|
package/src/constants/index.ts
CHANGED