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.
- package/README.md +401 -59
- package/dist/adapters/customFields.d.ts +1 -0
- package/dist/api/checkout.d.ts +2 -0
- package/dist/api/common.d.ts +1 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/preRegistrationComplete.d.ts +1 -1
- package/dist/components/addonsContainer/AddonComponent.d.ts +6 -1
- package/dist/components/addonsContainer/SimpleAddonsContainer.d.ts +17 -0
- package/dist/components/addonsContainer/index.d.ts +6 -1
- package/dist/components/billing-info-container/hooks/index.d.ts +3 -0
- package/dist/components/billing-info-container/hooks/usePaymentContext.d.ts +5 -0
- package/dist/components/billing-info-container/hooks/usePaymentRedirect.d.ts +14 -0
- package/dist/components/billing-info-container/hooks/useStripePayment.d.ts +18 -0
- package/dist/components/billing-info-container/index.d.ts +13 -2
- package/dist/components/billing-info-container/utils.d.ts +26 -1
- package/dist/components/common/DatePickerField.d.ts +7 -1
- package/dist/components/common/PhoneNumberField.d.ts +1 -1
- package/dist/components/confirmationContainer/index.d.ts +4 -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 +8 -1
- package/dist/components/paymentContainer/OrderDetails.d.ts +9 -0
- package/dist/components/paymentContainer/handlePayment.d.ts +15 -0
- package/dist/components/paymentContainer/index.d.ts +12 -6
- package/dist/components/preRegistration/FieldsSection.d.ts +7 -1
- package/dist/components/preRegistration/PreRegistrationComplete.d.ts +8 -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/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 +29 -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 +11284 -9565
- 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 +11293 -9577
- 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 +3 -1
- package/dist/utils/auth.d.ts +8 -0
- package/dist/utils/createCheckoutDataBodyWithDefaultHolder.d.ts +1 -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 +14 -8
- package/src/adapters/customFields.ts +7 -1
- package/src/api/auth.ts +2 -1
- package/src/api/checkout.ts +9 -4
- package/src/api/common.ts +49 -2
- package/src/api/index.ts +1 -0
- 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 +96 -11
- package/src/components/addonsContainer/SimpleAddonsContainer.tsx +420 -0
- package/src/components/addonsContainer/index.tsx +198 -47
- package/src/components/billing-info-container/hooks/index.ts +3 -0
- package/src/components/billing-info-container/hooks/usePaymentContext.ts +22 -0
- package/src/components/billing-info-container/hooks/usePaymentRedirect.ts +147 -0
- package/src/components/billing-info-container/hooks/useStripePayment.ts +121 -0
- package/src/components/billing-info-container/index.tsx +859 -418
- package/src/components/billing-info-container/{utils.ts → utils.tsx} +124 -1
- package/src/components/common/CheckboxField/index.tsx +1 -1
- package/src/components/common/CustomField.tsx +39 -3
- package/src/components/common/DatePickerField.tsx +25 -10
- package/src/components/common/PhoneNumberField.tsx +4 -2
- package/src/components/common/SnackbarAlert.tsx +32 -34
- package/src/components/confirmationContainer/config.ts +3 -3
- package/src/components/confirmationContainer/index.tsx +20 -1
- package/src/components/confirmationContainer/social-buttons.tsx +5 -3
- package/src/components/confirmationContainer/style.css +9 -5
- 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 +19 -27
- package/src/components/loginModal/style.css +3 -1
- package/src/components/myTicketsContainer/index.tsx +13 -9
- package/src/components/orderDetailsContainer/index.tsx +206 -174
- package/src/components/paymentContainer/OrderDetails.tsx +257 -0
- package/src/components/paymentContainer/handlePayment.ts +86 -0
- package/src/components/paymentContainer/index.tsx +299 -259
- package/src/components/paymentContainer/style.css +141 -0
- package/src/components/preRegistration/FieldsSection.tsx +8 -0
- package/src/components/preRegistration/PreRegistrationComplete.tsx +138 -118
- package/src/components/preRegistration/PreRegistrationInformations.tsx +21 -15
- package/src/components/preRegistration/constants.tsx +10 -4
- package/src/components/preRegistration/index.tsx +233 -179
- package/src/components/preRegistration/style.css +3 -0
- package/src/components/registerForm/constants.tsx +3 -1
- package/src/components/registerForm/index.tsx +3 -3
- package/src/components/registerModal/index.tsx +47 -72
- package/src/components/resetPasswordContainer/index.tsx +20 -14
- package/src/components/seatMapContainer/TicketsSection.tsx +2 -2
- package/src/components/signupModal/index.tsx +13 -6
- package/src/components/ticketResale/index.tsx +7 -0
- 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 +189 -57
- package/src/components/ticketsContainer/TimeSlotsSection.tsx +120 -0
- package/src/components/ticketsContainer/index.tsx +268 -106
- package/src/components/timerWidget/index.tsx +15 -3
- package/src/components/timerWidget/style.css +2 -1
- package/src/constants/index.ts +2 -0
- package/src/env.ts +14 -6
- 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/cart.d.ts +8 -0
- package/src/types/api/checkout.d.ts +58 -7
- package/src/types/api/common.d.ts +30 -0
- package/src/types/api/orders.d.ts +19 -3
- package/src/types/api/payment.d.ts +6 -2
- package/src/types/api/preRegistrationComplete.d.ts +2 -2
- package/src/types/checkoutPageConfigs.ts +1 -1
- package/src/types/order-data.ts +3 -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/createCheckoutDataBodyWithDefaultHolder.ts +3 -1
- 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
- package/dist/components/stripePayment/index.d.ts +0 -24
- package/src/components/stripePayment/index.tsx +0 -281
- 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 {
|
|
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'
|
|
@@ -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:
|
|
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:
|
|
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?:
|
|
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
|
-
|
|
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
|
-
|
|
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 [
|
|
232
|
+
const [preregisteredUsers, setPreregisteredUsers] = useState(
|
|
233
|
+
[] as Array<IInfluencerData>
|
|
234
|
+
)
|
|
188
235
|
const [ticketsNotAvailableModalOpen, setTicketsNotAvailableModalOpen] = useState(false)
|
|
189
|
-
const [
|
|
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
|
|
195
|
-
|
|
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
|
-
|
|
263
|
+
fetchPreregisteredData()
|
|
207
264
|
}
|
|
265
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
208
266
|
}, [eventId])
|
|
209
267
|
|
|
210
268
|
useEffect(() => {
|
|
211
|
-
|
|
212
|
-
}, [
|
|
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
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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
|
|
404
|
+
async function fetchPreregisteredData() {
|
|
298
405
|
try {
|
|
299
|
-
const preregistrationData = await
|
|
406
|
+
const preregistrationData = await getPreRegistrationInfluencers({
|
|
300
407
|
eventId,
|
|
301
408
|
})
|
|
302
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
379
|
-
|
|
380
|
-
|
|
479
|
+
status: 200,
|
|
480
|
+
data: { attributes: _get(result, 'data.attributes') },
|
|
481
|
+
}
|
|
381
482
|
|
|
382
|
-
if (
|
|
383
|
-
const pageConfigsData =
|
|
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
|
-
|
|
424
|
-
|
|
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 = (
|
|
451
|
-
getTicketsApi(
|
|
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 =
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
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
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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
|
|
678
|
+
const ordinaryTickets = {} as ITicket
|
|
568
679
|
_forEach(tickets, (ticket: any, key: string) => {
|
|
569
680
|
if (!ticket.isTable) {
|
|
570
|
-
|
|
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
|
-
|
|
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
|
-
{
|
|
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={
|
|
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(
|
|
784
|
+
hideTicketsHeader={hideTicketsHeader || _isEmpty(ordinaryTickets)}
|
|
628
785
|
showGroupNameBlock={showGroupNameBlock}
|
|
629
|
-
|
|
786
|
+
currencySymbol={currencySymbol}
|
|
630
787
|
isSeatMapAllowed={isSeatMapAllowed}
|
|
631
788
|
/>
|
|
632
789
|
)}
|
|
633
790
|
{externalUrl ? null : isSalesClosed ? (
|
|
634
791
|
<p
|
|
635
|
-
className={`event-closed-message ${
|
|
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
|
-
{
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
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
|
-
|
|
693
|
-
|
|
694
|
-
|
|
854
|
+
event?.presalesStarted &&
|
|
855
|
+
!event?.presalesEnded &&
|
|
856
|
+
(!isPreregistered || !isLogged)
|
|
695
857
|
? handleNotAvailableTicketsClick
|
|
696
858
|
: handleGetTicketClick
|
|
697
859
|
}
|