iticket-seatingplan-dev 1.7.8 → 1.8.0

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.
@@ -9,9 +9,7 @@ require("leaflet-draw/dist/leaflet.draw.css");
9
9
  var _react = _interopRequireWildcard(require("react"));
10
10
  var _reactLeaflet = require("react-leaflet");
11
11
  var L = _interopRequireWildcard(require("leaflet"));
12
- var _reactLeafletDraw = require("react-leaflet-draw");
13
12
  var _gestureHandling2 = require("./gestureHandling");
14
- var _reactLeafletCustomControl = _interopRequireDefault(require("react-leaflet-custom-control"));
15
13
  var _encodedSvgs = require("./assets/encodedSvgs");
16
14
  var _utils = require("../utils");
17
15
  var _PriceButton = _interopRequireDefault(require("./PriceButton"));
@@ -19,8 +17,8 @@ var _Flexi = _interopRequireDefault(require("./Flexi"));
19
17
  var _CloseIcon = _interopRequireDefault(require("./icons/CloseIcon"));
20
18
  var _TicketIcon = _interopRequireDefault(require("./icons/TicketIcon"));
21
19
  var _FlexiIcon = _interopRequireDefault(require("./icons/FlexiIcon"));
22
- var _EditIcon = _interopRequireDefault(require("./icons/EditIcon"));
23
20
  var _HoverPopup = _interopRequireDefault(require("./HoverPopup"));
21
+ var _Controls = _interopRequireDefault(require("./Controls"));
24
22
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
25
23
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
26
24
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -64,7 +62,6 @@ function SeatMap(_ref) {
64
62
  setInvalidSeatsPopupOpen,
65
63
  batchAddTicketsToCart
66
64
  } = _ref;
67
- const [isLegendOpen, setIsLegendOpen] = (0, _react.useState)(false);
68
65
  const [isDragging, setIsDragging] = (0, _react.useState)(false);
69
66
  const [highlightedSeats, setHighlightedSeats] = (0, _react.useState)([]);
70
67
  const [greyedOutSeats, setGreyedOutSeats] = (0, _react.useState)([]);
@@ -79,11 +76,22 @@ function SeatMap(_ref) {
79
76
  const drawRef = (0, _react.useRef)(null);
80
77
  const popupRef = (0, _react.useRef)(null);
81
78
  const prevHovered = (0, _react.useRef)(null);
79
+ const resetTooltipTimeoutRef = (0, _react.useRef)(null);
82
80
  const hideTooltipTimeoutRef = (0, _react.useRef)(null);
83
- (0, _react.useEffect)(() => {
84
- prevHovered.current = hoveredSeat;
85
- }, [hoveredSeat]);
86
81
  const map = (0, _reactLeaflet.useMap)();
82
+ const seatsMap = (0, _react.useMemo)(() => new Map(seats.seats.map(s => {
83
+ const isIcon = (!priceSectionIds || priceSectionIds.includes(s.psId)) && (s.s === _utils.statuses.WHEELCHAIR_ACCESS || s.s === _utils.statuses.USER_PENDING && s.m);
84
+ const latlng = (0, _utils.getSeatCenterLatLng)(s, isIcon, height);
85
+ const lat = s.r.includes("NORTH") ? (0, _utils.getNorthSeatLat)(s, height) : latlng.lat;
86
+ const seatCenter = {
87
+ lat,
88
+ lng: latlng.lng
89
+ };
90
+ return [s.sId, _objectSpread(_objectSpread({}, s), {}, {
91
+ center: seatCenter
92
+ })];
93
+ })), [seats.seats, height, priceSectionIds]);
94
+ const isOrphanMode = (seats === null || seats === void 0 ? void 0 : seats.preventOrphanedSeats) && desiredSeatQuantity > 0;
87
95
  const isTouchScreen = (0, _utils.getIsTouchScreen)();
88
96
 
89
97
  // L.drawLocal.draw.toolbar.buttons.rectangle = "Box select";
@@ -127,6 +135,9 @@ function SeatMap(_ref) {
127
135
  }
128
136
  }
129
137
  });
