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