tf-checkout-react 1.0.84 → 1.0.88
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/components/billing-info-container/index.d.ts +4 -1
- package/dist/components/paymentContainer/index.d.ts +4 -2
- package/dist/components/ticketsContainer/index.d.ts +2 -1
- package/dist/components/timerWidget/index.d.ts +15 -0
- package/dist/tf-checkout-react.cjs.development.js +226 -87
- 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 +228 -89
- package/dist/tf-checkout-react.esm.js.map +1 -1
- package/dist/tf-checkout-styles.css +1 -1
- package/dist/utils/showZero.d.ts +1 -0
- package/package.json +2 -1
- package/src/api/index.ts +4 -5
- package/src/components/billing-info-container/index.tsx +105 -102
- package/src/components/common/CustomField.tsx +15 -12
- package/src/components/paymentContainer/index.tsx +30 -10
- package/src/components/ticketsContainer/index.tsx +17 -9
- package/src/components/ticketsContainer/style.css +5 -0
- package/src/components/timerWidget/index.tsx +70 -0
- package/src/components/timerWidget/style.css +26 -0
- package/src/components/waitingList/index.tsx +12 -6
- package/src/utils/showZero.tsx +10 -0
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from '../../api'
|
|
12
12
|
import _get from 'lodash/get'
|
|
13
13
|
import _some from 'lodash/some'
|
|
14
|
+
import _every from 'lodash/every'
|
|
14
15
|
import _find from 'lodash/find'
|
|
15
16
|
import _isEmpty from 'lodash/isEmpty'
|
|
16
17
|
import CircularProgress from '@mui/material/CircularProgress'
|
|
@@ -21,7 +22,7 @@ import WaitingList from '../waitingList'
|
|
|
21
22
|
import { PromoCodeSection } from './PromoCodeSection'
|
|
22
23
|
import { LoginModal } from '../loginModal'
|
|
23
24
|
import Countdown from '../countdown'
|
|
24
|
-
import { createCheckoutDataBodyWithDefaultHolder } from '../../utils'
|
|
25
|
+
import { createCheckoutDataBodyWithDefaultHolder, getQueryVariable } from '../../utils'
|
|
25
26
|
import { ThemeProvider } from '@mui/private-theming'
|
|
26
27
|
import { createTheme, ThemeOptions } from '@mui/material'
|
|
27
28
|
import { CSSProperties } from '@mui/styles'
|
|
@@ -58,6 +59,7 @@ export interface IGetTickets {
|
|
|
58
59
|
themeOptions?: ThemeOptions & { input?: CSSProperties; checkbox?: CSSProperties }
|
|
59
60
|
isAccessCodeEnabled?: boolean;
|
|
60
61
|
hideSessionButtons?: boolean;
|
|
62
|
+
hideWaitingList?: boolean;
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
export interface ITicket {
|
|
@@ -83,7 +85,8 @@ export const TicketsContainer = ({
|
|
|
83
85
|
isPromotionsEnabled = true,
|
|
84
86
|
themeOptions,
|
|
85
87
|
isAccessCodeEnabled = false,
|
|
86
|
-
hideSessionButtons = false
|
|
88
|
+
hideSessionButtons = false,
|
|
89
|
+
hideWaitingList = false
|
|
87
90
|
}: IGetTickets) => {
|
|
88
91
|
const [selectedTickets, setSelectedTickets] = useState(
|
|
89
92
|
{} as ISelectedTickets
|
|
@@ -99,7 +102,7 @@ export const TicketsContainer = ({
|
|
|
99
102
|
const [isLoading, setIsLoading] = useState(false)
|
|
100
103
|
const [handleBookIsLoading, setHandleBookIsLoading] = useState(false)
|
|
101
104
|
const [promoCode, setPromoCode] = useState('')
|
|
102
|
-
const [promoCodeUpdated, setPromoCodeUpdated] = useState(queryPromoCode)
|
|
105
|
+
const [promoCodeUpdated, setPromoCodeUpdated] = useState(getQueryVariable('r') || queryPromoCode)
|
|
103
106
|
const [showPromoInput, setShowPromoInput] = useState(false)
|
|
104
107
|
const [promoCodeIsApplied, setPromoCodeIsApplied] = useState(false)
|
|
105
108
|
|
|
@@ -279,9 +282,14 @@ export const TicketsContainer = ({
|
|
|
279
282
|
getTicketsApi()
|
|
280
283
|
}
|
|
281
284
|
|
|
282
|
-
const isAllTicketsSoldOut =
|
|
285
|
+
const isAllTicketsSoldOut = _every(
|
|
283
286
|
tickets,
|
|
284
|
-
item =>
|
|
287
|
+
item => (item.sold_out || item.soldOut)
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
const isTicketOnSale = _some(
|
|
291
|
+
tickets,
|
|
292
|
+
item => (item.salesStarted && !item.salesEnded && !item.soldOut)
|
|
285
293
|
)
|
|
286
294
|
|
|
287
295
|
const themeMui = createTheme(themeOptions)
|
|
@@ -321,8 +329,8 @@ export const TicketsContainer = ({
|
|
|
321
329
|
promoCodeIsApplied={promoCodeIsApplied}
|
|
322
330
|
/>
|
|
323
331
|
{event?.salesEnded ? (
|
|
324
|
-
<p>Sales for this event are closed.</p>
|
|
325
|
-
) : event?.salesStart ? (
|
|
332
|
+
<p className='event-closed-message'>Sales for this event are closed.</p>
|
|
333
|
+
) : !event?.salesStarted && event?.salesStart ? (
|
|
326
334
|
<Countdown
|
|
327
335
|
startDate={event.salesStart}
|
|
328
336
|
timezone={event.timezone}
|
|
@@ -331,7 +339,7 @@ export const TicketsContainer = ({
|
|
|
331
339
|
callback={updateTickets}
|
|
332
340
|
/>
|
|
333
341
|
) : null}
|
|
334
|
-
{showWaitingList && event.salesStarted && (
|
|
342
|
+
{showWaitingList && event.salesStarted && !hideWaitingList && (
|
|
335
343
|
<WaitingList tickets={tickets} eventId={eventId} />
|
|
336
344
|
)}
|
|
337
345
|
<PromoCodeSection
|
|
@@ -345,7 +353,7 @@ export const TicketsContainer = ({
|
|
|
345
353
|
isAccessCodeEnabled={isAccessCodeEnabled}
|
|
346
354
|
isAllTicketsSoldOut={isAllTicketsSoldOut}
|
|
347
355
|
/>
|
|
348
|
-
{!
|
|
356
|
+
{(isTicketOnSale || !event?.salesEnded) && (
|
|
349
357
|
<Button
|
|
350
358
|
aria-hidden={true}
|
|
351
359
|
className={`book-button ${
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import Countdown from 'react-countdown'
|
|
3
|
+
import { showZero } from '../../utils/showZero'
|
|
4
|
+
import './style.css'
|
|
5
|
+
|
|
6
|
+
export interface ITimerWidgetPage {
|
|
7
|
+
expires_at: number;
|
|
8
|
+
buyLoading?: boolean;
|
|
9
|
+
onCountdownFinish?: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface IRenderer {
|
|
13
|
+
minutes: number;
|
|
14
|
+
seconds: number;
|
|
15
|
+
completed: number;
|
|
16
|
+
handleCountdownFinish: () => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const TimerWidget = ({
|
|
20
|
+
expires_at,
|
|
21
|
+
buyLoading,
|
|
22
|
+
onCountdownFinish = () => {},
|
|
23
|
+
}: ITimerWidgetPage) => {
|
|
24
|
+
const [showTimer, setShowTimer] = useState(true)
|
|
25
|
+
|
|
26
|
+
const handleCountdownFinish = () => {
|
|
27
|
+
setShowTimer(false)
|
|
28
|
+
if (!buyLoading) {
|
|
29
|
+
onCountdownFinish()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const renderer = ({
|
|
34
|
+
minutes,
|
|
35
|
+
seconds,
|
|
36
|
+
completed,
|
|
37
|
+
handleCountdownFinish,
|
|
38
|
+
}: IRenderer) => {
|
|
39
|
+
if (completed) {
|
|
40
|
+
handleCountdownFinish()
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
return (
|
|
44
|
+
<span>
|
|
45
|
+
{showZero(minutes)}:{showZero(seconds)}
|
|
46
|
+
</span>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return showTimer && !!expires_at ? (
|
|
51
|
+
<div className="timer">
|
|
52
|
+
<div className="toast-message">
|
|
53
|
+
<p>Please complete your purchase before the timer reaches zero.</p>
|
|
54
|
+
<p className="countdown">
|
|
55
|
+
<Countdown
|
|
56
|
+
date={Date.now() + expires_at * 1000}
|
|
57
|
+
renderer={(props: any) =>
|
|
58
|
+
renderer({
|
|
59
|
+
...props,
|
|
60
|
+
handleCountdownFinish,
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
/>
|
|
64
|
+
</p>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
) : null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default TimerWidget
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.timer {
|
|
2
|
+
position: absolute;
|
|
3
|
+
pointer-events: auto;
|
|
4
|
+
background-color: #000000;
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
margin: 0 0 6px;
|
|
7
|
+
padding: 15px 15px 15px 50px;
|
|
8
|
+
width: 300px;
|
|
9
|
+
-moz-border-radius: 3px;
|
|
10
|
+
-webkit-border-radius: 3px;
|
|
11
|
+
border-radius: 3px;
|
|
12
|
+
background-position: 15px center;
|
|
13
|
+
background-repeat: no-repeat;
|
|
14
|
+
-moz-box-shadow: 0 0 12px #999;
|
|
15
|
+
-webkit-box-shadow: 0 0 12px #999;
|
|
16
|
+
box-shadow: 0 0 12px #999;
|
|
17
|
+
max-width: 300px;
|
|
18
|
+
color: #fff;
|
|
19
|
+
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=);
|
|
20
|
+
right: 15px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.timer .countdown {
|
|
24
|
+
font-weight: bold;
|
|
25
|
+
margin-top: 10px;
|
|
26
|
+
}
|
|
@@ -33,8 +33,14 @@ const generateQuantity = (n: number) => {
|
|
|
33
33
|
}
|
|
34
34
|
return quantityList
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
const WaitingList = ({ tickets = {}, eventId }: WaitingListProps) => {
|
|
38
|
+
const isWindowDefined = typeof window !== 'undefined'
|
|
39
|
+
const userData =
|
|
40
|
+
isWindowDefined && window.localStorage.getItem('user_data')
|
|
41
|
+
? JSON.parse(window.localStorage.getItem('user_data') || '')
|
|
42
|
+
: {}
|
|
43
|
+
|
|
38
44
|
const [showSuccessMessage, setShowSuccessMessage] = useState(false)
|
|
39
45
|
const [loading, setLoading] = useState(false)
|
|
40
46
|
const ticketTypesList = Object.values(tickets).map((d: any) => ({
|
|
@@ -77,9 +83,9 @@ const WaitingList = ({ tickets = {}, eventId }: WaitingListProps) => {
|
|
|
77
83
|
initialValues={{
|
|
78
84
|
ticketTypeId: '',
|
|
79
85
|
quantity: '',
|
|
80
|
-
firstName: '',
|
|
81
|
-
lastName: '',
|
|
82
|
-
email: '',
|
|
86
|
+
firstName: userData.first_name || '',
|
|
87
|
+
lastName: userData.last_name || '',
|
|
88
|
+
email: userData.email || '',
|
|
83
89
|
}}
|
|
84
90
|
onSubmit={handleSubmit}
|
|
85
91
|
>
|
|
@@ -90,7 +96,7 @@ const WaitingList = ({ tickets = {}, eventId }: WaitingListProps) => {
|
|
|
90
96
|
<div className="field-item">
|
|
91
97
|
<Field
|
|
92
98
|
name="ticketTypeId"
|
|
93
|
-
label="Ticket
|
|
99
|
+
label="Type of Ticket"
|
|
94
100
|
type="select"
|
|
95
101
|
component={CustomField}
|
|
96
102
|
selectOptions={[
|
|
@@ -102,7 +108,7 @@ const WaitingList = ({ tickets = {}, eventId }: WaitingListProps) => {
|
|
|
102
108
|
<div className="field-item">
|
|
103
109
|
<Field
|
|
104
110
|
name="quantity"
|
|
105
|
-
label="Quantity"
|
|
111
|
+
label="Quantity Requested"
|
|
106
112
|
type="select"
|
|
107
113
|
component={CustomField}
|
|
108
114
|
selectOptions={[
|