tf-checkout-react 1.4.21 → 1.4.22
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/hooks/useOnline.d.ts +1 -0
- package/dist/tf-checkout-react.cjs.development.js +44 -10
- 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 +44 -10
- package/dist/tf-checkout-react.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/seatMapContainer/index.tsx +74 -52
- package/src/hooks/useOnline.ts +21 -0
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@ import _map from 'lodash/map'
|
|
|
11
11
|
import _values from 'lodash/values'
|
|
12
12
|
import moment from 'moment'
|
|
13
13
|
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
|
14
|
-
import Countdown from 'react-countdown'
|
|
14
|
+
import Countdown, { CountdownRenderProps } from 'react-countdown'
|
|
15
15
|
|
|
16
16
|
import {
|
|
17
17
|
getSeatMapData,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
removeSeatReserve,
|
|
20
20
|
reserveSeat,
|
|
21
21
|
} from '../../api'
|
|
22
|
+
import { useOnline } from '../../hooks/useOnline'
|
|
22
23
|
import { showZero } from '../../utils/showZero'
|
|
23
24
|
import { ReferralLogic } from '../ticketsContainer/ReferralLogic'
|
|
24
25
|
import { addToCartFunc } from './addToCart'
|
|
@@ -31,6 +32,8 @@ import {
|
|
|
31
32
|
getTierIdBasedOnSeatId,
|
|
32
33
|
} from './utils'
|
|
33
34
|
|
|
35
|
+
const OFFLINE_MESSAGE = 'Offline.'
|
|
36
|
+
|
|
34
37
|
interface IGuestCounts {
|
|
35
38
|
[key: string]: number;
|
|
36
39
|
}
|
|
@@ -76,8 +79,11 @@ export const SeatMapContainer = (props: IMapContainerProps) => {
|
|
|
76
79
|
Date.now() <= Number(localStorage.getItem(`reservationStart-${eventId}`))
|
|
77
80
|
)
|
|
78
81
|
const [guestCounts, setGuestCounts] = useState<IGuestCounts>({} as IGuestCounts)
|
|
82
|
+
const [isOnline, setIsOnline] = useState(true)
|
|
79
83
|
const isGuestCountsSet = useRef(false)
|
|
80
84
|
|
|
85
|
+
useOnline(setIsOnline)
|
|
86
|
+
|
|
81
87
|
const updateGuestCounts = (data: any) => {
|
|
82
88
|
_forEach(data, (item: any) => {
|
|
83
89
|
const tierTickets = ticketTypeTierRelationsRef.current[item.tierId]
|
|
@@ -123,62 +129,64 @@ export const SeatMapContainer = (props: IMapContainerProps) => {
|
|
|
123
129
|
}, [eventId])
|
|
124
130
|
|
|
125
131
|
const fetchSeatMapReservations = useCallback(async () => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
if (isOnline) {
|
|
133
|
+
try {
|
|
134
|
+
const statusesResponse = await getSeatMapStatuses(eventId)
|
|
135
|
+
const statuses = _get(statusesResponse, 'data.attributes') || {}
|
|
136
|
+
const reservationData: Array<SeatReservationData> = []
|
|
137
|
+
const ownReservations: string[] = getOwnReservationsBasedOnStatuses(statuses)
|
|
138
|
+
|
|
139
|
+
_forEach(ownReservations, reservation => {
|
|
140
|
+
const tierIdOfReservation = getTierIdBasedOnSeatId(
|
|
141
|
+
reservation,
|
|
142
|
+
eventSeatsRef.current
|
|
143
|
+
) as string
|
|
144
|
+
reservationData.push({
|
|
145
|
+
seatId: reservation,
|
|
146
|
+
tierId: tierIdOfReservation,
|
|
147
|
+
type: 'reserve',
|
|
148
|
+
})
|
|
141
149
|
})
|
|
142
|
-
})
|
|
143
150
|
|
|
144
|
-
|
|
151
|
+
localStorage.setItem('reservationData', JSON.stringify(reservationData))
|
|
145
152
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// automatically set ticket/table type if it's the only one
|
|
154
|
-
if (
|
|
155
|
-
ticketTypeTierRelationsRef.current &&
|
|
156
|
-
!_isEqual(reservationData, reservedSeats)
|
|
157
|
-
) {
|
|
158
|
-
if (!isGuestCountsSet.current) {
|
|
159
|
-
updateGuestCounts(reservationData)
|
|
160
|
-
isGuestCountsSet.current = true
|
|
153
|
+
if (!_isEqual(seatMapStatuses, statusesResponse.data.attributes)) {
|
|
154
|
+
setSeatMapStatuses(statusesResponse.data.attributes)
|
|
155
|
+
}
|
|
156
|
+
if (!_isEqual(reservationData, reservedSeats)) {
|
|
157
|
+
setReservedSeats(reservationData)
|
|
161
158
|
}
|
|
162
|
-
_forEach(reservationData, (item: any) => {
|
|
163
|
-
const tierTickets = ticketTypeTierRelationsRef.current[item.tierId]
|
|
164
|
-
const seatTicketsArray = _values(tierTickets)
|
|
165
|
-
|
|
166
|
-
setSelectedTickets((prevState: any) => ({
|
|
167
|
-
...prevState,
|
|
168
|
-
[item.seatId]:
|
|
169
|
-
seatTicketsArray.length === 1 ? seatTicketsArray[0].ticket_type_id : '',
|
|
170
|
-
}))
|
|
171
|
-
})
|
|
172
159
|
|
|
173
|
-
if
|
|
174
|
-
|
|
175
|
-
|
|
160
|
+
// automatically set ticket/table type if it's the only one
|
|
161
|
+
if (
|
|
162
|
+
ticketTypeTierRelationsRef.current &&
|
|
163
|
+
!_isEqual(reservationData, reservedSeats)
|
|
164
|
+
) {
|
|
165
|
+
if (!isGuestCountsSet.current) {
|
|
166
|
+
updateGuestCounts(reservationData)
|
|
167
|
+
isGuestCountsSet.current = true
|
|
168
|
+
}
|
|
169
|
+
_forEach(reservationData, (item: any) => {
|
|
170
|
+
const tierTickets = ticketTypeTierRelationsRef.current[item.tierId]
|
|
171
|
+
const seatTicketsArray = _values(tierTickets)
|
|
172
|
+
|
|
173
|
+
setSelectedTickets((prevState: any) => ({
|
|
174
|
+
...prevState,
|
|
175
|
+
[item.seatId]:
|
|
176
|
+
seatTicketsArray.length === 1 ? seatTicketsArray[0].ticket_type_id : '',
|
|
177
|
+
}))
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
if (_isEmpty(reservationData)) {
|
|
181
|
+
setGuestCounts({})
|
|
182
|
+
setSelectedTickets({})
|
|
183
|
+
}
|
|
176
184
|
}
|
|
185
|
+
} catch (error) {
|
|
186
|
+
setError('Something went wrong')
|
|
177
187
|
}
|
|
178
|
-
} catch (error) {
|
|
179
|
-
setError('Something went wrong')
|
|
180
188
|
}
|
|
181
|
-
}, [eventId, seatMapStatuses, reservedSeats])
|
|
189
|
+
}, [eventId, seatMapStatuses, reservedSeats, isOnline])
|
|
182
190
|
|
|
183
191
|
const startTimer = useCallback(
|
|
184
192
|
(duration: number) => {
|
|
@@ -217,7 +225,7 @@ export const SeatMapContainer = (props: IMapContainerProps) => {
|
|
|
217
225
|
handleTicketSelect(relations.length === 1 ? firstItem : '', seatId)
|
|
218
226
|
} catch (error) {
|
|
219
227
|
setError(
|
|
220
|
-
|
|
228
|
+
error?.response?.data?.message === 'Selected seat is not available'
|
|
221
229
|
? // eslint-disable-next-line max-len
|
|
222
230
|
'No more of this ticket type are available right now - they’re either sold out or in people’s shopping carts. Try refreshing the page!'
|
|
223
231
|
: 'Something went wrong'
|
|
@@ -251,7 +259,13 @@ export const SeatMapContainer = (props: IMapContainerProps) => {
|
|
|
251
259
|
}
|
|
252
260
|
}
|
|
253
261
|
|
|
254
|
-
const onSeatClick = async (seatInfo:
|
|
262
|
+
const onSeatClick = async (seatInfo: {
|
|
263
|
+
seat: {
|
|
264
|
+
tierId: string;
|
|
265
|
+
seatId: string;
|
|
266
|
+
status: string;
|
|
267
|
+
};
|
|
268
|
+
}) => {
|
|
255
269
|
const {
|
|
256
270
|
seat: { tierId, seatId, status },
|
|
257
271
|
} = seatInfo
|
|
@@ -347,6 +361,14 @@ export const SeatMapContainer = (props: IMapContainerProps) => {
|
|
|
347
361
|
}
|
|
348
362
|
}, [fetchSeatMapReservations])
|
|
349
363
|
|
|
364
|
+
useEffect(() => {
|
|
365
|
+
if (!isOnline) {
|
|
366
|
+
setError(OFFLINE_MESSAGE)
|
|
367
|
+
} else if (isOnline && error === OFFLINE_MESSAGE) {
|
|
368
|
+
setError(null)
|
|
369
|
+
}
|
|
370
|
+
}, [error, isOnline])
|
|
371
|
+
|
|
350
372
|
return (
|
|
351
373
|
<>
|
|
352
374
|
{error && (
|
|
@@ -366,7 +388,7 @@ export const SeatMapContainer = (props: IMapContainerProps) => {
|
|
|
366
388
|
date={moment(
|
|
367
389
|
Number(localStorage.getItem(`reservationStart-${eventId}`))
|
|
368
390
|
).valueOf()}
|
|
369
|
-
renderer={(props:
|
|
391
|
+
renderer={(props: CountdownRenderProps) => (
|
|
370
392
|
<div className="reservation-countdown">
|
|
371
393
|
<span className="reservation-message">{timerMessage}</span>
|
|
372
394
|
<span className="reservation-timer">
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useEffect } from 'react'
|
|
2
|
+
|
|
3
|
+
export const useOnline = (handler: (value: boolean) => void) => {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
const handleOffline = () => {
|
|
6
|
+
handler(false)
|
|
7
|
+
}
|
|
8
|
+
const handleOnline = () => {
|
|
9
|
+
handler(true)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
window.addEventListener('offline', handleOffline)
|
|
13
|
+
window.addEventListener('online', handleOnline)
|
|
14
|
+
|
|
15
|
+
return () => {
|
|
16
|
+
window.removeEventListener('offline', handleOffline)
|
|
17
|
+
window.removeEventListener('online', handleOnline)
|
|
18
|
+
}
|
|
19
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
20
|
+
}, [])
|
|
21
|
+
}
|