138
+ (0, _react.useEffect)(() => {
139
+ prevHovered.current = hoveredSeat;
140
+ }, [hoveredSeat]);
130
141
  (0, _react.useEffect)(() => {
131
142
  const keyboardHandler = e => {
132
143
  if (e.key === "Escape") {
@@ -174,37 +185,48 @@ function SeatMap(_ref) {
174
185
  window.removeEventListener("keydown", keyboardHandler);
175
186
  }
176
187
  };
177
- }, [isFullScreen, ticketPopupOpen, mode]);
178
- const getNorthSeatLat = seat => {
179
- return height / 33.33 - height / 33.33 * seat.y * 0.0105 + 1.4;
180
- };
181
- const getSeatXy = e => {
182
- const latlng = e.target.getLatLng();
183
- const clickedSeatXy = map.latLngToContainerPoint(latlng);
184
- return clickedSeatXy;
185
- };
186
- const getSeatRadius = e => {
187
- const latlng = e.target.getLatLng();
188
- const radius = e.target.getRadius();
189
- const point1 = map.latLngToLayerPoint(latlng);
190
- const point2 = map.latLngToLayerPoint([latlng.lat, latlng.lng + radius / 111320]); // Approx. conversion
191
- const pixelRadius = Math.abs(point2.x - point1.x);
192
- return pixelRadius;
193
- };
194
- const getSeatCenterLatLng = (seat, isIcon) => {
195
- return {
196
- lat: height * 0.05 - seat.y / (height > 800 ? height > 999 ? isIcon ? 3.5 : 3.45 : 3.3 : 3.35) - (height > 800 ? height > 999 ? height * 0.0201 : height * 0.0198 : height > 587 ? height * 0.0201 : height > 399 ? height * 0.02035 : height * 0.0207),
197
- lng: seat.x * 0.3 + 0.15
188
+ }, [isFullScreen, ticketPopupOpen, mode, canMultiSelect, map, pricingPopupOpen, setMode, setPricingPopupOpen, setSelectedSeats, setIsFullScreen]);
189
+
190
+ // gesture-handling plugin disallows scroll zooming and touch panning,
191
+ // to allow users to scroll past the map when it's not full screen.
192
+ (0, _react.useEffect)(() => {
193
+ if (!isFullScreen) {
194
+ map.addHandler("gestureHandling", _gestureHandling2.GestureHandling);
195
+ // @ts-expect-error works
196
+ map.gestureHandling.enable();
197
+ }
198
+ }, [map, isFullScreen]);
199
+ (0, _react.useEffect)(() => {
200
+ if (mode === _utils.modes.SINGLE) {
201
+ map.dragging.enable();
202
+ } else {
203
+ map.dragging.disable();
204
+ }
205
+ }, [mode, map]);
206
+ (0, _react.useEffect)(() => {
207
+ const resetTooltipTimeout = resetTooltipTimeoutRef.current;
208
+ const hideTooltipTimeout = hideTooltipTimeoutRef.current;
209
+ return () => {
210
+ if (resetTooltipTimeout) {
211
+ clearTimeout(resetTooltipTimeout);
212
+ }
213
+ if (hideTooltipTimeout) {
214
+ clearTimeout(hideTooltipTimeout);
215
+ }
198
216
  };
199
- };
217
+ }, []);
200
218
  const handleDrawBox = v => {
201
219
  var _seats$seats, _drawLayersRef$curren;
202
220
  if (!canMultiSelect || !(v.layer instanceof L.Rectangle)) return;
203
221
  const seatsToBook = [];
204
222
  const boxBounds = v.layer.getBounds();
205
223
  seats === null || seats === void 0 || (_seats$seats = seats.seats) === null || _seats$seats === void 0 || _seats$seats.forEach(seat => {
206
- const seatCenter = getSeatCenterLatLng(seat, false);
207
- const latlng = [seat.r.includes("NORTH") ? getNorthSeatLat(seat) : seatCenter.lat, seatCenter.lng];
224
+ var _seatsMap$get;
225
+ const seatCenter = ((_seatsMap$get = seatsMap.get(seat.sId)) === null || _seatsMap$get === void 0 ? void 0 : _seatsMap$get.center) || {
226
+ lat: seat.y,
227
+ lng: seat.x
228
+ };
229
+ const latlng = [seatCenter.lat, seatCenter.lng];
208
230
  if (boxBounds.contains(latlng) && !seatsToBook.find(s => s.ssId === seat.ssId) && seat.s === _utils.statuses.UNSOLD) {
209
231
  seatsToBook.push(seat);
210
232
  }
@@ -215,249 +237,230 @@ function SeatMap(_ref) {
215
237
  }
216
238
  (_drawLayersRef$curren = drawLayersRef.current) === null || _drawLayersRef$curren === void 0 || _drawLayersRef$curren.clearLayers();
217
239
  };
240
+ const handleHighlightSeats = (0, _react.useCallback)((e, s) => {
241
+ if (s.s === _utils.statuses.UNSOLD && mode === _utils.modes.SINGLE) {
242
+ const seatsToBook = (0, _utils.getValidSeats)(s, seatsMap, desiredSeatQuantity);
243
+ if (seatsToBook.valid) {
244
+ setHighlightedSeats(seatsToBook.seats);
245
+ } else {
246
+ setGreyedOutSeats(seatsToBook.seats);
247
+ setHighlightedSeats([]);
248
+ }
249
+ } else if (highlightedSeats.length > 0) {
250
+ setHighlightedSeats([]);
251
+ }
252
+ }, [mode, seatsMap, desiredSeatQuantity, highlightedSeats.length]);
253
+ const onClickSeat = (e, s, isSingleFlexi, hasSeatPrices) => {
254
+ if (resetTooltipTimeoutRef.current) {
255
+ clearTimeout(resetTooltipTimeoutRef.current);
256
+ }
257
+ if (hideTooltipTimeoutRef.current) {
258
+ clearTimeout(hideTooltipTimeoutRef.current);
259
+ }
260
+ if (isTouchScreen) {
261
+ setMousePos({
262
+ x: e.containerPoint.x,
263
+ y: e.containerPoint.y
264
+ });
265
+ }
266
+ if (s.loading) {
267
+ return;
268
+ }
218
269
 
219
- // gesture-handling plugin disallows scroll zooming and touch panning,
220
- // to allow users to scroll past the map when it's not full screen.
221
- (0, _react.useEffect)(() => {
222
- if (!isFullScreen) {
223
- map.addHandler("gestureHandling", _gestureHandling2.GestureHandling);
224
- // @ts-ignore
225
- map.gestureHandling.enable();
270
+ // pos multi-select mode
271
+ if (mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE || mode === _utils.modes.DRAW || selectedSeats.length > 0) {
272
+ map.closePopup();
273
+ return;
226
274
  }
227
- }, [map, isFullScreen]);
228
- (0, _react.useEffect)(() => {
229
- if (mode === _utils.modes.SINGLE) {
230
- map.dragging.enable();
231
- } else {
232
- map.dragging.disable();
275
+
276
+ // orphan multi-select mode
277
+ if (isOrphanMode) {
278
+ map.closePopup();
279
+ if (s.s === _utils.statuses.USER_PENDING) {
280
+ const newSeatsToRemove = (0, _utils.getAdjacentBookedSeats)(s, seatsMap);
281
+ if (newSeatsToRemove.length === 1) {
282
+ handleClickSeat(e, s);
283
+ } else {
284
+ setSeatsToRemove(newSeatsToRemove);
285
+ setRemoveMultipleSeatsPopupOpen(true);
286
+ }
287
+ return;
288
+ }
289
+ if (isTouchScreen && (clickedSeat === null || clickedSeat === void 0 ? void 0 : clickedSeat.ssId) !== s.ssId) {
290
+ setClickedSeat(_objectSpread(_objectSpread({}, s), {}, {
291
+ offset: (0, _utils.getSeatRadius)(e, map),
292
+ xy: (0, _utils.getSeatXy)(e, map)
293
+ }));
294
+ handleHighlightSeats(e, s);
295
+ setIsHoveringOnSeat(true);
296
+ setHoveredSeat(_objectSpread(_objectSpread({}, s), {}, {
297
+ infoVisible: true
298
+ }));
299
+ return;
300
+ }
301
+ if (highlightedSeats.length === desiredSeatQuantity) {
302
+ setClickedSeat(null);
303
+ const groupedSeats = (0, _utils.groupSeatsByPriceSection)(highlightedSeats, seats.pricing, priceSectionIds);
304
+ const priceages = Object.values(groupedSeats).flatMap(group => group.priceages.map(pa => pa.priceage));
305
+ if (priceages.length === 1 && (priceages[0].q === null || priceages[0].q >= desiredSeatQuantity) && !isSingleFlexi) {
306
+ batchAddTicketsToCart(highlightedSeats.map(s => ({
307
+ seat: s,
308
+ priceage: priceages[0]
309
+ })));
310
+ setHighlightedSeats([]);
311
+ setSelectedSeats([]);
312
+ setHoveredSeat(prev => _objectSpread(_objectSpread({}, prev), {}, {
313
+ infoVisible: false
314
+ }));
315
+ } else {
316
+ setSelectedSeats([...highlightedSeats]);
317
+ setPricingPopupOpen(true);
318
+ }
319
+ } else if (greyedOutSeats.some(gs => gs.ssId === s.ssId)) {
320
+ setInvalidSeatsPopupOpen(true);
321
+ }
322
+ return;
233
323
  }
234
- }, [mode, map]);
235
- const seatsMap = (0, _react.useMemo)(() => new Map(seats.seats.map(s => [s.sId, s])), [seats.seats]);
324
+
325
+ // single select mode
326
+ if (mode === _utils.modes.SINGLE && hasSeatPrices) {
327
+ handleClickSeat(e, s);
328
+ }
329
+ };
330
+ const onMouseDown = (0, _react.useCallback)((s, hasSeatPrices) => {
331
+ if ((mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE) && canMultiSelect && hasSeatPrices && !selectedSeats.find(seat => seat.ssId === s.ssId) && s.s === (mode === _utils.modes.DRAG ? _utils.statuses.UNSOLD : _utils.statuses.USER_PENDING)) {
332
+ setSelectedSeats(prev => [...prev, s]);
333
+ }
334
+ }, [mode, canMultiSelect, selectedSeats, setSelectedSeats]);
335
+ const onHover = (0, _react.useCallback)((e, s, hasSeatPrices) => {
336
+ if (resetTooltipTimeoutRef.current) {
337
+ clearTimeout(resetTooltipTimeoutRef.current);
338
+ }
339
+ if (hideTooltipTimeoutRef.current) {
340
+ clearTimeout(hideTooltipTimeoutRef.current);
341
+ }
342
+ if ((mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE) && isDragging && canMultiSelect && hasSeatPrices && !selectedSeats.find(seat => seat.ssId === s.ssId) && s.s === (mode === _utils.modes.DRAG ? _utils.statuses.UNSOLD : _utils.statuses.USER_PENDING)) {
343
+ setSelectedSeats(prev => [...prev, s]);
344
+ return;
345
+ }
346
+ setIsHoveringOnSeat(true);
347
+ setHoveredSeat(_objectSpread(_objectSpread({}, s), {}, {
348
+ infoVisible: true
349
+ }));
350
+ if (isOrphanMode) {
351
+ handleHighlightSeats(e, s);
352
+ }
353
+ }, [mode, isOrphanMode, isDragging, canMultiSelect, selectedSeats, handleHighlightSeats, setSelectedSeats]);
354
+ const onMouseOut = (0, _react.useCallback)(() => {
355
+ if (greyedOutSeats.length > 0) {
356
+ setGreyedOutSeats([]);
357
+ }
358
+ if (clickedSeat) {
359
+ setClickedSeat(null);
360
+ }
361
+ if (isHoveringOnSeat) {
362
+ hideTooltipTimeoutRef.current = setTimeout(() => {
363
+ setIsHoveringOnSeat(false);
364
+ }, isTouchScreen ? 400 : 0);
365
+ }
366
+ if (hoveredSeat !== null && hoveredSeat !== void 0 && hoveredSeat.infoVisible || (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0) {
367
+ {
368
+ resetTooltipTimeoutRef.current = setTimeout(() => {
369
+ if (hoveredSeat !== null && hoveredSeat !== void 0 && hoveredSeat.infoVisible) {
370
+ setHoveredSeat(prev => _objectSpread(_objectSpread({}, prev), {}, {
371
+ infoVisible: false
372
+ }));
373
+ }
374
+ if ((highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0) {
375
+ setHighlightedSeats([]);
376
+ }
377
+ }, 400);
378
+ }
379
+ }
380
+ }, [greyedOutSeats, clickedSeat, isHoveringOnSeat, hoveredSeat, highlightedSeats, isTouchScreen]);
381
+ const onMouseMove = e => {
382
+ setMousePos({
383
+ x: e.containerPoint.x,
384
+ y: e.containerPoint.y
385
+ });
386
+ };
236
387
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
237
388
  className: "mobile-tooltip",
238
389
  style: {
239
- opacity: clickedSeat ? 1 : 0,
390
+ opacity: clickedSeat && (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0 ? 1 : 0,
240
391
  top: clickedSeat ? clickedSeat.xy.y - clickedSeat.offset - 12 : -10000,
241
- left: clickedSeat ? clickedSeat.xy.x : -10000
392
+ left: clickedSeat ? clickedSeat.xy.x : -10000,
393
+ transitionDuration: clickedSeat ? "100ms" : "0ms"
242
394
  }
243
395
  }, "Tap again to select"), /*#__PURE__*/_react.default.createElement(_HoverPopup.default, {
244
396
  hoveredSeat: hoveredSeat,
245
397
  highlightedSeats: (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0 ? highlightedSeats : null,
246
398
  mousePos: mousePos,
247
- show: ((hoveredSeat === null || hoveredSeat === void 0 ? void 0 : hoveredSeat.infoVisible) || (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0) && !ticketPopupOpen && !pricingPopupOpen && !isDragging && isHoveringOnSeat,
399
+ show: ((hoveredSeat === null || hoveredSeat === void 0 ? void 0 : hoveredSeat.infoVisible) && !isOrphanMode || (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0) && !ticketPopupOpen && !pricingPopupOpen && !isDragging && isHoveringOnSeat,
248
400
  availablePrices: (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0 ? highlightedSeats.flatMap(s => {
249
401
  var _seats$pricing;
250
402
  return ((_seats$pricing = seats.pricing) === null || _seats$pricing === void 0 ? void 0 : _seats$pricing.filter(p => p.psId === s.psId && (!priceSectionIds || priceSectionIds.includes(p.psId)) && (p.q === null || p.q > 0))) || [];
251
403
  }) : hoveredSeat ? ((_seats$pricing2 = seats.pricing) === null || _seats$pricing2 === void 0 ? void 0 : _seats$pricing2.filter(p => p.psId === hoveredSeat.psId && (!priceSectionIds || priceSectionIds.includes(p.psId)) && (p.q === null || p.q > 0))) || [] : undefined,
252
- prevHovered: prevHovered.current
253
- }), seats.preventOrphanedSeats && /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
254
- position: "topright"
255
- }, /*#__PURE__*/_react.default.createElement("div", {
256
- className: "extra-controls seat-quantity-control"
257
- }, /*#__PURE__*/_react.default.createElement("button", {
258
- title: "Quantity of seats to book",
259
- onClick: () => {
260
- setSelectQuantityPopupOpen(prev => !prev);
261
- },
262
- className: "leaflet-control-seat-quantity"
263
- }, /*#__PURE__*/_react.default.createElement("span", null, "Selecting ", desiredSeatQuantity, " ", desiredSeatQuantity === 1 ? "seat" : "seats"), /*#__PURE__*/_react.default.createElement(_EditIcon.default, {
264
- height: "16px",
265
- width: "16px",
266
- strokeWidth: "2"
267
- })))), /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
268
- position: "bottomright"
269
- }, /*#__PURE__*/_react.default.createElement("div", {
270
- className: "legendBox"
271
- }, /*#__PURE__*/_react.default.createElement("div", {
272
- className: "legend-header"
273
- }, /*#__PURE__*/_react.default.createElement("button", {
274
- className: "legend-button ".concat(isLegendOpen ? "expanded" : ""),
275
- onClick: () => setIsLegendOpen(!isLegendOpen)
276
- }, /*#__PURE__*/_react.default.createElement("p", null, isLegendOpen ? "LEGEND:" : "VIEW LEGEND")), isLegendOpen && /*#__PURE__*/_react.default.createElement("button", {
277
- className: "close-button",
278
- onClick: () => setIsLegendOpen(false)
279
- }, /*#__PURE__*/_react.default.createElement("img", {
280
- src: _encodedSvgs.closeIcon,
281
- alt: "close"
282
- }))), /*#__PURE__*/_react.default.createElement("div", {
283
- className: "legend-contents ".concat(isLegendOpen ? "expanded" : "")
284
- }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
285
- className: "legend-item"
286
- }, /*#__PURE__*/_react.default.createElement("div", {
287
- className: "legend-symbol legend-available"
288
- }), /*#__PURE__*/_react.default.createElement("p", null, "available"))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
289
- className: "legend-item"
290
- }, /*#__PURE__*/_react.default.createElement("div", {
291
- className: "legend-symbol legend-sold"
292
- }), /*#__PURE__*/_react.default.createElement("p", null, "sold"))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
293
- className: "legend-item"
294
- }, /*#__PURE__*/_react.default.createElement("div", {
295
- className: "legend-symbol legend-in-cart"
296
- }), /*#__PURE__*/_react.default.createElement("p", null, "in cart"))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
297
- className: "legend-item"
298
- }, /*#__PURE__*/_react.default.createElement("img", {
299
- src: _encodedSvgs.wheelchairIcon,
300
- width: 15,
301
- height: 15
302
- }), /*#__PURE__*/_react.default.createElement("p", null, "wheelchair"))), ((_seats$seats2 = seats.seats) === null || _seats$seats2 === void 0 ? void 0 : _seats$seats2.filter(seat => seat.m).length) > 0 ? /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
303
- className: "legend-item"
304
- }, /*#__PURE__*/_react.default.createElement("img", {
305
- src: _encodedSvgs.userIcon,
306
- width: 15,
307
- height: 15
308
- }), /*#__PURE__*/_react.default.createElement("p", null, "membership seats"))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null)))), /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
309
- position: "topleft"
310
- }, /*#__PURE__*/_react.default.createElement("div", {
311
- className: "extra-controls"
312
- }, /*#__PURE__*/_react.default.createElement("button", {
313
- title: "Re-centre Seating Plan",
314
- onClick: () => map.fitBounds(bounds),
315
- className: "leaflet-control-zoom-in"
316
- }, /*#__PURE__*/_react.default.createElement("img", {
317
- src: "https://au-iticket-shop-legacy.azurewebsites.net/assets/images/fit-icon.jpg",
318
- style: {
319
- height: "17px"
320
- }
321
- })), /*#__PURE__*/_react.default.createElement("button", {
322
- title: "Reload Seating Plan",
323
- disabled: isReloading,
324
- onClick: () => {
325
- initialFetch(true);
326
- map.fitBounds(bounds);
327
- },
328
- className: "leaflet-control-zoom-in reload-seating-plan",
329
- style: {
330
- background: isReloading ? "rgb(0, 230, 64)" : undefined
331
- }
332
- }, /*#__PURE__*/_react.default.createElement("img", {
333
- className: isReloading ? "rotate" : "",
334
- src: "https://au-iticket-shop-legacy.azurewebsites.net/assets/images/refresh.png",
335
- style: {
336
- height: "17px"
337
- }
338
- })))), /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
339
- position: "topleft"
340
- }, /*#__PURE__*/_react.default.createElement("div", {
341
- className: "extra-controls full-screen-control"
342
- }, /*#__PURE__*/_react.default.createElement("button", {
343
- title: isFullScreen ? "Collapse Seating Plan" : "Expand Seating Plan",
344
- onClick: () => {
345
- setIsFullScreen(prev => !prev);
346
- },
347
- className: "leaflet-control-zoom-in"
348
- }, /*#__PURE__*/_react.default.createElement("img", {
349
- src: isFullScreen ? _encodedSvgs.collapseIcon : _encodedSvgs.expandIcon,
350
- style: {
351
- height: "24px"
352
- }
353
- })))), canMultiSelect && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
354
- position: "bottomleft"
355
- }, /*#__PURE__*/_react.default.createElement("div", {
356
- className: "extra-controls multi-select-control"
357
- }, /*#__PURE__*/_react.default.createElement("div", {
358
- className: "drag-select"
359
- }, /*#__PURE__*/_react.default.createElement("button", {
360
- title: "Drag select",
361
- onClick: () => {
362
- var _drawRef$current5;
363
- (_drawRef$current5 = drawRef.current) === null || _drawRef$current5 === void 0 || _drawRef$current5._toolbars.draw.disable();
364
- setMode(prev => prev === _utils.modes.DRAG ? _utils.modes.SINGLE : _utils.modes.DRAG);
365
- },
366
- className: "leaflet-control-zoom-in drag-button"
367
- }, /*#__PURE__*/_react.default.createElement("span", null)), /*#__PURE__*/_react.default.createElement("ul", {
368
- className: "leaflet-draw-actions leaflet-draw-actions-top leaflet-draw-actions-bottom cancel-button",
369
- style: {
370
- display: mode === _utils.modes.DRAG ? "block" : "none"
371
- }
372
- }, /*#__PURE__*/_react.default.createElement("li", null, /*#__PURE__*/_react.default.createElement("a", {
373
- href: "#",
374
- onClick: e => {
375
- e.preventDefault();
376
- setMode(_utils.modes.SINGLE);
377
- }
378
- }, "Cancel")))), (bookedSeats.length > 0 || mode === _utils.modes.REMOVE) && /*#__PURE__*/_react.default.createElement("div", {
379
- className: "remove-seats"
380
- }, /*#__PURE__*/_react.default.createElement("button", {
381
- title: "Remove seats",
382
- onClick: () => {
383
- var _drawRef$current6;
384
- (_drawRef$current6 = drawRef.current) === null || _drawRef$current6 === void 0 || _drawRef$current6._toolbars.draw.disable();
385
- setMode(_utils.modes.REMOVE);
386
- },
387
- className: "leaflet-control-zoom-in remove-button"
388
- }, /*#__PURE__*/_react.default.createElement("span", null)), /*#__PURE__*/_react.default.createElement("ul", {
389
- className: "leaflet-draw-actions leaflet-draw-actions-top leaflet-draw-actions-bottom cancel-button",
390
- style: {
391
- display: mode === _utils.modes.REMOVE ? "block" : "none"
392
- }
393
- }, /*#__PURE__*/_react.default.createElement("li", null, /*#__PURE__*/_react.default.createElement("a", {
394
- href: "#",
395
- onClick: e => {
396
- e.preventDefault();
397
- setMode(_utils.modes.SINGLE);
398
- }
399
- }, "Cancel")))), /*#__PURE__*/_react.default.createElement("button", {
400
- title: "Single select",
401
- onClick: () => {
402
- var _drawRef$current7;
403
- (_drawRef$current7 = drawRef.current) === null || _drawRef$current7 === void 0 || _drawRef$current7._toolbars.draw.disable();
404
- setMode(_utils.modes.SINGLE);
405
- },
406
- className: "leaflet-control-zoom-in single-button"
407
- }, /*#__PURE__*/_react.default.createElement("span", null)))), /*#__PURE__*/_react.default.createElement(_reactLeaflet.FeatureGroup, {
408
- ref: drawLayersRef
409
- }, /*#__PURE__*/_react.default.createElement(_reactLeafletDraw.EditControl, {
410
- position: "bottomleft",
411
- onCreated: handleDrawBox,
412
- onDrawStart: () => {
413
- setMode(_utils.modes.DRAW);
414
- },
415
- onDrawStop: () => {
416
- setMode(prev => prev === _utils.modes.DRAW ? _utils.modes.SINGLE : prev);
417
- },
418
- draw: {
419
- rectangle: true,
420
- circle: false,
421
- polyline: false,
422
- polygon: false,
423
- marker: false,
424
- circlemarker: false
425
- },
426
- edit: {
427
- edit: false,
428
- remove: false
429
- },
430
- onMounted: drawInstance => {
431
- drawRef.current = drawInstance;
432
- }
433
- }))), /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
434
- position: "topright"
435
- }, /*#__PURE__*/_react.default.createElement("button", {
436
- title: "Close full screen",
437
- onClick: () => setIsFullScreen(false),
438
- className: "full-screen-close-button ".concat(isFullScreen ? "show" : "")
439
- }, /*#__PURE__*/_react.default.createElement("img", {
440
- src: _encodedSvgs.closeIcon,
441
- style: {
442
- height: "24px"
443
- }
444
- }))), /*#__PURE__*/_react.default.createElement(_reactLeaflet.ImageOverlay, {
445
- url: seats.background,
404
+ prevHovered: prevHovered.current,
405
+ isTouchScreen: isTouchScreen
406
+ }), /*#__PURE__*/_react.default.createElement(_Controls.default, {
407
+ preventOrphanedSeats: seats === null || seats === void 0 ? void 0 : seats.preventOrphanedSeats,
408
+ bounds: bounds,
409
+ setSelectQuantityPopupOpen: setSelectQuantityPopupOpen,
410
+ isFullScreen: isFullScreen,
411
+ setIsFullScreen: setIsFullScreen,
412
+ mode: mode,
413
+ setMode: setMode,
414
+ drawRef: drawRef,
415
+ drawLayersRef: drawLayersRef,
416
+ handleDrawBox: handleDrawBox,
417
+ canMultiSelect: canMultiSelect,
418
+ desiredSeatQuantity: desiredSeatQuantity,
419
+ onReload: initialFetch,
420
+ isReloading: isReloading,
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
+ hasBookedSeats: (bookedSeats === null || bookedSeats === void 0 ? void 0 : bookedSeats.length) > 0
423
+ }), /*#__PURE__*/_react.default.createElement(_reactLeaflet.ImageOverlay, {
424
+ url: seats === null || seats === void 0 ? void 0 : seats.background,
446
425
  bounds: [[0, 0], [height * 0.03, width * 0.03]],
447
426
  zIndex: 10
448
427
  }), seats && seats.seats && seats.seats.map((s, i) => {
449
- var _seats$pricing3, _chosenSeat$seat, _chosenSeat$seat2, _chosenSeat$seat3;
450
- const isIcon = (!priceSectionIds || priceSectionIds.includes(s.psId)) && (s.s === _utils.statuses.WHEELCHAIR_ACCESS || s.s === _utils.statuses.USER_PENDING && s.m);
451
- const seatCenter = getSeatCenterLatLng(s, isIcon);
428
+ var _seatsMap$get2, _seats$pricing3, _chosenSeat$seat, _chosenSeat$seat2, _chosenSeat$seat3;
429
+ const seatCenter = ((_seatsMap$get2 = seatsMap.get(s.sId)) === null || _seatsMap$get2 === void 0 ? void 0 : _seatsMap$get2.center) || {
430
+ lat: s.y,
431
+ lng: s.x
432
+ };
452
433
  const seatPrices = ((_seats$pricing3 = seats.pricing) === null || _seats$pricing3 === void 0 ? void 0 : _seats$pricing3.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && price.psId === s.psId)) || [];
453
434
  const hasSeatPrices = (seatPrices === null || seatPrices === void 0 ? void 0 : seatPrices.length) > 0;
454
435
  const isSingleFlexi = seatPrices.length === 1 && !!seatPrices[0].pMax && !!seatPrices[0].pMin && seatPrices[0].pMax > seatPrices[0].pMin;
455
- const isOrphanMode = seats.preventOrphanedSeats && desiredSeatQuantity > 0;
436
+ const eventHandlers = {
437
+ click: e => {
438
+ onClickSeat(e, s, isSingleFlexi, hasSeatPrices);
439
+ },
440
+ popupopen: popup => {
441
+ setTicketPopupOpen(true);
442
+ popupRef.current = popup;
443
+ },
444
+ popupclose: () => {
445
+ setTicketPopupOpen(false);
446
+ popupRef.current = null;
447
+ },
448
+ mousedown: () => {
449
+ onMouseDown(s, hasSeatPrices);
450
+ },
451
+ mouseout: onMouseOut
452
+ };
453
+ if (!isTouchScreen) {
454
+ eventHandlers.mouseover = e => {
455
+ onHover(e, s, hasSeatPrices);
456
+ };
457
+ eventHandlers.mousemove = onMouseMove;
458
+ }
456
459
  return /*#__PURE__*/_react.default.createElement("div", {
457
460
  key: i
458
461
  }, (s.loading || ticketPopupOpen && (chosenSeat === null || chosenSeat === void 0 || (_chosenSeat$seat = chosenSeat.seat) === null || _chosenSeat$seat === void 0 ? void 0 : _chosenSeat$seat.ssId) === s.ssId) && /*#__PURE__*/_react.default.createElement(_reactLeaflet.ImageOverlay, {
459
462
  url: "https://iticketseatingplan.blob.core.windows.net/embed/static/media/rippleload.08e6a08dd832819226ef.gif",
460
- bounds: [[(s.r.includes("NORTH") ? getNorthSeatLat(s) : seatCenter.lat) - 0.11, seatCenter.lng - 0.11], [(s.r.includes("NORTH") ? getNorthSeatLat(s) : seatCenter.lat) + 0.11, seatCenter.lng + 0.11]],
463
+ bounds: [[seatCenter.lat - 0.11, seatCenter.lng - 0.11], [seatCenter.lat + 0.11, seatCenter.lng + 0.11]],
461
464
  opacity: s.loading || ticketPopupOpen && (chosenSeat === null || chosenSeat === void 0 || (_chosenSeat$seat2 = chosenSeat.seat) === null || _chosenSeat$seat2 === void 0 ? void 0 : _chosenSeat$seat2.ssId) === s.ssId ? 100 : 0,
462
465
  zIndex: 10
463
466
  }), !priceSectionIds || priceSectionIds.includes(s.psId) ? s.s === _utils.statuses.WHEELCHAIR_ACCESS ? /*#__PURE__*/_react.default.createElement(_reactLeaflet.ImageOverlay, {
@@ -469,160 +472,10 @@ function SeatMap(_ref) {
469
472
  bounds: [[seatCenter.lat - 0.11, seatCenter.lng - 0.15], [seatCenter.lat + 0.11, seatCenter.lng + 0.15]],
470
473
  zIndex: 10
471
474
  }) : /*#__PURE__*/_react.default.createElement(_reactLeaflet.Circle, {
472
- center: [s.r.includes("NORTH") ? getNorthSeatLat(s) : seatCenter.lat, seatCenter.lng],
473
- pathOptions: (0, _utils.getInitialColor)(s, price, s.loading || ticketPopupOpen && (chosenSeat === null || chosenSeat === void 0 || (_chosenSeat$seat3 = chosenSeat.seat) === null || _chosenSeat$seat3 === void 0 ? void 0 : _chosenSeat$seat3.ssId) === s.ssId, !hasSeatPrices, selectedSeats.some(selectedSeat => selectedSeat.ssId === s.ssId) || highlightedSeats.some(hs => hs.ssId === s.ssId), greyedOutSeats.some(gs => gs.ssId === s.ssId)),
475
+ center: [seatCenter.lat, seatCenter.lng],
476
+ pathOptions: (0, _utils.getInitialColor)(s, price, s.loading || ticketPopupOpen && (chosenSeat === null || chosenSeat === void 0 || (_chosenSeat$seat3 = chosenSeat.seat) === null || _chosenSeat$seat3 === void 0 ? void 0 : _chosenSeat$seat3.ssId) === s.ssId, !hasSeatPrices, (selectedSeats.some(selectedSeat => selectedSeat.ssId === s.ssId) || highlightedSeats.some(hs => hs.ssId === s.ssId)) && isHoveringOnSeat, greyedOutSeats.some(gs => gs.ssId === s.ssId)),
474
477
  radius: 12000,
475
- eventHandlers: {
476
- click: e => {
477
- // pos multi-select mode
478
- if (mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE || mode === _utils.modes.DRAW || selectedSeats.length > 0) {
479
- map.closePopup();
480
- return;
481
- }
482
-
483
- // orphan multi-select mode
484
- if (isOrphanMode) {
485
- map.closePopup();
486
- if (s.s === _utils.statuses.USER_PENDING) {
487
- const newSeatsToRemove = (0, _utils.getAdjacentBookedSeats)(s, seatsMap);
488
- if (newSeatsToRemove.length === 1) {
489
- handleClickSeat(e, s);
490
- } else {
491
- setSeatsToRemove(newSeatsToRemove);
492
- setRemoveMultipleSeatsPopupOpen(true);
493
- }
494
- return;
495
- }
496
- if (highlightedSeats.length === desiredSeatQuantity) {
497
- if (isTouchScreen && (clickedSeat === null || clickedSeat === void 0 ? void 0 : clickedSeat.ssId) !== s.ssId) {
498
- setClickedSeat(_objectSpread(_objectSpread({}, s), {}, {
499
- offset: getSeatRadius(e),
500
- xy: getSeatXy(e)
501
- }));
502
- } else {
503
- setClickedSeat(null);
504
- const groupedSeats = (0, _utils.groupSeatsByPriceSection)(highlightedSeats, seats.pricing, priceSectionIds);
505
- const priceages = Object.values(groupedSeats).flatMap(group => group.priceages.map(pa => pa.priceage));
506
- if (priceages.length === 1 && (priceages[0].q === null || priceages[0].q >= desiredSeatQuantity) && !isSingleFlexi) {
507
- batchAddTicketsToCart(highlightedSeats.map(s => ({
508
- seat: s,
509
- priceage: priceages[0]
510
- })));
511
- setHighlightedSeats([]);
512
- setSelectedSeats([]);
513
- setHoveredSeat(prev => _objectSpread(_objectSpread({}, prev), {}, {
514
- infoVisible: false
515
- }));
516
- } else {
517
- setSelectedSeats([...highlightedSeats]);
518
- setPricingPopupOpen(true);
519
- }
520
- }
521
- return;
522
- }
523
- if (greyedOutSeats.some(gs => gs.ssId === s.ssId)) {
524
- setInvalidSeatsPopupOpen(true);
525
- }
526
- return;
527
- }
528
-
529
- // single select mode
530
- if (mode === _utils.modes.SINGLE && hasSeatPrices) {
531
- if (isTouchScreen && (clickedSeat === null || clickedSeat === void 0 ? void 0 : clickedSeat.ssId) !== s.ssId && mode === _utils.modes.SINGLE && s.s === _utils.statuses.UNSOLD && seatPrices.length === 1 && !isSingleFlexi) {
532
- setClickedSeat(_objectSpread(_objectSpread({}, s), {}, {
533
- offset: getSeatRadius(e),
534
- xy: getSeatXy(e)
535
- }));
536
- map.closePopup();
537
- } else {
538
- setClickedSeat(null);
539
- handleClickSeat(e, s);
540
- return;
541
- }
542
- }
543
- },
544
- popupopen: popup => {
545
- setTicketPopupOpen(true);
546
- popupRef.current = popup;
547
- },
548
- popupclose: () => {
549
- setTicketPopupOpen(false);
550
- popupRef.current = null;
551
- },
552
- mousedown: () => {
553
- if ((mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE) && canMultiSelect && hasSeatPrices) {
554
- if (!selectedSeats.find(seat => seat.ssId === s.ssId) && s.s === (mode === _utils.modes.DRAG ? _utils.statuses.UNSOLD : _utils.statuses.USER_PENDING)) {
555
- setSelectedSeats(prev => [...prev, s]);
556
- }
557
- }
558
- },
559
- mouseover: e => {
560
- if (hideTooltipTimeoutRef.current) {
561
- clearTimeout(hideTooltipTimeoutRef.current);
562
- }
563
- if ((mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE) && isDragging && canMultiSelect && hasSeatPrices) {
564
- if (!selectedSeats.find(seat => seat.ssId === s.ssId) && s.s === (mode === _utils.modes.DRAG ? _utils.statuses.UNSOLD : _utils.statuses.USER_PENDING)) {
565
- setSelectedSeats(prev => [...prev, s]);
566
- }
567
- } else {
568
- setIsHoveringOnSeat(true);
569
- setHoveredSeat(_objectSpread(_objectSpread({}, s), {}, {
570
- infoVisible: true
571
- }));
572
- if (isOrphanMode && s.s === _utils.statuses.UNSOLD && mode === _utils.modes.SINGLE) {
573
- const seatsToBook = (0, _utils.getValidSeats)(s, seatsMap, desiredSeatQuantity);
574
- if (seatsToBook.valid) {
575
- setHighlightedSeats(seatsToBook.seats);
576
- if (isTouchScreen && (clickedSeat === null || clickedSeat === void 0 ? void 0 : clickedSeat.ssId) !== s.ssId && !isHoveringOnSeat) {
577
- setClickedSeat(_objectSpread(_objectSpread({}, s), {}, {
578
- offset: getSeatRadius(e),
579
- xy: getSeatXy(e)
580
- }));
581
- }
582
- } else if (s.s === _utils.statuses.UNSOLD && mode === _utils.modes.SINGLE && isTouchScreen && (clickedSeat === null || clickedSeat === void 0 ? void 0 : clickedSeat.ssId) !== s.ssId && !isHoveringOnSeat && seatPrices.length === 1 && !isSingleFlexi) {
583
- setClickedSeat(_objectSpread(_objectSpread({}, s), {}, {
584
- offset: getSeatRadius(e),
585
- xy: getSeatXy(e)
586
- }));
587
- } else {
588
- setGreyedOutSeats(seatsToBook.seats);
589
- setHighlightedSeats([]);
590
- }
591
- } else if (highlightedSeats.length > 0) {
592
- setHighlightedSeats([]);
593
- }
594
- }
595
- },
596
- mouseout: async () => {
597
- if (greyedOutSeats.length > 0) {
598
- setGreyedOutSeats([]);
599
- }
600
- if (clickedSeat) {
601
- setClickedSeat(null);
602
- }
603
- if (isHoveringOnSeat) {
604
- setIsHoveringOnSeat(false);
605
- }
606
- if (hoveredSeat !== null && hoveredSeat !== void 0 && hoveredSeat.infoVisible || (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0) {
607
- hideTooltipTimeoutRef.current = setTimeout(() => {
608
- if (hoveredSeat !== null && hoveredSeat !== void 0 && hoveredSeat.infoVisible) {
609
- setHoveredSeat(prev => _objectSpread(_objectSpread({}, prev), {}, {
610
- infoVisible: false
611
- }));
612
- }
613
- if ((highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0) {
614
- setHighlightedSeats([]);
615
- }
616
- }, 400);
617
- }
618
- },
619
- mousemove: e => {
620
- setMousePos({
621
- x: e.containerPoint.x,
622
- y: e.containerPoint.y
623
- });
624
- }
625
- }
478
+ eventHandlers: eventHandlers
626
479
  }, s.s === _utils.statuses.UNSOLD && hasSeatPrices ? /*#__PURE__*/_react.default.createElement(_reactLeaflet.Popup, {
627
480
  className: "ticket-popup popup-".concat(s.sId)
628
481
  }, isSingleFlexi ? /*#__PURE__*/_react.default.createElement("div", {