iticket-seatingplan-dev 1.8.5 → 1.8.7
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.
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _leaflet = _interopRequireDefault(require("leaflet"));
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _reactLeaflet = require("react-leaflet");
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
12
|
+
const POSITION_CLASSES = {
|
|
13
|
+
bottomleft: "leaflet-bottom leaflet-left",
|
|
14
|
+
bottomright: "leaflet-bottom leaflet-right",
|
|
15
|
+
topleft: "leaflet-top leaflet-left",
|
|
16
|
+
topright: "leaflet-top leaflet-right"
|
|
17
|
+
};
|
|
18
|
+
const Control = props => {
|
|
19
|
+
var _props$container;
|
|
20
|
+
const [portalRoot, setPortalRoot] = _react.default.useState(document.createElement("div"));
|
|
21
|
+
const positionClass = props.position && POSITION_CLASSES[props.position] || POSITION_CLASSES.topright;
|
|
22
|
+
const controlContainerRef = /*#__PURE__*/_react.default.createRef();
|
|
23
|
+
const map = (0, _reactLeaflet.useMap)();
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Whenever the control container ref is created,
|
|
27
|
+
* Ensure the click / scroll propagation is removed
|
|
28
|
+
* This way click/scroll events do not bubble down to the map
|
|
29
|
+
*/
|
|
30
|
+
_react.default.useEffect(() => {
|
|
31
|
+
if (controlContainerRef.current !== null) {
|
|
32
|
+
_leaflet.default.DomEvent.disableClickPropagation(controlContainerRef.current);
|
|
33
|
+
_leaflet.default.DomEvent.disableScrollPropagation(controlContainerRef.current);
|
|
34
|
+
}
|
|
35
|
+
}, [controlContainerRef]);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Whenever the position is changed, go ahead and get the container of the map and the first
|
|
39
|
+
* instance of the position class in that map container
|
|
40
|
+
* Fixes #17
|
|
41
|
+
*/
|
|
42
|
+
_react.default.useEffect(() => {
|
|
43
|
+
const mapContainer = map.getContainer();
|
|
44
|
+
const targetDiv = mapContainer.getElementsByClassName(positionClass);
|
|
45
|
+
setPortalRoot(targetDiv[0]);
|
|
46
|
+
}, [positionClass]);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Whenever the portal root is complete,
|
|
50
|
+
* append or prepend the control container to the portal root
|
|
51
|
+
*/
|
|
52
|
+
_react.default.useEffect(() => {
|
|
53
|
+
if (portalRoot !== null) {
|
|
54
|
+
if (props.prepend !== undefined && props.prepend === true) {
|
|
55
|
+
portalRoot.prepend(controlContainerRef.current);
|
|
56
|
+
} else {
|
|
57
|
+
portalRoot.append(controlContainerRef.current);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}, [portalRoot, props.prepend, controlContainerRef]);
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Concatenate the props.container className to the class of the control div
|
|
64
|
+
*/
|
|
65
|
+
const className = (((_props$container = props.container) === null || _props$container === void 0 || (_props$container = _props$container.className) === null || _props$container === void 0 ? void 0 : _props$container.concat(" ")) || "") + "leaflet-control";
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Render
|
|
69
|
+
*/
|
|
70
|
+
return /*#__PURE__*/_react.default.createElement("div", _extends({}, props.container, {
|
|
71
|
+
ref: controlContainerRef,
|
|
72
|
+
className: className
|
|
73
|
+
}), props.children);
|
|
74
|
+
};
|
|
75
|
+
var _default = exports.default = Control;
|
package/dist/components/Map.js
CHANGED
|
@@ -420,7 +420,7 @@ function SeatMap(_ref) {
|
|
|
420
420
|
isReloading: isReloading,
|
|
421
421
|
hasMembershipSeats: (seats === null || seats === void 0 || (_seats$seats2 = seats.seats) === null || _seats$seats2 === void 0 ? void 0 : _seats$seats2.filter(seat => seat.m).length) > 0,
|
|
422
422
|
hasBookedSeats: (bookedSeats === null || bookedSeats === void 0 ? void 0 : bookedSeats.length) > 0
|
|
423
|
-
}), /*#__PURE__*/_react.default.createElement(_reactLeaflet.ImageOverlay, {
|
|
423
|
+
}), (seats === null || seats === void 0 ? void 0 : seats.background) && /*#__PURE__*/_react.default.createElement(_reactLeaflet.ImageOverlay, {
|
|
424
424
|
url: seats === null || seats === void 0 ? void 0 : seats.background,
|
|
425
425
|
bounds: [[0, 0], [height * 0.03, width * 0.03]],
|
|
426
426
|
zIndex: 10
|
|
@@ -24,7 +24,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
24
24
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
25
25
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
26
26
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
27
|
-
const
|
|
27
|
+
const SEATINGPLAN_MAX_RETRIES = 5;
|
|
28
|
+
const BOOKING_MAX_RETRIES = 2;
|
|
28
29
|
const SeatingPlan = _ref => {
|
|
29
30
|
var _document, _document2, _document3;
|
|
30
31
|
let {
|
|
@@ -67,6 +68,7 @@ const SeatingPlan = _ref => {
|
|
|
67
68
|
const [seatsToRemove, setSeatsToRemove] = (0, _react.useState)([]);
|
|
68
69
|
const [removeMultipleSeatsPopupOpen, setRemoveMultipleSeatsPopupOpen] = (0, _react.useState)(false);
|
|
69
70
|
const [invalidSeatsPopupOpen, setInvalidSeatsPopupOpen] = (0, _react.useState)(false);
|
|
71
|
+
const [retrying, setRetrying] = (0, _react.useState)([]);
|
|
70
72
|
const mapRef = (0, _react.useRef)(null);
|
|
71
73
|
const canMultiSelect = bookingMode === _utils.bookingModes.POS;
|
|
72
74
|
const apiUrl = "".concat(baseUrl, "/legacy/").concat(countryCode, "/shop/events/").concat(eventId, "/").concat(eventVenueId, "/showings/").concat(showingId, "/tickets/allocated/").concat(areaId);
|
|
@@ -83,17 +85,36 @@ const SeatingPlan = _ref => {
|
|
|
83
85
|
};
|
|
84
86
|
callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
|
|
85
87
|
};
|
|
86
|
-
const
|
|
88
|
+
const updateSeat = (seatIndex, newSeat) => {
|
|
89
|
+
if (seatIndex !== -1) {
|
|
90
|
+
setSeats(prev => {
|
|
91
|
+
const updatedSeats = _objectSpread({}, prev);
|
|
92
|
+
updatedSeats.seats[seatIndex] = newSeat;
|
|
93
|
+
return updatedSeats;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const setSeatsLoading = (seatsToUpdate, loading) => {
|
|
98
|
+
setSeats(prev => {
|
|
99
|
+
const updatedSeats = _objectSpread({}, prev);
|
|
100
|
+
seatsToUpdate.forEach(seat => {
|
|
101
|
+
const seatIndex = updatedSeats.seats.findIndex(s => s.ssId === seat.ssId);
|
|
102
|
+
if (seatIndex !== -1) {
|
|
103
|
+
updatedSeats.seats[seatIndex] = _objectSpread(_objectSpread({}, updatedSeats.seats[seatIndex]), {}, {
|
|
104
|
+
loading: loading
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
return updatedSeats;
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
const _addTicketToCart = async function addTicketToCart(s, priceage) {
|
|
87
112
|
var _mapRef$current;
|
|
88
|
-
|
|
89
|
-
const seatIndex =
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
setSeats(updatedSeats);
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
setSeatLoading(true);
|
|
113
|
+
let retryCount = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
114
|
+
const seatIndex = seats.seats.findIndex(seat => seat.ssId === s.ssId);
|
|
115
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
116
|
+
loading: true
|
|
117
|
+
}));
|
|
97
118
|
const isSeatAvailable = (s.s === _utils.statuses.UNSOLD || s.s === _utils.statuses.USER_PENDING) && !(bookedSeats.length >= quantity && s.s === _utils.statuses.UNSOLD) && (priceage.q === null || priceage.q > 0);
|
|
98
119
|
if (!isSeatAvailable) {
|
|
99
120
|
if (bookedSeats.length >= quantity) {
|
|
@@ -105,210 +126,224 @@ const SeatingPlan = _ref => {
|
|
|
105
126
|
message: _utils.ERROR_MESSAGES.NO_ALLOCATION
|
|
106
127
|
});
|
|
107
128
|
}
|
|
108
|
-
|
|
129
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
130
|
+
loading: false
|
|
131
|
+
}));
|
|
109
132
|
return;
|
|
110
133
|
}
|
|
111
134
|
(_mapRef$current = mapRef.current) === null || _mapRef$current === void 0 || (_mapRef$current = _mapRef$current.target) === null || _mapRef$current === void 0 || _mapRef$current.closePopup();
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}).then(response => {
|
|
125
|
-
if ((response === null || response === void 0 ? void 0 : response.status) === 403 || (response === null || response === void 0 ? void 0 : response.status) === 400) {
|
|
126
|
-
if (seatIndex !== -1) {
|
|
127
|
-
updatedSeats.seats[seatIndex] = _objectSpread(_objectSpread({}, s), {}, {
|
|
128
|
-
loading: false,
|
|
129
|
-
s: _utils.statuses.SOLD
|
|
130
|
-
});
|
|
131
|
-
setSeats(updatedSeats);
|
|
135
|
+
try {
|
|
136
|
+
const response = await fetch(apiUrl, {
|
|
137
|
+
method: "POST",
|
|
138
|
+
body: JSON.stringify({
|
|
139
|
+
priceAgeId: priceage.paId,
|
|
140
|
+
seatId: s.ssId,
|
|
141
|
+
price: priceage.p,
|
|
142
|
+
connectedShowings: connectedShowings
|
|
143
|
+
}),
|
|
144
|
+
headers: {
|
|
145
|
+
"content-type": "application/json",
|
|
146
|
+
"basket-key": sessionId
|
|
132
147
|
}
|
|
148
|
+
});
|
|
149
|
+
if ((response === null || response === void 0 ? void 0 : response.status) === 429) {
|
|
150
|
+
if (retryCount < BOOKING_MAX_RETRIES) {
|
|
151
|
+
setRetrying(prev => [...prev, s.ssId]);
|
|
152
|
+
const delay = (0, _utils.getRetryDelay)(response);
|
|
153
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
154
|
+
return _addTicketToCart(s, priceage, retryCount + 1);
|
|
155
|
+
}
|
|
156
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
157
|
+
loading: false
|
|
158
|
+
}));
|
|
159
|
+
setRetrying(prev => prev.filter(id => id !== s.ssId));
|
|
133
160
|
handleError({
|
|
134
|
-
code:
|
|
135
|
-
message:
|
|
161
|
+
code: 429,
|
|
162
|
+
message: _utils.ERROR_MESSAGES.MAX_RETRIES
|
|
136
163
|
});
|
|
137
|
-
|
|
138
|
-
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
setRetrying(prev => prev.filter(id => id !== s.ssId));
|
|
167
|
+
if ((response === null || response === void 0 ? void 0 : response.status) === 403) {
|
|
168
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
169
|
+
loading: false,
|
|
170
|
+
s: _utils.statuses.SOLD
|
|
171
|
+
}));
|
|
139
172
|
handleError({
|
|
140
|
-
code:
|
|
173
|
+
code: 403,
|
|
141
174
|
message: _utils.ERROR_MESSAGES.SEAT_TAKEN
|
|
142
175
|
});
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (!(response !== null && response !== void 0 && response.ok)) {
|
|
179
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
180
|
+
loading: false
|
|
181
|
+
}));
|
|
182
|
+
handleError({
|
|
183
|
+
code: (response === null || response === void 0 ? void 0 : response.status) === 400 ? 400 : 500,
|
|
184
|
+
message: (response === null || response === void 0 ? void 0 : response.status) === 400 ? _utils.ERROR_MESSAGES.INCOMPATIBLE_TICKETS : _utils.ERROR_MESSAGES.GENERIC_ERROR
|
|
185
|
+
});
|
|
143
186
|
} else {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
setSeats(updatedSeats);
|
|
151
|
-
}
|
|
152
|
-
setBookedSeats(prev => [...prev, {
|
|
153
|
-
ssId: s.ssId,
|
|
154
|
-
r: s.r,
|
|
155
|
-
c: s.c,
|
|
187
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
188
|
+
loading: false,
|
|
189
|
+
s: _utils.statuses.USER_PENDING,
|
|
190
|
+
bookedPrice: price
|
|
191
|
+
}));
|
|
192
|
+
setBookedSeats(prev => [...prev, _objectSpread(_objectSpread({}, s), {}, {
|
|
156
193
|
showingId: showingId,
|
|
157
194
|
pId: priceage.paId,
|
|
158
195
|
p: priceage.p,
|
|
159
196
|
paName: priceage.paName
|
|
160
|
-
}]);
|
|
197
|
+
})]);
|
|
161
198
|
const event = {
|
|
162
199
|
type: "cart-change-add",
|
|
163
|
-
details: [
|
|
164
|
-
ssId: s.ssId,
|
|
165
|
-
r: s.r,
|
|
166
|
-
c: s.c,
|
|
200
|
+
details: [_objectSpread(_objectSpread({}, s), {}, {
|
|
167
201
|
showingId: showingId,
|
|
168
202
|
pId: priceage.paId,
|
|
169
203
|
p: priceage.p,
|
|
170
204
|
paName: priceage.paName
|
|
171
|
-
}]
|
|
205
|
+
})]
|
|
172
206
|
};
|
|
173
207
|
callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
|
|
174
208
|
}
|
|
175
|
-
}
|
|
176
|
-
|
|
209
|
+
} catch (_unused) {
|
|
210
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
211
|
+
loading: false
|
|
212
|
+
}));
|
|
213
|
+
setRetrying(prev => prev.filter(id => id !== s.ssId));
|
|
177
214
|
handleError({
|
|
178
215
|
code: 500,
|
|
179
216
|
message: _utils.ERROR_MESSAGES.GENERIC_ERROR
|
|
180
217
|
});
|
|
181
|
-
}
|
|
182
|
-
_initialFetch(true);
|
|
183
|
-
});
|
|
218
|
+
}
|
|
184
219
|
};
|
|
185
|
-
const removeTicketFromCart = (s, e) => {
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
"
|
|
199
|
-
}
|
|
200
|
-
}).then(() => {
|
|
201
|
-
if (seatIndex !== -1) {
|
|
202
|
-
updatedSeats.seats[seatIndex] = _objectSpread(_objectSpread({}, s), {}, {
|
|
203
|
-
loading: false,
|
|
204
|
-
s: _utils.statuses.UNSOLD,
|
|
205
|
-
bookedPrice: null
|
|
206
|
-
});
|
|
207
|
-
setSeats(updatedSeats);
|
|
220
|
+
const removeTicketFromCart = async (s, e) => {
|
|
221
|
+
const seatIndex = seats.seats.findIndex(seat => seat.ssId === s.ssId);
|
|
222
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
223
|
+
loading: true
|
|
224
|
+
}));
|
|
225
|
+
try {
|
|
226
|
+
const response = await fetch("".concat(apiUrl, "/seat/").concat(s.ssId), {
|
|
227
|
+
method: "DELETE",
|
|
228
|
+
headers: {
|
|
229
|
+
"basket-key": sessionId
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
if (!response.ok) {
|
|
233
|
+
throw new Error("".concat(response.status));
|
|
208
234
|
}
|
|
235
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
236
|
+
loading: false,
|
|
237
|
+
s: _utils.statuses.UNSOLD,
|
|
238
|
+
bookedPrice: null
|
|
239
|
+
}));
|
|
209
240
|
setBookedSeats(prev => prev.filter(bs => bs.ssId !== s.ssId));
|
|
210
241
|
const event = {
|
|
211
242
|
type: "cart-change-remove",
|
|
212
243
|
details: bookedSeats.filter(bs => bs.ssId === s.ssId)
|
|
213
244
|
};
|
|
214
245
|
callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
});
|
|
246
|
+
} catch (_unused2) {
|
|
247
|
+
updateSeat(seatIndex, _objectSpread(_objectSpread({}, s), {}, {
|
|
248
|
+
loading: false
|
|
249
|
+
}));
|
|
220
250
|
handleError({
|
|
221
251
|
code: 500,
|
|
222
252
|
message: _utils.ERROR_MESSAGES.GENERIC_ERROR
|
|
223
253
|
});
|
|
224
|
-
}
|
|
225
|
-
_initialFetch(true);
|
|
226
|
-
});
|
|
254
|
+
}
|
|
227
255
|
};
|
|
228
256
|
const batchAddTicketsToCart = async seatsToBook => {
|
|
229
257
|
if (!canMultiSelect && !seats.preventOrphanedSeats || seatsToBook.length === 0) {
|
|
230
258
|
return;
|
|
231
259
|
}
|
|
232
|
-
|
|
233
|
-
const seatIds = seatsToBook.map(s => s.seat.ssId);
|
|
234
|
-
const setSeatsLoading = loading => {
|
|
235
|
-
updatedSeats.seats.forEach(s => {
|
|
236
|
-
if (seatIds.includes(s.ssId)) {
|
|
237
|
-
s.loading = loading;
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
setSeats(updatedSeats);
|
|
241
|
-
};
|
|
242
|
-
setSeatsLoading(true);
|
|
260
|
+
setSeatsLoading(seatsToBook.map(seat => seat.seat), true);
|
|
243
261
|
const succeeded = [];
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
if (!res.ok) {
|
|
261
|
-
throw new Error("".concat(res.status));
|
|
262
|
+
const _tryBook = async function tryBook(seatToBook) {
|
|
263
|
+
let retryCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
264
|
+
try {
|
|
265
|
+
const res = await fetch(apiUrl, {
|
|
266
|
+
method: "POST",
|
|
267
|
+
body: JSON.stringify({
|
|
268
|
+
priceAgeId: seatToBook.priceage.paId,
|
|
269
|
+
seatId: seatToBook.seat.ssId,
|
|
270
|
+
price: seatToBook.priceage.p,
|
|
271
|
+
connectedShowings: connectedShowings
|
|
272
|
+
}),
|
|
273
|
+
headers: {
|
|
274
|
+
"content-type": "application/json",
|
|
275
|
+
"basket-key": sessionId
|
|
262
276
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
277
|
+
});
|
|
278
|
+
if (res.status === 429) {
|
|
279
|
+
if (retryCount < BOOKING_MAX_RETRIES) {
|
|
280
|
+
setRetrying(prev => [...prev, seatToBook.seat.ssId]);
|
|
281
|
+
const delay = (0, _utils.getRetryDelay)(res);
|
|
282
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
283
|
+
return _tryBook(seatToBook, retryCount + 1);
|
|
284
|
+
} else {
|
|
285
|
+
throw new Error("429");
|
|
286
|
+
}
|
|
287
|
+
} else if (!res.ok) {
|
|
288
|
+
throw new Error("".concat(res.status));
|
|
267
289
|
}
|
|
290
|
+
succeeded.push(seatToBook.seat);
|
|
291
|
+
} catch (_unused3) {
|
|
292
|
+
throw new Error("Booking failed for seat ".concat(seatToBook.seat.r, " ").concat(seatToBook.seat.c));
|
|
268
293
|
}
|
|
294
|
+
};
|
|
295
|
+
try {
|
|
296
|
+
for (const seatToBook of seatsToBook) {
|
|
297
|
+
await _tryBook(seatToBook);
|
|
298
|
+
}
|
|
299
|
+
setRetrying(prev => prev.filter(id => !seatsToBook.some(s => s.seat.ssId === id)));
|
|
269
300
|
setBookedSeats(prev => [...prev, ...seatsToBook.map(_ref2 => {
|
|
270
301
|
let {
|
|
271
302
|
seat,
|
|
272
303
|
priceage
|
|
273
304
|
} = _ref2;
|
|
274
|
-
return {
|
|
275
|
-
ssId: seat.ssId,
|
|
276
|
-
r: seat.r,
|
|
277
|
-
c: seat.c,
|
|
305
|
+
return _objectSpread(_objectSpread({}, seat), {}, {
|
|
278
306
|
showingId: showingId,
|
|
279
307
|
pId: priceage.paId,
|
|
280
308
|
p: priceage.p,
|
|
281
309
|
paName: priceage.paName
|
|
282
|
-
};
|
|
310
|
+
});
|
|
283
311
|
})]);
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
312
|
+
setSeats(prev => {
|
|
313
|
+
const updatedSeats = _objectSpread({}, prev);
|
|
314
|
+
seatsToBook.forEach(_ref3 => {
|
|
315
|
+
let {
|
|
316
|
+
seat
|
|
317
|
+
} = _ref3;
|
|
318
|
+
const seatIndex = updatedSeats.seats.findIndex(s => s.ssId === seat.ssId);
|
|
319
|
+
if (seatIndex !== -1) {
|
|
320
|
+
updatedSeats.seats[seatIndex] = _objectSpread(_objectSpread({}, updatedSeats.seats[seatIndex]), {}, {
|
|
321
|
+
loading: false,
|
|
322
|
+
s: _utils.statuses.USER_PENDING,
|
|
323
|
+
bookedPrice: price
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
return updatedSeats;
|
|
290
328
|
});
|
|
291
|
-
setSeats(updatedSeats);
|
|
292
329
|
const event = {
|
|
293
330
|
type: "cart-change-add",
|
|
294
|
-
details: [...
|
|
331
|
+
details: [...seatsToBook.map(_ref4 => {
|
|
295
332
|
let {
|
|
296
333
|
seat,
|
|
297
334
|
priceage
|
|
298
|
-
} =
|
|
299
|
-
return {
|
|
300
|
-
ssId: seat.ssId,
|
|
301
|
-
r: seat.r,
|
|
302
|
-
c: seat.c,
|
|
335
|
+
} = _ref4;
|
|
336
|
+
return _objectSpread(_objectSpread({}, seat), {}, {
|
|
303
337
|
showingId: showingId,
|
|
304
338
|
pId: priceage.paId,
|
|
305
339
|
p: priceage.p,
|
|
306
340
|
paName: priceage.paName
|
|
307
|
-
};
|
|
341
|
+
});
|
|
308
342
|
})]
|
|
309
343
|
};
|
|
310
344
|
callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
|
|
311
345
|
} catch (error) {
|
|
346
|
+
setRetrying(prev => prev.filter(id => !seatsToBook.some(s => s.seat.ssId === id)));
|
|
312
347
|
console.error("Failed to book seats:", error);
|
|
313
348
|
for (const seat of succeeded) {
|
|
314
349
|
await fetch("".concat(apiUrl, "/seat/").concat(seat.ssId), {
|
|
@@ -318,27 +353,18 @@ const SeatingPlan = _ref => {
|
|
|
318
353
|
}
|
|
319
354
|
});
|
|
320
355
|
}
|
|
321
|
-
setSeatsLoading(false);
|
|
356
|
+
setSeatsLoading(seatsToBook.map(seat => seat.seat), false);
|
|
322
357
|
handleError({
|
|
323
358
|
code: error === "429" ? 429 : 500,
|
|
324
|
-
message:
|
|
359
|
+
message: _utils.ERROR_MESSAGES.GENERIC_ERROR
|
|
325
360
|
});
|
|
326
|
-
} finally {
|
|
327
|
-
_initialFetch(true);
|
|
328
361
|
}
|
|
329
362
|
};
|
|
330
363
|
const batchRemoveTicketsFromCart = async seatsToRemove => {
|
|
331
364
|
if (!canMultiSelect && !seats.preventOrphanedSeats || seatsToRemove.length === 0) {
|
|
332
365
|
return;
|
|
333
366
|
}
|
|
334
|
-
|
|
335
|
-
const seatIds = seatsToRemove.map(s => s.ssId);
|
|
336
|
-
updatedSeats.seats.forEach(s => {
|
|
337
|
-
if (seatIds.includes(s.ssId)) {
|
|
338
|
-
s.loading = true;
|
|
339
|
-
}
|
|
340
|
-
});
|
|
341
|
-
setSeats(updatedSeats);
|
|
367
|
+
setSeatsLoading(seatsToRemove, true);
|
|
342
368
|
const succeededIds = [];
|
|
343
369
|
try {
|
|
344
370
|
for (const seat of seatsToRemove) {
|
|
@@ -357,23 +383,27 @@ const SeatingPlan = _ref => {
|
|
|
357
383
|
console.error("Failed to remove seat ".concat(seat, ":"), error);
|
|
358
384
|
}
|
|
359
385
|
}
|
|
360
|
-
} catch (
|
|
386
|
+
} catch (_unused4) {
|
|
361
387
|
handleError({
|
|
362
388
|
code: 500,
|
|
363
389
|
message: _utils.ERROR_MESSAGES.GENERIC_ERROR
|
|
364
390
|
});
|
|
365
391
|
}
|
|
366
392
|
setBookedSeats(prev => [...prev.filter(v => !succeededIds.includes(v.ssId))]);
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
393
|
+
setSeats(prev => {
|
|
394
|
+
const updatedSeats = _objectSpread({}, prev);
|
|
395
|
+
seatsToRemove.forEach(s => {
|
|
396
|
+
const seatIndex = updatedSeats.seats.findIndex(seat => seat.ssId === s.ssId);
|
|
397
|
+
if (seatIndex !== -1) {
|
|
398
|
+
updatedSeats.seats[seatIndex] = _objectSpread(_objectSpread({}, updatedSeats.seats[seatIndex]), {}, {
|
|
399
|
+
loading: false,
|
|
400
|
+
s: succeededIds.includes(s.ssId) ? _utils.statuses.UNSOLD : s.s,
|
|
401
|
+
bookedPrice: null
|
|
402
|
+
});
|
|
373
403
|
}
|
|
374
|
-
}
|
|
404
|
+
});
|
|
405
|
+
return updatedSeats;
|
|
375
406
|
});
|
|
376
|
-
setSeats(updatedSeats);
|
|
377
407
|
setSeatsToRemove([]);
|
|
378
408
|
if (succeededIds.length > 0) {
|
|
379
409
|
const event = {
|
|
@@ -382,7 +412,6 @@ const SeatingPlan = _ref => {
|
|
|
382
412
|
};
|
|
383
413
|
callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
|
|
384
414
|
}
|
|
385
|
-
_initialFetch(true);
|
|
386
415
|
};
|
|
387
416
|
const handleClickSeat = (e, s) => {
|
|
388
417
|
setChosenSeat({
|
|
@@ -402,7 +431,7 @@ const SeatingPlan = _ref => {
|
|
|
402
431
|
const availablePrices = ((_seats$pricing = seats.pricing) === null || _seats$pricing === void 0 ? void 0 : _seats$pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && s.psId === price.psId)) || [];
|
|
403
432
|
const isSingleFlexi = availablePrices.length === 1 && !!availablePrices[0].pMax && !!availablePrices[0].pMin && availablePrices[0].pMax > availablePrices[0].pMin;
|
|
404
433
|
if (availablePrices.length === 1 && !isSingleFlexi) {
|
|
405
|
-
|
|
434
|
+
_addTicketToCart(s, availablePrices[0]);
|
|
406
435
|
}
|
|
407
436
|
} else {
|
|
408
437
|
removeTicketFromCart(s, e);
|
|
@@ -426,10 +455,10 @@ const SeatingPlan = _ref => {
|
|
|
426
455
|
}
|
|
427
456
|
});
|
|
428
457
|
if (response.status === 429) {
|
|
429
|
-
if (retryCount >=
|
|
458
|
+
if (retryCount >= SEATINGPLAN_MAX_RETRIES) {
|
|
430
459
|
throw new Error("We're experiencing high demand. Please try again later.");
|
|
431
460
|
}
|
|
432
|
-
const delay = (0, _utils.getRetryDelay)(response
|
|
461
|
+
const delay = (0, _utils.getRetryDelay)(response);
|
|
433
462
|
setInitialiseMessage("We're experiencing high demand. Please wait while we try again...");
|
|
434
463
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
435
464
|
return _initialFetch(isReload, retryCount + 1);
|
|
@@ -444,8 +473,6 @@ const SeatingPlan = _ref => {
|
|
|
444
473
|
throw new Error("Something went wrong. Please try again or contact support.");
|
|
445
474
|
}
|
|
446
475
|
}
|
|
447
|
-
const img = new Image();
|
|
448
|
-
img.src = data.background;
|
|
449
476
|
setBookedSeats(data.seats.filter(s => s.s === _utils.statuses.USER_PENDING && s.bookedPrice === price).map(s => ({
|
|
450
477
|
ssId: s.ssId,
|
|
451
478
|
r: s.r,
|
|
@@ -456,18 +483,29 @@ const SeatingPlan = _ref => {
|
|
|
456
483
|
pId: s.pId,
|
|
457
484
|
paName: s.paName
|
|
458
485
|
})));
|
|
459
|
-
img
|
|
460
|
-
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
486
|
+
const img = new Image();
|
|
487
|
+
const setupSeats = (height, width) => {
|
|
488
|
+
const southwest = [0, 0];
|
|
489
|
+
const northeast = [height * 0.015, width * 0.015];
|
|
490
|
+
setBounds([southwest, northeast]);
|
|
491
|
+
setPosition([height * 0.005, width * 0.005]);
|
|
492
|
+
setHeight(height * 0.5);
|
|
493
|
+
setWidth(width * 0.5);
|
|
466
494
|
setSeats(data);
|
|
467
495
|
if (data.preventOrphanedSeats && !isReload) {
|
|
468
496
|
setSelectQuantityPopupOpen(true);
|
|
469
497
|
}
|
|
470
498
|
};
|
|
499
|
+
if (data.background) {
|
|
500
|
+
img.src = data.background;
|
|
501
|
+
img.onload = () => {
|
|
502
|
+
setupSeats(img.height, img.width);
|
|
503
|
+
};
|
|
504
|
+
} else {
|
|
505
|
+
const estHeight = 800;
|
|
506
|
+
const estWidth = 800;
|
|
507
|
+
setupSeats(estHeight, estWidth);
|
|
508
|
+
}
|
|
471
509
|
setIsReloading(false);
|
|
472
510
|
} catch (error) {
|
|
473
511
|
var _error$message;
|
|
@@ -516,7 +554,9 @@ const SeatingPlan = _ref => {
|
|
|
516
554
|
pricing: seats.pricing,
|
|
517
555
|
priceSectionIds: priceSectionIds,
|
|
518
556
|
batchAddTicketsToCart: batchAddTicketsToCart
|
|
519
|
-
}) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null),
|
|
557
|
+
}) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null), retrying.length > 0 ? /*#__PURE__*/_react.default.createElement("div", {
|
|
558
|
+
className: "retrying"
|
|
559
|
+
}, "Looks like things are busy right now. Please wait while we continue to confirm your selection...") : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null), seats.preventOrphanedSeats && selectQuantityPopupOpen ? /*#__PURE__*/_react.default.createElement(_SelectQuantityPopup.default, {
|
|
520
560
|
quantity: desiredSeatQuantity,
|
|
521
561
|
setQuantity: v => {
|
|
522
562
|
setDesiredSeatQuantity(v);
|
|
@@ -553,7 +593,7 @@ const SeatingPlan = _ref => {
|
|
|
553
593
|
setTicketPopupOpen: setTicketPopupOpen,
|
|
554
594
|
chosenSeat: chosenSeat,
|
|
555
595
|
bookedSeats: bookedSeats,
|
|
556
|
-
addTicketToCart:
|
|
596
|
+
addTicketToCart: _addTicketToCart,
|
|
557
597
|
batchRemoveTicketsFromCart: batchRemoveTicketsFromCart,
|
|
558
598
|
isReloading: isReloading,
|
|
559
599
|
initialFetch: _initialFetch,
|
|
@@ -1597,6 +1597,22 @@ svg.leaflet-image-layer.leaflet-interactive path {
|
|
|
1597
1597
|
transform: translateX(-50%);
|
|
1598
1598
|
}
|
|
1599
1599
|
|
|
1600
|
+
.retrying {
|
|
1601
|
+
position: absolute;
|
|
1602
|
+
top: 10px;
|
|
1603
|
+
left: 50%;
|
|
1604
|
+
transform: translateX(-50%);
|
|
1605
|
+
background: white;
|
|
1606
|
+
border-radius: 5px;
|
|
1607
|
+
padding: 0.5rem;
|
|
1608
|
+
font-size: 0.875rem;
|
|
1609
|
+
color: #333;
|
|
1610
|
+
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
|
1611
|
+
z-index: 1005;
|
|
1612
|
+
animation: fade-in 400ms;
|
|
1613
|
+
max-width: 50%;
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1600
1616
|
/* Printing */
|
|
1601
1617
|
|
|
1602
1618
|
@media print {
|
package/dist/utils/enums.js
CHANGED
|
@@ -42,5 +42,6 @@ const ERROR_MESSAGES = exports.ERROR_MESSAGES = {
|
|
|
42
42
|
SEAT_TAKEN: "Someone else selected this first. Please try again",
|
|
43
43
|
GENERIC_ERROR: "Oops! Something went wrong. Please try again.",
|
|
44
44
|
MAX_QUANTITY: "Maximum ticket booking quantity specified reached.",
|
|
45
|
-
NO_ALLOCATION: "Allocation exhausted, please try another area or price."
|
|
45
|
+
NO_ALLOCATION: "Allocation exhausted, please try another area or price.",
|
|
46
|
+
MAX_RETRIES: "Looks like things are busy and we couldn't complete your request. Please try again."
|
|
46
47
|
};
|
package/dist/utils/helpers.js
CHANGED
|
@@ -228,15 +228,13 @@ const getAdjacentBookedSeats = (seat, seatsMap) => {
|
|
|
228
228
|
return adjacentBookedSeats;
|
|
229
229
|
};
|
|
230
230
|
exports.getAdjacentBookedSeats = getAdjacentBookedSeats;
|
|
231
|
-
const getRetryDelay =
|
|
231
|
+
const getRetryDelay = response => {
|
|
232
232
|
var _ref, _ref2, _response$headers$get;
|
|
233
233
|
const retryAfter = (_ref = (_ref2 = (_response$headers$get = response.headers.get("Retry-After")) !== null && _response$headers$get !== void 0 ? _response$headers$get : response.headers.get("retry-after")) !== null && _ref2 !== void 0 ? _ref2 : response.headers.get("rl-twm")) !== null && _ref !== void 0 ? _ref : "5";
|
|
234
|
-
|
|
235
|
-
return response.headers.get("rl-twm") ? Math.round(parseInt(retryAfter) * 60 * 1000) : parseInt(retryAfter) * 1000;
|
|
236
|
-
}
|
|
234
|
+
const delay = response.headers.get("rl-twm") ? Math.round(parseInt(retryAfter) * 60 * 1000) : parseInt(retryAfter) * 1000;
|
|
237
235
|
|
|
238
236
|
// adds jitter
|
|
239
|
-
return
|
|
237
|
+
return delay + Math.random() * 1000;
|
|
240
238
|
};
|
|
241
239
|
exports.getRetryDelay = getRetryDelay;
|
|
242
240
|
const groupSeatsByPriceSection = (seats, pricing, priceSectionIds) => {
|