tf-checkout-react 1.0.106 → 1.2.1
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 +278 -1
- package/dist/api/index.d.ts +40 -28
- package/dist/components/account-settings/index.d.ts +3 -0
- package/dist/components/billing-info-container/index.d.ts +11 -8
- package/dist/components/common/PhoneNumberField.d.ts +9 -0
- package/dist/components/common/index.d.ts +1 -0
- package/dist/components/confirmationContainer/index.d.ts +2 -1
- package/dist/components/countdown/index.d.ts +2 -1
- package/dist/components/forgotPasswordModal/index.d.ts +11 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/loginModal/index.d.ts +35 -2
- package/dist/components/myTicketsContainer/index.d.ts +2 -1
- package/dist/components/myTicketsContainer/tableConfig.d.ts +1 -1
- package/dist/components/orderDetailsContainer/index.d.ts +6 -1
- package/dist/components/orderDetailsContainer/ticketsTable.d.ts +2 -1
- package/dist/components/paymentContainer/index.d.ts +2 -1
- package/dist/components/resetPasswordContainer/index.d.ts +10 -0
- package/dist/components/signupModal/index.d.ts +14 -0
- package/dist/components/ticketsContainer/PromoCodeSection.d.ts +3 -2
- package/dist/components/ticketsContainer/TicketsSection.d.ts +1 -2
- package/dist/components/ticketsContainer/index.d.ts +7 -3
- package/dist/index.d.ts +2 -0
- package/dist/tf-checkout-react.cjs.development.js +2177 -1482
- 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 +2166 -1473
- package/dist/tf-checkout-react.esm.js.map +1 -1
- package/dist/tf-checkout-styles.css +1 -1
- package/dist/utils/cookies.d.ts +3 -0
- package/dist/utils/createCheckoutDataBodyWithDefaultHolder.d.ts +6 -1
- package/dist/utils/downloadPDF.d.ts +1 -1
- package/dist/utils/getDomain.d.ts +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/package.json +12 -1
- package/src/api/index.ts +100 -29
- package/src/components/account-settings/index.tsx +161 -0
- package/src/components/account-settings/style.css +200 -0
- package/src/components/billing-info-container/index.tsx +145 -99
- package/src/components/billing-info-container/style.css +1 -1
- package/src/components/billing-info-container/utils.ts +11 -3
- package/src/components/common/PhoneNumberField.tsx +68 -0
- package/src/components/common/SnackbarAlert.tsx +1 -1
- package/src/components/common/dist/PhoneNumberField.js +96 -0
- package/src/components/common/index.tsx +1 -0
- package/src/components/confirmationContainer/index.tsx +19 -9
- package/src/components/countdown/index.tsx +3 -1
- package/src/components/forgotPasswordModal/index.tsx +107 -0
- package/src/components/forgotPasswordModal/style.css +47 -0
- package/src/components/index.ts +1 -0
- package/src/components/loginModal/index.tsx +72 -71
- package/src/components/myTicketsContainer/index.tsx +99 -95
- package/src/components/myTicketsContainer/style.css +2 -2
- package/src/components/myTicketsContainer/tableConfig.tsx +3 -6
- package/src/components/orderDetailsContainer/index.tsx +80 -21
- package/src/components/orderDetailsContainer/style.css +7 -3
- package/src/components/orderDetailsContainer/ticketsTable.tsx +130 -83
- package/src/components/paymentContainer/index.tsx +114 -49
- package/src/components/registerModal/index.tsx +3 -10
- package/src/components/resetPasswordContainer/index.tsx +96 -0
- package/src/components/resetPasswordContainer/style.css +36 -0
- package/src/components/signupModal/index.tsx +195 -0
- package/src/components/signupModal/style.css +58 -0
- package/src/components/stripePayment/index.tsx +14 -12
- package/src/components/stripePayment/style.css +3 -3
- package/src/components/ticketResaleModal/index.tsx +12 -14
- package/src/components/ticketsContainer/PromoCodeSection.tsx +8 -7
- package/src/components/ticketsContainer/TicketRow.tsx +12 -6
- package/src/components/ticketsContainer/TicketsSection.tsx +0 -3
- package/src/components/ticketsContainer/index.tsx +155 -86
- package/src/env.ts +3 -3
- package/src/index.ts +3 -1
- package/src/utils/cookies.ts +42 -0
- package/src/utils/createCheckoutDataBodyWithDefaultHolder.ts +16 -4
- package/src/utils/downloadPDF.tsx +28 -6
- package/src/utils/getDomain.ts +15 -0
- package/src/utils/index.ts +2 -0
|
@@ -1,32 +1,38 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef, ReactNode } from 'react'
|
|
2
|
-
import axios, { AxiosError } from 'axios'
|
|
3
|
-
import { Loader } from '../common/index'
|
|
4
1
|
import './style.css'
|
|
5
2
|
|
|
3
|
+
import { createTheme, ThemeOptions } from '@mui/material'
|
|
4
|
+
import { ThemeProvider } from '@mui/private-theming'
|
|
5
|
+
import { CSSProperties } from '@mui/styles'
|
|
6
|
+
import axios, { AxiosError } from 'axios'
|
|
7
|
+
import jwt_decode from 'jwt-decode'
|
|
8
|
+
import _find from 'lodash/find'
|
|
9
|
+
import _get from 'lodash/get'
|
|
10
|
+
import _isEmpty from 'lodash/isEmpty'
|
|
11
|
+
import _some from 'lodash/some'
|
|
12
|
+
import React, { ReactNode,useEffect, useRef, useState } from 'react'
|
|
13
|
+
import Button from 'react-bootstrap/Button'
|
|
14
|
+
|
|
6
15
|
import {
|
|
7
|
-
getTickets,
|
|
8
|
-
getEvent,
|
|
9
16
|
addToCart,
|
|
17
|
+
getEvent,
|
|
18
|
+
getTickets,
|
|
19
|
+
logout,
|
|
10
20
|
postOnCheckout,
|
|
11
21
|
} from '../../api'
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import
|
|
19
|
-
import
|
|
22
|
+
import {
|
|
23
|
+
createCheckoutDataBodyWithDefaultHolder,
|
|
24
|
+
deleteCookieByName,
|
|
25
|
+
getCookieByName,
|
|
26
|
+
getQueryVariable,
|
|
27
|
+
} from '../../utils'
|
|
28
|
+
import { Loader } from '../common/index'
|
|
29
|
+
import Countdown from '../countdown'
|
|
30
|
+
import { LoginModal } from '../loginModal'
|
|
20
31
|
import WaitingList from '../waitingList'
|
|
21
|
-
import { PromoCodeSection } from './PromoCodeSection'
|
|
22
32
|
import { AccessCodeSection } from './AccessCodeSection'
|
|
23
|
-
import {
|
|
24
|
-
import Countdown from '../countdown'
|
|
25
|
-
import { createCheckoutDataBodyWithDefaultHolder, getQueryVariable } from '../../utils'
|
|
26
|
-
import { ThemeProvider } from '@mui/private-theming'
|
|
27
|
-
import { createTheme, ThemeOptions } from '@mui/material'
|
|
28
|
-
import { CSSProperties } from '@mui/styles'
|
|
33
|
+
import { PromoCodeSection } from './PromoCodeSection'
|
|
29
34
|
import { ReferralLogic } from './ReferralLogic'
|
|
35
|
+
import { TicketsSection } from './TicketsSection'
|
|
30
36
|
|
|
31
37
|
interface CartSuccess {
|
|
32
38
|
skip_billing_page: boolean;
|
|
@@ -46,22 +52,29 @@ export interface IGetTickets {
|
|
|
46
52
|
onAddToCartError: (e: AxiosError) => void;
|
|
47
53
|
onGetTicketsSuccess: (response: any) => void;
|
|
48
54
|
onGetTicketsError: (e: AxiosError) => void;
|
|
55
|
+
onLogoutSuccess: () => void;
|
|
56
|
+
onLogoutError: (e: AxiosError) => void;
|
|
49
57
|
onLoginSuccess: () => void;
|
|
50
58
|
|
|
51
59
|
theme?: 'light' | 'dark';
|
|
52
60
|
queryPromoCode?: string;
|
|
53
61
|
isPromotionsEnabled?: boolean;
|
|
54
|
-
themeOptions?: ThemeOptions & {
|
|
62
|
+
themeOptions?: ThemeOptions & {
|
|
63
|
+
input?: CSSProperties;
|
|
64
|
+
checkbox?: CSSProperties;
|
|
65
|
+
};
|
|
55
66
|
isAccessCodeEnabled?: boolean;
|
|
56
67
|
hideSessionButtons?: boolean;
|
|
57
68
|
hideWaitingList?: boolean;
|
|
69
|
+
enableBillingInfoAutoCreate?: boolean;
|
|
58
70
|
isButtonScrollable?: boolean;
|
|
59
71
|
sortBySoldOut?: boolean;
|
|
60
72
|
disableCountdownLeadingZero?: boolean;
|
|
61
73
|
isLoggedIn?: boolean;
|
|
62
74
|
actionsSectionComponent?: any;
|
|
63
|
-
ticketsHeaderComponent?: ReactNode
|
|
64
|
-
hideTicketsHeader?: boolean
|
|
75
|
+
ticketsHeaderComponent?: ReactNode;
|
|
76
|
+
hideTicketsHeader?: boolean;
|
|
77
|
+
enableInfluencersSection?: boolean;
|
|
65
78
|
}
|
|
66
79
|
|
|
67
80
|
export interface ITicket {
|
|
@@ -69,6 +82,9 @@ export interface ITicket {
|
|
|
69
82
|
[key: string]: string | number;
|
|
70
83
|
}
|
|
71
84
|
|
|
85
|
+
interface IInfluencer {
|
|
86
|
+
[key: string]: string | undefined;
|
|
87
|
+
}
|
|
72
88
|
export interface ISelectedTickets {
|
|
73
89
|
[key: string]: string | number;
|
|
74
90
|
}
|
|
@@ -82,6 +98,8 @@ export const TicketsContainer = ({
|
|
|
82
98
|
onAddToCartError = () => {},
|
|
83
99
|
onGetTicketsSuccess = () => {},
|
|
84
100
|
onGetTicketsError = () => {},
|
|
101
|
+
onLogoutSuccess = () => {},
|
|
102
|
+
onLogoutError = () => {},
|
|
85
103
|
theme = 'light',
|
|
86
104
|
queryPromoCode = '',
|
|
87
105
|
isPromotionsEnabled = true,
|
|
@@ -89,20 +107,22 @@ export const TicketsContainer = ({
|
|
|
89
107
|
isAccessCodeEnabled = false,
|
|
90
108
|
hideSessionButtons = false,
|
|
91
109
|
hideWaitingList = false,
|
|
110
|
+
enableBillingInfoAutoCreate = true,
|
|
92
111
|
isButtonScrollable = false,
|
|
93
112
|
sortBySoldOut = false,
|
|
94
113
|
disableCountdownLeadingZero = false,
|
|
95
114
|
isLoggedIn = false,
|
|
96
|
-
actionsSectionComponent
|
|
115
|
+
actionsSectionComponent: ActionsSectionComponent,
|
|
97
116
|
ticketsHeaderComponent,
|
|
98
|
-
hideTicketsHeader = false
|
|
117
|
+
hideTicketsHeader = false,
|
|
118
|
+
enableInfluencersSection = true
|
|
99
119
|
}: IGetTickets) => {
|
|
100
|
-
const [selectedTickets, setSelectedTickets] = useState(
|
|
101
|
-
{} as ISelectedTickets
|
|
102
|
-
)
|
|
120
|
+
const [selectedTickets, setSelectedTickets] = useState({} as ISelectedTickets)
|
|
103
121
|
const isWindowDefined = typeof window !== 'undefined'
|
|
122
|
+
const xtfCookie = getCookieByName('X-TF-ECOMMERCE')
|
|
104
123
|
const [isLogged, setIsLogged] = useState(
|
|
105
|
-
isWindowDefined ? !!window.localStorage.getItem('access_token') : false
|
|
124
|
+
(isWindowDefined ? !!window.localStorage.getItem('access_token') : false) ||
|
|
125
|
+
!!xtfCookie
|
|
106
126
|
)
|
|
107
127
|
const [showLoginModal, setShowLoginModal] = useState(false)
|
|
108
128
|
const [tickets, setTickets] = useState([] as ITicket[])
|
|
@@ -136,13 +156,20 @@ export const TicketsContainer = ({
|
|
|
136
156
|
!!eventId && getTicketsApi()
|
|
137
157
|
}, [eventId])
|
|
138
158
|
|
|
139
|
-
const handleLogout = () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
159
|
+
const handleLogout = async () => {
|
|
160
|
+
try {
|
|
161
|
+
await logout()
|
|
162
|
+
onLogoutSuccess()
|
|
163
|
+
if (isWindowDefined) {
|
|
164
|
+
window.localStorage.removeItem('access_token')
|
|
165
|
+
window.localStorage.removeItem('user_data')
|
|
166
|
+
setIsLogged(false)
|
|
167
|
+
const event = new window.CustomEvent('tf-logout')
|
|
168
|
+
deleteCookieByName('X-TF-ECOMMERCE')
|
|
169
|
+
window.document.dispatchEvent(event)
|
|
170
|
+
}
|
|
171
|
+
} catch (e) {
|
|
172
|
+
onLogoutError(e)
|
|
146
173
|
}
|
|
147
174
|
}
|
|
148
175
|
|
|
@@ -154,10 +181,12 @@ export const TicketsContainer = ({
|
|
|
154
181
|
: {}
|
|
155
182
|
if (userData.country === '') {
|
|
156
183
|
handleLogout()
|
|
157
|
-
window.open(
|
|
184
|
+
window.open(
|
|
185
|
+
'https://www.ticketfairy.com/account/change_information?need_country=true'
|
|
186
|
+
)
|
|
158
187
|
}
|
|
159
188
|
}
|
|
160
|
-
} catch(e) {}
|
|
189
|
+
} catch (e) {}
|
|
161
190
|
}, [])
|
|
162
191
|
|
|
163
192
|
const handleExternalLogin = () => {
|
|
@@ -174,14 +203,14 @@ export const TicketsContainer = ({
|
|
|
174
203
|
}
|
|
175
204
|
}
|
|
176
205
|
|
|
177
|
-
async function getTicketsApi(isUpdateingCode?: boolean) {
|
|
206
|
+
async function getTicketsApi(isUpdateingCode?: boolean, type?: string) {
|
|
178
207
|
try {
|
|
179
208
|
isUpdateingCode ? setCodeIsLoading(true) : setIsLoading(true)
|
|
180
209
|
const response = await getTickets(eventId, code)
|
|
181
210
|
const eventResponse = await getEvent(eventId)
|
|
182
211
|
if (response.data.success) {
|
|
183
212
|
const attributes = _get(response, 'data.data.attributes')
|
|
184
|
-
setCodeIsApplied(attributes.ValidPromoCode)
|
|
213
|
+
type === 'promo' && setCodeIsApplied(attributes.ValidPromoCode)
|
|
185
214
|
setTickets(_get(attributes, 'tickets'))
|
|
186
215
|
setShowWaitingList(attributes.showWaitingList)
|
|
187
216
|
onGetTicketsSuccess(response.data)
|
|
@@ -251,7 +280,6 @@ export const TicketsContainer = ({
|
|
|
251
280
|
try {
|
|
252
281
|
const result = await addToCart(eventId, data)
|
|
253
282
|
if (result.status === 200) {
|
|
254
|
-
|
|
255
283
|
const skipBillingPage =
|
|
256
284
|
result?.data?.data?.attributes?.skip_billing_page ?? false
|
|
257
285
|
const nameIsRequired =
|
|
@@ -282,10 +310,9 @@ export const TicketsContainer = ({
|
|
|
282
310
|
userData
|
|
283
311
|
)
|
|
284
312
|
|
|
285
|
-
const checkoutResult =
|
|
286
|
-
checkoutBody,
|
|
287
|
-
|
|
288
|
-
)
|
|
313
|
+
const checkoutResult = enableBillingInfoAutoCreate
|
|
314
|
+
? await postOnCheckout(checkoutBody, access_token)
|
|
315
|
+
: null
|
|
289
316
|
|
|
290
317
|
hash = _get(checkoutResult, 'data.data.attributes.hash')
|
|
291
318
|
total = _get(checkoutResult, 'data.data.attributes.total')
|
|
@@ -298,7 +325,7 @@ export const TicketsContainer = ({
|
|
|
298
325
|
age_required: ageIsRequired,
|
|
299
326
|
event_id: String(eventId),
|
|
300
327
|
hash,
|
|
301
|
-
total
|
|
328
|
+
total,
|
|
302
329
|
})
|
|
303
330
|
}
|
|
304
331
|
} catch (e) {
|
|
@@ -310,17 +337,20 @@ export const TicketsContainer = ({
|
|
|
310
337
|
}
|
|
311
338
|
}
|
|
312
339
|
|
|
313
|
-
const updateTickets = (isUpdateingCode?: boolean) => {
|
|
314
|
-
getTicketsApi(isUpdateingCode)
|
|
340
|
+
const updateTickets = (isUpdateingCode?: boolean, type?: string) => {
|
|
341
|
+
getTicketsApi(isUpdateingCode, type)
|
|
315
342
|
}
|
|
316
343
|
|
|
317
344
|
const isTicketOnSale = _some(
|
|
318
345
|
tickets,
|
|
319
|
-
item =>
|
|
346
|
+
item => item.salesStarted && !item.salesEnded && !item.soldOut
|
|
320
347
|
)
|
|
321
348
|
|
|
349
|
+
const eventHasTickets = !_isEmpty(tickets)
|
|
350
|
+
const isSalesClosed = event?.salesEnded
|
|
351
|
+
|
|
322
352
|
const themeMui = createTheme(themeOptions)
|
|
323
|
-
|
|
353
|
+
|
|
324
354
|
useEffect(() => {
|
|
325
355
|
isWindowDefined &&
|
|
326
356
|
window.document.addEventListener('custom-logout', handleLogout)
|
|
@@ -335,32 +365,49 @@ export const TicketsContainer = ({
|
|
|
335
365
|
window.document.addEventListener('custom-login', handleExternalLogin)
|
|
336
366
|
return () => {
|
|
337
367
|
isWindowDefined &&
|
|
338
|
-
window.document.removeEventListener(
|
|
339
|
-
'custom-login',
|
|
340
|
-
handleExternalLogin
|
|
341
|
-
)
|
|
368
|
+
window.document.removeEventListener('custom-login', handleExternalLogin)
|
|
342
369
|
}
|
|
343
370
|
}, [])
|
|
344
371
|
|
|
345
372
|
const handleGetTicketClick = () => {
|
|
346
|
-
if (
|
|
373
|
+
if (
|
|
374
|
+
!handleBookIsLoading &&
|
|
375
|
+
!_isEmpty(selectedTickets) &&
|
|
376
|
+
Object.values(selectedTickets)[0] > 0
|
|
377
|
+
) {
|
|
347
378
|
handleBook()
|
|
348
379
|
} else {
|
|
349
|
-
if (
|
|
350
|
-
|
|
380
|
+
if (
|
|
381
|
+
isButtonScrollable &&
|
|
382
|
+
ticketsContainerRef &&
|
|
383
|
+
ticketsContainerRef.current
|
|
384
|
+
) {
|
|
385
|
+
ticketsContainerRef.current.scrollIntoView({
|
|
386
|
+
behavior: 'smooth',
|
|
387
|
+
block: 'center',
|
|
388
|
+
inline: 'nearest',
|
|
389
|
+
})
|
|
351
390
|
}
|
|
352
391
|
}
|
|
353
392
|
}
|
|
354
393
|
|
|
355
|
-
const bookButtonIsDisabled =
|
|
394
|
+
const bookButtonIsDisabled =
|
|
395
|
+
handleBookIsLoading ||
|
|
396
|
+
_isEmpty(selectedTickets) ||
|
|
397
|
+
Object.values(selectedTickets)[0] === 0
|
|
356
398
|
|
|
357
|
-
const wrappedActionsSectionComponent = React.isValidElement(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
399
|
+
const wrappedActionsSectionComponent = React.isValidElement(
|
|
400
|
+
ActionsSectionComponent
|
|
401
|
+
)
|
|
402
|
+
? React.cloneElement(ActionsSectionComponent as React.ReactElement<any>, {
|
|
403
|
+
handleGetTicketClick,
|
|
404
|
+
isTicketOnSale,
|
|
405
|
+
})
|
|
406
|
+
: null
|
|
361
407
|
|
|
362
408
|
const externalUrl = event?.redirectUrl
|
|
363
409
|
const eventSaleIsNotStarted = !event?.salesStarted && event?.salesStart
|
|
410
|
+
const influencers = event?.referralsEnabled ? event?.referrals : []
|
|
364
411
|
|
|
365
412
|
return (
|
|
366
413
|
<ThemeProvider theme={themeMui}>
|
|
@@ -370,23 +417,27 @@ export const TicketsContainer = ({
|
|
|
370
417
|
<Loader />
|
|
371
418
|
) : (
|
|
372
419
|
<div ref={ticketsContainerRef}>
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
420
|
+
{!isSalesClosed && (
|
|
421
|
+
<TicketsSection
|
|
422
|
+
ticketsList={tickets}
|
|
423
|
+
selectedTickets={selectedTickets}
|
|
424
|
+
handleTicketSelect={handleTicketSelect}
|
|
425
|
+
sortBySoldOut={sortBySoldOut}
|
|
426
|
+
ticketsHeaderComponent={ticketsHeaderComponent}
|
|
427
|
+
hideTicketsHeader={hideTicketsHeader || _isEmpty(tickets)}
|
|
428
|
+
/>
|
|
429
|
+
)}
|
|
430
|
+
{externalUrl ? null : isSalesClosed ? (
|
|
431
|
+
<p className={`event-closed-message ${!isLoggedIn ? 'event-closed-on-bottom' : ''}`}>
|
|
432
|
+
Sales for this event are closed.
|
|
433
|
+
</p>
|
|
384
434
|
) : eventSaleIsNotStarted ? (
|
|
385
435
|
<Countdown
|
|
386
436
|
startDate={event.salesStart}
|
|
387
437
|
timezone={event.timezone}
|
|
388
438
|
title="Sales start in:"
|
|
389
439
|
message="No tickets are currently available for this event."
|
|
440
|
+
showMessage={!eventHasTickets}
|
|
390
441
|
callback={updateTickets}
|
|
391
442
|
disableLeadingZero={disableCountdownLeadingZero}
|
|
392
443
|
isLoggedIn={isLoggedIn}
|
|
@@ -395,10 +446,9 @@ export const TicketsContainer = ({
|
|
|
395
446
|
{showWaitingList && event.salesStarted && !hideWaitingList && (
|
|
396
447
|
<WaitingList tickets={tickets} eventId={eventId} />
|
|
397
448
|
)}
|
|
398
|
-
{
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
) : showAccessCodeSection ? (
|
|
449
|
+
{codeIsLoading ? (
|
|
450
|
+
<Loader />
|
|
451
|
+
) : isSalesClosed ? null : showAccessCodeSection ? (
|
|
402
452
|
<AccessCodeSection
|
|
403
453
|
code={code}
|
|
404
454
|
setCode={setCode}
|
|
@@ -408,6 +458,7 @@ export const TicketsContainer = ({
|
|
|
408
458
|
<PromoCodeSection
|
|
409
459
|
code={code}
|
|
410
460
|
codeIsApplied={codeIsApplied}
|
|
461
|
+
setCodeIsApplied={setCodeIsApplied}
|
|
411
462
|
showPromoInput={showPromoInput}
|
|
412
463
|
setShowPromoInput={setShowPromoInput}
|
|
413
464
|
setCode={setCode}
|
|
@@ -416,19 +467,23 @@ export const TicketsContainer = ({
|
|
|
416
467
|
) : null
|
|
417
468
|
}
|
|
418
469
|
{wrappedActionsSectionComponent}
|
|
419
|
-
{!wrappedActionsSectionComponent &&
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
470
|
+
{!wrappedActionsSectionComponent &&
|
|
471
|
+
!eventSaleIsNotStarted &&
|
|
472
|
+
isTicketOnSale &&
|
|
473
|
+
!event?.salesEnded &&
|
|
474
|
+
!externalUrl && (
|
|
475
|
+
<Button
|
|
476
|
+
aria-hidden={true}
|
|
477
|
+
className={`book-button
|
|
423
478
|
${bookButtonIsDisabled ? 'disabled' : ''}
|
|
424
479
|
${isButtonScrollable ? 'is-scrollable' : ''}
|
|
425
480
|
${!isLoggedIn ? 'on-bottom' : ''}
|
|
426
481
|
`}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
482
|
+
onClick={handleGetTicketClick}
|
|
483
|
+
>
|
|
484
|
+
{getTicketsLabel || 'GET TICKETS'}
|
|
485
|
+
</Button>
|
|
486
|
+
)}
|
|
432
487
|
{isLogged && !hideSessionButtons ? (
|
|
433
488
|
<div className="session-wrapper">
|
|
434
489
|
<span className="session-container">
|
|
@@ -459,6 +514,20 @@ export const TicketsContainer = ({
|
|
|
459
514
|
<LoginModal onClose={handleOnClose} onLogin={handleOnLogin} />
|
|
460
515
|
) : null}
|
|
461
516
|
</div>
|
|
517
|
+
{enableInfluencersSection && influencers.length ? (
|
|
518
|
+
<div className="event-influencers">
|
|
519
|
+
<h3>
|
|
520
|
+
<span>TOP</span> INFLUENCERS
|
|
521
|
+
</h3>
|
|
522
|
+
<ol className="influencer-list">
|
|
523
|
+
{influencers.map((influencer: IInfluencer, i: number) => (
|
|
524
|
+
<li className="influencer-item" key={i}>
|
|
525
|
+
{`${influencer.firstName} ${influencer.lastName?.charAt(0)}`}{' '}
|
|
526
|
+
</li>
|
|
527
|
+
))}
|
|
528
|
+
</ol>
|
|
529
|
+
</div>
|
|
530
|
+
) : null}
|
|
462
531
|
</ThemeProvider>
|
|
463
532
|
)
|
|
464
533
|
}
|
package/src/env.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// preview
|
|
2
2
|
export const ENV = {
|
|
3
|
-
EVENT_ID:
|
|
4
|
-
BASE_URL: 'https://
|
|
5
|
-
CLIENT_ID: '
|
|
3
|
+
EVENT_ID: 12906,
|
|
4
|
+
BASE_URL: 'https://test.ticketfairy.com',
|
|
5
|
+
CLIENT_ID: 'e9d8f8922797b4621e562255afe90dbf',
|
|
6
6
|
CLIENT_SECRET: 'b89c191eff22fdcf84ac9bfd88d005355a151ec2c83b26b9',
|
|
7
7
|
STRIPE_PUBLISHABLE_KEY:
|
|
8
8
|
'pk_test_51H4BkOGqveRD6EShliLrT9vd7mPOBPvQSuqmvc3wIinDqxWsCLeS2N7HonPPn6MhjU35ayYy5v4I6MLlD4jNWrd000NSgAF6UL',
|
package/src/index.ts
CHANGED
|
@@ -12,4 +12,6 @@ export { OrderDetailsContainer } from './components/orderDetailsContainer'
|
|
|
12
12
|
export { setConfigs } from './utils/setConfigs'
|
|
13
13
|
export { TicketResaleContainer } from './components'
|
|
14
14
|
export { RedirectModal } from './components/common/RedirectModal'
|
|
15
|
-
export { RsvpContainer } from './components/rsvpContainer'
|
|
15
|
+
export { RsvpContainer } from './components/rsvpContainer'
|
|
16
|
+
export { ResetPasswordContainer } from './components/resetPasswordContainer'
|
|
17
|
+
export { ForgotPasswordModal } from './components/forgotPasswordModal'
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { getDomain } from './getDomain'
|
|
2
|
+
|
|
3
|
+
export function setCustomCookie(name: string, value: string, days: number = 5) {
|
|
4
|
+
let expires = ''
|
|
5
|
+
if (days) {
|
|
6
|
+
let date = new Date()
|
|
7
|
+
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000)
|
|
8
|
+
expires = '; expires=' + date.toUTCString()
|
|
9
|
+
}
|
|
10
|
+
if (typeof window !== 'undefined') {
|
|
11
|
+
const domain = getDomain(window.location.hostname)
|
|
12
|
+
document.cookie =
|
|
13
|
+
name + '=' + (value || '') + expires + '; path=/' + `; domain=${domain}`
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function getCookieByName(cname: string) {
|
|
18
|
+
if (typeof window === 'undefined') return ''
|
|
19
|
+
let name = cname + '='
|
|
20
|
+
let ca = document.cookie.split(';')
|
|
21
|
+
for (let i = 0; i < ca.length; i++) {
|
|
22
|
+
let c = ca[i]
|
|
23
|
+
while (c.charAt(0) == ' ') {
|
|
24
|
+
c = c.substring(1)
|
|
25
|
+
}
|
|
26
|
+
if (c.indexOf(name) == 0) {
|
|
27
|
+
return c.substring(name.length, c.length)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return ''
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function deleteCookieByName(name: string) {
|
|
34
|
+
if (typeof window !== 'undefined') {
|
|
35
|
+
const domain = getDomain(window.location.hostname)
|
|
36
|
+
document.cookie =
|
|
37
|
+
name +
|
|
38
|
+
'=; Path=/' +
|
|
39
|
+
`; domain=${domain}` +
|
|
40
|
+
'; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -13,21 +13,33 @@ interface IticketHolder {
|
|
|
13
13
|
email?: string;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
interface IUserCredentialsValues {
|
|
17
|
+
emailLogged?: string;
|
|
18
|
+
firstNameLogged?: string;
|
|
19
|
+
lastNameLogged?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
16
22
|
export const createCheckoutDataBodyWithDefaultHolder = (
|
|
17
23
|
ticketsQuantity: number,
|
|
18
24
|
logedInValues: {},
|
|
19
|
-
includeDob: boolean = false
|
|
25
|
+
includeDob: boolean = false,
|
|
26
|
+
userCredentials: IUserCredentialsValues = {}
|
|
20
27
|
): ICheckoutBody => {
|
|
21
28
|
const ticket_holders: IticketHolder[] = []
|
|
22
29
|
|
|
23
30
|
const first_name =
|
|
24
|
-
_get(logedInValues, 'firstName') ||
|
|
31
|
+
_get(logedInValues, 'firstName') ||
|
|
32
|
+
_get(logedInValues, 'first_name') ||
|
|
33
|
+
_get(userCredentials, 'firstNameLogged') ||
|
|
34
|
+
''
|
|
35
|
+
|
|
25
36
|
const last_name =
|
|
26
|
-
_get(logedInValues, 'lastName'
|
|
37
|
+
_get(logedInValues, 'lastName') ||
|
|
27
38
|
_get(logedInValues, 'last_name') ||
|
|
39
|
+
_get(userCredentials, 'lastNameLogged') ||
|
|
28
40
|
''
|
|
29
41
|
const phone = _get(logedInValues, 'phone', '')
|
|
30
|
-
const email = _get(logedInValues, 'email', '')
|
|
42
|
+
const email = _get(logedInValues, 'email') || _get(userCredentials, 'emailLogged') || ''
|
|
31
43
|
|
|
32
44
|
for (let i = 0; i <= ticketsQuantity - 1; i++) {
|
|
33
45
|
const individualHolder = i
|
|
@@ -1,23 +1,42 @@
|
|
|
1
|
+
import { getCookieByName } from './cookies'
|
|
2
|
+
|
|
1
3
|
export const downloadPDF = (pdfUrl: string) => {
|
|
2
4
|
if (typeof window === 'undefined') return
|
|
3
5
|
|
|
6
|
+
const xtfCookie = getCookieByName('X-TF-ECOMMERCE')
|
|
4
7
|
const accessToken: string | null = localStorage.getItem('access_token')
|
|
5
8
|
|
|
6
|
-
if (!accessToken) return
|
|
9
|
+
if (!accessToken && !xtfCookie) return
|
|
10
|
+
|
|
11
|
+
let headers = {}
|
|
7
12
|
|
|
8
|
-
|
|
9
|
-
headers
|
|
13
|
+
if (accessToken) {
|
|
14
|
+
headers = {
|
|
10
15
|
Authorization: `Bearer ${accessToken}`,
|
|
11
|
-
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (xtfCookie) {
|
|
20
|
+
headers = {
|
|
21
|
+
'X-TF-ECOMMERCE': xtfCookie,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return fetch(pdfUrl, {
|
|
26
|
+
headers,
|
|
27
|
+
credentials: 'include',
|
|
12
28
|
})
|
|
13
29
|
.then(async response => {
|
|
14
30
|
const blobValue = await response.blob()
|
|
15
|
-
const fileNameHeader = response.headers.get(
|
|
31
|
+
const fileNameHeader = response.headers.get('content-disposition') || ''
|
|
16
32
|
const fileName = fileNameHeader.split('"')[1]
|
|
17
33
|
return { blobValue, fileName }
|
|
18
34
|
})
|
|
19
35
|
.then(({ blobValue, fileName }) => {
|
|
20
|
-
if (!fileName)
|
|
36
|
+
if (!fileName) {
|
|
37
|
+
throw Error('Something went wrong.')
|
|
38
|
+
return
|
|
39
|
+
}
|
|
21
40
|
const file = new Blob([blobValue], { type: 'application/pdf' })
|
|
22
41
|
const fileURL = URL.createObjectURL(file)
|
|
23
42
|
const link = document.createElement('a')
|
|
@@ -27,4 +46,7 @@ export const downloadPDF = (pdfUrl: string) => {
|
|
|
27
46
|
link.click()
|
|
28
47
|
document.body.removeChild(link)
|
|
29
48
|
})
|
|
49
|
+
.catch(error => {
|
|
50
|
+
return error
|
|
51
|
+
})
|
|
30
52
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function getDomain(url: string, subdomain?: string): string {
|
|
2
|
+
let updatedUrl: any = url.replace(/(https?:\/\/)?(www.)?/i, '')
|
|
3
|
+
|
|
4
|
+
if (!subdomain) {
|
|
5
|
+
updatedUrl = updatedUrl.split('.')
|
|
6
|
+
|
|
7
|
+
updatedUrl = updatedUrl.slice(updatedUrl.length - 2).join('.')
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (updatedUrl.indexOf('/') !== -1) {
|
|
11
|
+
return updatedUrl.split('/')[0]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return updatedUrl
|
|
15
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -3,3 +3,5 @@ export { getQueryVariable } from './getQueryVariable'
|
|
|
3
3
|
export { ErrorFocus } from './formikErrorFocus'
|
|
4
4
|
export { downloadPDF } from './downloadPDF'
|
|
5
5
|
export { createCheckoutDataBodyWithDefaultHolder } from './createCheckoutDataBodyWithDefaultHolder'
|
|
6
|
+
export { setCustomCookie, getCookieByName, deleteCookieByName } from './cookies'
|
|
7
|
+
export { getDomain } from './getDomain'
|