iticket-seatingplan-dev 1.6.6 → 1.6.8

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.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = Map;
6
+ exports.default = SeatMap;
7
7
  require("./styles/gestureHandling.css");
8
8
  require("leaflet-draw/dist/leaflet.draw.css");
9
9
  var _react = _interopRequireWildcard(require("react"));
@@ -11,7 +11,7 @@ var _reactLeaflet = require("react-leaflet");
11
11
  var L = _interopRequireWildcard(require("leaflet"));
12
12
  var _reactLeafletDraw = require("react-leaflet-draw");
13
13
  var _gestureHandling2 = require("./gestureHandling");
14
- var _Control = _interopRequireDefault(require("./Control"));
14
+ var _reactLeafletCustomControl = _interopRequireDefault(require("react-leaflet-custom-control"));
15
15
  var _encodedSvgs = require("./assets/encodedSvgs");
16
16
  var _utils = require("../utils");
17
17
  var _PriceButton = _interopRequireDefault(require("./PriceButton"));
@@ -19,6 +19,7 @@ var _Flexi = _interopRequireDefault(require("./Flexi"));
19
19
  var _CloseIcon = _interopRequireDefault(require("./icons/CloseIcon"));
20
20
  var _TicketIcon = _interopRequireDefault(require("./icons/TicketIcon"));
21
21
  var _FlexiIcon = _interopRequireDefault(require("./icons/FlexiIcon"));
22
+ var _EditIcon = _interopRequireDefault(require("./icons/EditIcon"));
22
23
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
23
24
  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); }
24
25
  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; }
@@ -27,7 +28,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
27
28
  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; }
28
29
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
29
30
  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); }
30
- function Map(_ref) {
31
+ function SeatMap(_ref) {
31
32
  let {
32
33
  seats,
33
34
  height,
@@ -53,7 +54,12 @@ function Map(_ref) {
53
54
  pricingPopupOpen,
54
55
  setPricingPopupOpen,
55
56
  selectedSeats,
56
- setSelectedSeats
57
+ setSelectedSeats,
58
+ selectQuantityPopupOpen,
59
+ setSelectQuantityPopupOpen,
60
+ desiredSeatQuantity,
61
+ setSeatsToRemove,
62
+ setRemoveMultipleSeatsPopupOpen
57
63
  } = _ref;
58
64
  const [isLegendOpen, setIsLegendOpen] = (0, _react.useState)(false);
59
65
  const [isDragging, setIsDragging] = (0, _react.useState)(false);
@@ -195,7 +201,22 @@ function Map(_ref) {
195
201
  map.dragging.disable();
196
202
  }
197
203
  }, [mode, map]);
198
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Control.default, {
204
+ const seatsMap = (0, _react.useMemo)(() => new Map(seats.seats.map(s => [s.sId, s])), [seats.seats]);
205
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, seats.preventOrphanedSeats && /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
206
+ position: "topright"
207
+ }, /*#__PURE__*/_react.default.createElement("div", {
208
+ className: "extra-controls seat-quantity-control"
209
+ }, /*#__PURE__*/_react.default.createElement("button", {
210
+ title: "Quantity of seats to book",
211
+ onClick: () => {
212
+ setSelectQuantityPopupOpen(prev => !prev);
213
+ },
214
+ className: "leaflet-control-seat-quantity"
215
+ }, /*#__PURE__*/_react.default.createElement("span", null, "Selecting ", desiredSeatQuantity, " ", desiredSeatQuantity === 1 ? "seat" : "seats"), /*#__PURE__*/_react.default.createElement(_EditIcon.default, {
216
+ height: "16px",
217
+ width: "16px",
218
+ strokeWidth: "2"
219
+ })))), /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
199
220
  position: "bottomright"
200
221
  }, /*#__PURE__*/_react.default.createElement("div", {
201
222
  className: "legendBox"
@@ -236,7 +257,7 @@ function Map(_ref) {
236
257
  src: _encodedSvgs.userIcon,
237
258
  width: 15,
238
259
  height: 15
239
- }), /*#__PURE__*/_react.default.createElement("p", null, "membership seats"))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null)))), /*#__PURE__*/_react.default.createElement(_Control.default, {
260
+ }), /*#__PURE__*/_react.default.createElement("p", null, "membership seats"))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null)))), /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
240
261
  position: "topleft"
241
262
  }, /*#__PURE__*/_react.default.createElement("div", {
242
263
  className: "extra-controls"
@@ -266,7 +287,7 @@ function Map(_ref) {
266
287
  style: {
267
288
  height: "17px"
268
289
  }
269
- })))), /*#__PURE__*/_react.default.createElement(_Control.default, {
290
+ })))), /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
270
291
  position: "topleft"
271
292
  }, /*#__PURE__*/_react.default.createElement("div", {
272
293
  className: "extra-controls full-screen-control"
@@ -281,7 +302,7 @@ function Map(_ref) {
281
302
  style: {
282
303
  height: "24px"
283
304
  }
284
- })))), canMultiSelect && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Control.default, {
305
+ })))), canMultiSelect && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
285
306
  position: "bottomleft"
286
307
  }, /*#__PURE__*/_react.default.createElement("div", {
287
308
  className: "extra-controls multi-select-control"
@@ -361,7 +382,7 @@ function Map(_ref) {
361
382
  onMounted: drawInstance => {
362
383
  drawRef.current = drawInstance;
363
384
  }
364
- }))), /*#__PURE__*/_react.default.createElement(_Control.default, {
385
+ }))), /*#__PURE__*/_react.default.createElement(_reactLeafletCustomControl.default, {
365
386
  position: "topright"
366
387
  }, /*#__PURE__*/_react.default.createElement("button", {
367
388
  title: "Close full screen",
@@ -381,6 +402,7 @@ function Map(_ref) {
381
402
  const isIcon = (!priceSectionIds || priceSectionIds.includes(s.psId)) && (s.s === _utils.statuses.WHEELCHAIR_ACCESS || s.s === _utils.statuses.USER_PENDING && s.m);
382
403
  const seatCenter = getSeatCenterLatLng(s, isIcon);
383
404
  const seatPrices = seats.pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && price.psId === s.psId);
405
+ const hasSeatPrices = (seatPrices === null || seatPrices === void 0 ? void 0 : seatPrices.length) > 0;
384
406
  const isSingleFlexi = seatPrices.length === 1 && !!seatPrices[0].pMax && !!seatPrices[0].pMin && seatPrices[0].pMax > seatPrices[0].pMin;
385
407
  return /*#__PURE__*/_react.default.createElement("div", {
386
408
  key: i
@@ -399,16 +421,23 @@ function Map(_ref) {
399
421
  zIndex: 10
400
422
  }) : /*#__PURE__*/_react.default.createElement(_reactLeaflet.Circle, {
401
423
  center: [s.r.includes("NORTH") ? getNorthSeatLat(s) : seatCenter.lat, seatCenter.lng],
402
- pathOptions: (0, _utils.getInitialColor)(s, price
424
+ pathOptions: (0, _utils.getInitialColor)(s, price, !hasSeatPrices,
403
425
  // TEST selected state for multiselect
404
- // !!selectedSeats.find(
405
- // (selectedSeat) => selectedSeat.ssId === s.ssId
406
- // )
407
- ),
426
+ !!selectedSeats.find(selectedSeat => selectedSeat.ssId === s.ssId)),
408
427
  radius: 12000,
409
428
  eventHandlers: {
410
429
  click: e => {
411
- if (mode === _utils.modes.SINGLE) {
430
+ if (seats.preventOrphanedSeats && desiredSeatQuantity > 0) {
431
+ map.closePopup();
432
+ if (s.s === _utils.statuses.USER_PENDING) {
433
+ const newSeatsToRemove = (0, _utils.getAdjacentBookedSeats)(s, seatsMap);
434
+ setSeatsToRemove(newSeatsToRemove);
435
+ setRemoveMultipleSeatsPopupOpen(true);
436
+ }
437
+ if (selectedSeats.length > 0 && selectedSeats.length === desiredSeatQuantity) {
438
+ setPricingPopupOpen(true);
439
+ } else if (s.s === _utils.statuses.USER_PENDING) {}
440
+ } else if (mode === _utils.modes.SINGLE && hasSeatPrices) {
412
441
  handleClickSeat(e, s);
413
442
  }
414
443
  },
@@ -421,17 +450,23 @@ function Map(_ref) {
421
450
  popupRef.current = null;
422
451
  },
423
452
  mousedown: () => {
424
- if ((mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE) && canMultiSelect) {
453
+ if ((mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE) && canMultiSelect && hasSeatPrices) {
425
454
  if (!selectedSeats.find(seat => seat.ssId === s.ssId) && s.s === (mode === _utils.modes.DRAG ? _utils.statuses.UNSOLD : _utils.statuses.USER_PENDING)) {
426
455
  setSelectedSeats(prev => [...prev, s]);
427
456
  }
428
457
  }
429
458
  },
430
459
  mouseover: () => {
431
- if ((mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE) && isDragging && canMultiSelect) {
460
+ if ((mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE) && isDragging && canMultiSelect && hasSeatPrices) {
432
461
  if (!selectedSeats.find(seat => seat.ssId === s.ssId) && s.s === (mode === _utils.modes.DRAG ? _utils.statuses.UNSOLD : _utils.statuses.USER_PENDING)) {
433
462
  setSelectedSeats(prev => [...prev, s]);
434
463
  }
464
+ } else {
465
+ setSelectedSeats([]);
466
+ if (seats.preventOrphanedSeats && desiredSeatQuantity > 0 && s.s === _utils.statuses.UNSOLD) {
467
+ const seatsToBook = (0, _utils.getValidSeats)(s, seatsMap, desiredSeatQuantity);
468
+ setSelectedSeats(seatsToBook);
469
+ }
435
470
  }
436
471
  }
437
472
  }
@@ -440,7 +475,7 @@ function Map(_ref) {
440
475
  className: "seatname-tooltip",
441
476
  direction: "top",
442
477
  offset: [0, height * 0.03 + -30]
443
- }, s.r + "-" + s.c), s.s === _utils.statuses.UNSOLD && /*#__PURE__*/_react.default.createElement(_reactLeaflet.Popup, {
478
+ }, s.r + "-" + s.c), s.s === _utils.statuses.UNSOLD && hasSeatPrices ? /*#__PURE__*/_react.default.createElement(_reactLeaflet.Popup, {
444
479
  className: "ticket-popup popup-".concat(s.sId)
445
480
  }, isSingleFlexi ? /*#__PURE__*/_react.default.createElement("div", {
446
481
  className: "single-flexi"
@@ -488,7 +523,7 @@ function Map(_ref) {
488
523
  className: "heading"
489
524
  }, "Select option:"), /*#__PURE__*/_react.default.createElement("div", {
490
525
  className: "priceages"
491
- }, seats.pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && price.psId === s.psId).map(price => /*#__PURE__*/_react.default.createElement(_PriceButton.default, {
526
+ }, seatPrices.map(price => /*#__PURE__*/_react.default.createElement(_PriceButton.default, {
492
527
  key: price.paId,
493
528
  price: price,
494
529
  addToCart: amount => addTicketToCart(s, _objectSpread(_objectSpread({}, price), {}, {
@@ -506,6 +541,6 @@ function Map(_ref) {
506
541
  }
507
542
  }
508
543
  }
509
- }))))))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null));
544
+ })))))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null)) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null));
510
545
  }));
511
546
  }
@@ -8,6 +8,7 @@ var _react = _interopRequireWildcard(require("react"));
8
8
  var _utils = require("../utils");
9
9
  var _encodedSvgs = require("./assets/encodedSvgs");
10
10
  var _Flexi = _interopRequireDefault(require("./Flexi"));
11
+ var _TicketIcon = _interopRequireDefault(require("./icons/TicketIcon"));
11
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
13
  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); }
13
14
  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; }
@@ -61,34 +62,43 @@ const PriceSelect = _ref => {
61
62
  };
62
63
  function PricingPopup(_ref2) {
63
64
  let {
64
- cancelPriceSelect,
65
+ cancel,
65
66
  groupedSelectedSeats,
66
67
  pricing,
67
68
  priceSectionIds,
68
- batchAddTicketsToCart
69
+ batchAddTicketsToCart,
70
+ selectedSeatsWithPricing,
71
+ singleSeats
69
72
  } = _ref2;
70
- const [seatsToBook, setSeatsToBook] = (0, _react.useState)(groupedSelectedSeats);
73
+ const [seatGroupsToBook, setSeatGroupsToBook] = (0, _react.useState)(groupedSelectedSeats);
74
+ const [singleSeatsToBook, setSingleSeatsToBook] = (0, _react.useState)(selectedSeatsWithPricing);
71
75
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
72
76
  className: "pricing-popup-backdrop",
73
- onClick: cancelPriceSelect
77
+ onClick: cancel
74
78
  }), /*#__PURE__*/_react.default.createElement("div", {
75
79
  className: "pricing-popup",
76
80
  role: "dialog",
77
81
  "aria-modal": "true"
78
82
  }, /*#__PURE__*/_react.default.createElement("div", {
79
83
  className: "popup-header"
80
- }, /*#__PURE__*/_react.default.createElement("h3", null, "Choose prices"), /*#__PURE__*/_react.default.createElement("button", {
84
+ }, /*#__PURE__*/_react.default.createElement(_TicketIcon.default, {
85
+ className: "ticket-icon",
86
+ height: "86px",
87
+ width: "86px"
88
+ }), /*#__PURE__*/_react.default.createElement("button", {
81
89
  className: "close-button",
82
90
  "aria-label": "close popup",
83
- onClick: cancelPriceSelect
91
+ onClick: cancel
84
92
  }, /*#__PURE__*/_react.default.createElement("img", {
85
- src: _encodedSvgs.closeIcon,
93
+ src: _encodedSvgs.closeIconWhite,
86
94
  alt: "close",
87
95
  height: "20px",
88
96
  width: "20px"
89
- }))), /*#__PURE__*/_react.default.createElement("div", {
97
+ })), /*#__PURE__*/_react.default.createElement("h3", null, "Choose prices")), /*#__PURE__*/_react.default.createElement("div", {
98
+ className: "pricing-popup-content"
99
+ }, /*#__PURE__*/_react.default.createElement("div", {
90
100
  className: "seat-list"
91
- }, Object.entries(seatsToBook).map(_ref3 => {
101
+ }, !singleSeats && groupedSelectedSeats ? Object.entries(seatGroupsToBook).map(_ref3 => {
92
102
  let [id, seatGroup] = _ref3;
93
103
  const seatPriceages = pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && price.psId === parseInt(id));
94
104
  return /*#__PURE__*/_react.default.createElement("div", {
@@ -102,27 +112,55 @@ function PricingPopup(_ref2) {
102
112
  seatGroup: seatGroup,
103
113
  seatPriceages: seatPriceages,
104
114
  updateSeatGroupPriceage: newPriceage => {
105
- const newSeats = _objectSpread({}, seatsToBook);
115
+ const newSeats = _objectSpread({}, seatGroupsToBook);
106
116
  newSeats[id].priceage = newPriceage;
107
- setSeatsToBook(newSeats);
117
+ setSeatGroupsToBook(newSeats);
118
+ }
119
+ }) : /*#__PURE__*/_react.default.createElement("p", {
120
+ className: "no-prices-available"
121
+ }, "Oops, looks like there are no prices available for this section."));
122
+ }) : singleSeats && selectedSeatsWithPricing ? selectedSeatsWithPricing.map(_ref4 => {
123
+ let {
124
+ seat,
125
+ priceage
126
+ } = _ref4;
127
+ const seatPriceages = pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && price.psId === seat.psId);
128
+ return /*#__PURE__*/_react.default.createElement("div", {
129
+ key: seat.ssId,
130
+ className: "seat-group"
131
+ }, /*#__PURE__*/_react.default.createElement("div", {
132
+ className: "seat-group-header"
133
+ }, /*#__PURE__*/_react.default.createElement("h4", null, "Seat", " ".concat(seat.r, "-").concat(seat.c))), seatPriceages.filter(price => price.is_available !== false).length > 0 ? /*#__PURE__*/_react.default.createElement(PriceSelect, {
134
+ seatGroup: {
135
+ seats: [seat],
136
+ priceage
137
+ },
138
+ seatPriceages: seatPriceages,
139
+ updateSeatGroupPriceage: newPriceage => {
140
+ const newSeats = _objectSpread({}, singleSeatsToBook);
141
+ const currSeat = newSeats.find(s => s.seat.ssId === seat.ssId);
142
+ if (currSeat) {
143
+ currSeat.priceage = newPriceage;
144
+ }
145
+ setSingleSeatsToBook(newSeats);
108
146
  }
109
147
  }) : /*#__PURE__*/_react.default.createElement("p", {
110
148
  className: "no-prices-available"
111
149
  }, "Oops, looks like there are no prices available for this section."));
112
- })), /*#__PURE__*/_react.default.createElement("div", {
150
+ }) : null), /*#__PURE__*/_react.default.createElement("div", {
113
151
  className: "buttons"
114
152
  }, /*#__PURE__*/_react.default.createElement("button", {
115
153
  className: "cancel",
116
- onClick: cancelPriceSelect
154
+ onClick: cancel
117
155
  }, "Cancel"), /*#__PURE__*/_react.default.createElement("button", {
118
156
  className: "add-cart",
119
157
  onClick: () => {
120
- batchAddTicketsToCart(Object.values(seatsToBook).filter(v => !!v.priceage).flatMap(s => s.seats.map(seat => ({
158
+ singleSeats ? batchAddTicketsToCart(singleSeatsToBook) : batchAddTicketsToCart(Object.values(seatGroupsToBook).filter(v => !!v.priceage).flatMap(s => s.seats.map(seat => ({
121
159
  seat,
122
160
  priceage: s.priceage
123
161
  }))));
124
- cancelPriceSelect();
162
+ cancel();
125
163
  },
126
- disabled: Object.values(seatsToBook).every(v => !v.priceage)
127
- }, "Add to cart"))));
164
+ disabled: singleSeats ? singleSeatsToBook.every(v => !v.priceage) : Object.values(seatGroupsToBook).every(v => !v.priceage)
165
+ }, "Add to cart")))));
128
166
  }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = RemoveMultipleSeatsPopup;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _encodedSvgs = require("./assets/encodedSvgs");
9
+ var _TicketIcon = _interopRequireDefault(require("./icons/TicketIcon"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ function RemoveMultipleSeatsPopup(_ref) {
12
+ let {
13
+ onConfirm,
14
+ onClose
15
+ } = _ref;
16
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
17
+ className: "pricing-popup-backdrop",
18
+ onClick: onClose
19
+ }), /*#__PURE__*/_react.default.createElement("div", {
20
+ className: "pricing-popup remove-multiple-seats-popup",
21
+ role: "dialog",
22
+ "aria-modal": "true"
23
+ }, /*#__PURE__*/_react.default.createElement("div", {
24
+ className: "popup-header"
25
+ }, /*#__PURE__*/_react.default.createElement(_TicketIcon.default, {
26
+ className: "ticket-icon",
27
+ height: "86px",
28
+ width: "86px"
29
+ }), /*#__PURE__*/_react.default.createElement("button", {
30
+ className: "close-button",
31
+ "aria-label": "close popup",
32
+ onClick: onClose
33
+ }, /*#__PURE__*/_react.default.createElement("img", {
34
+ src: _encodedSvgs.closeIconWhite,
35
+ alt: "close",
36
+ height: "20px",
37
+ width: "20px"
38
+ })), /*#__PURE__*/_react.default.createElement("h3", null, "Remove from cart")), /*#__PURE__*/_react.default.createElement("div", {
39
+ className: "pricing-popup-content"
40
+ }, /*#__PURE__*/_react.default.createElement("h4", {
41
+ className: "quantity-heading"
42
+ }, "This will remove all adjacent seats from your cart. Are you sure you want to proceed?"), /*#__PURE__*/_react.default.createElement("div", {
43
+ className: "buttons"
44
+ }, /*#__PURE__*/_react.default.createElement("button", {
45
+ className: "cancel",
46
+ onClick: onClose
47
+ }, "Cancel"), /*#__PURE__*/_react.default.createElement("button", {
48
+ className: "add-cart",
49
+ onClick: onConfirm
50
+ }, "Confirm")))));
51
+ }
@@ -13,6 +13,8 @@ var _reactLeaflet = require("react-leaflet");
13
13
  var _utils = require("../utils");
14
14
  var _reactDom = require("react-dom");
15
15
  var _PricingPopup = _interopRequireDefault(require("./PricingPopup"));
16
+ var _SelectQuantityPopup = _interopRequireDefault(require("./SelectQuantityPopup"));
17
+ var _RemoveMultipleSeatsPopup = _interopRequireDefault(require("./RemoveMultipleSeatsPopup"));
16
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
19
  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); }
18
20
  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; }
@@ -39,15 +41,7 @@ const SeatingPlan = _ref => {
39
41
  connectedShowings,
40
42
  areaName,
41
43
  promoCode,
42
- bookingMode = _utils.bookingModes.SHOPSITE,
43
- theme = {
44
- accent: "#6366f1",
45
- accentDark: "#3730a3",
46
- accentLight: "#e0e7ff",
47
- flexiAccent: "#e32664",
48
- flexiAccentDark: "#ffd3e2",
49
- flexiAccentLight: "#be003f"
50
- }
44
+ bookingMode = _utils.bookingModes.SHOPSITE
51
45
  } = _ref;
52
46
  const [initialiseMessage, setInitialiseMessage] = (0, _react.useState)("Initialising seating plan...");
53
47
  const [isReloading, setIsReloading] = (0, _react.useState)(false);
@@ -65,7 +59,11 @@ const SeatingPlan = _ref => {
65
59
  const [mounted, setMounted] = _react.default.useState(false);
66
60
  const [mode, setMode] = (0, _react.useState)(_utils.modes.SINGLE);
67
61
  const [pricingPopupOpen, setPricingPopupOpen] = (0, _react.useState)(false);
62
+ const [selectQuantityPopupOpen, setSelectQuantityPopupOpen] = (0, _react.useState)(false);
63
+ const [desiredSeatQuantity, setDesiredSeatQuantity] = (0, _react.useState)(2);
68
64
  const [selectedSeats, setSelectedSeats] = (0, _react.useState)([]);
65
+ const [seatsToRemove, setSeatsToRemove] = (0, _react.useState)([]);
66
+ const [removeMultipleSeatsPopupOpen, setRemoveMultipleSeatsPopupOpen] = (0, _react.useState)(false);
69
67
  const mapRef = (0, _react.useRef)(null);
70
68
  const canMultiSelect = bookingMode === _utils.bookingModes.POS;
71
69
  const apiUrl = "".concat(baseUrl, "/legacy/").concat(countryCode, "/shop/events/").concat(eventId, "/").concat(eventVenueId, "/showings/").concat(showingId, "/tickets/allocated/").concat(areaId);
@@ -277,7 +275,7 @@ const SeatingPlan = _ref => {
277
275
  });
278
276
  };
279
277
  const batchAddTicketsToCart = async seatsToBook => {
280
- if (!canMultiSelect || seatsToBook.length === 0) {
278
+ if (!canMultiSelect && !seats.preventOrphanedSeats || seatsToBook.length === 0) {
281
279
  return;
282
280
  }
283
281
  const updatedSeats = _objectSpread({}, seats);
@@ -288,33 +286,102 @@ const SeatingPlan = _ref => {
288
286
  }
289
287
  });
290
288
  setSeats(updatedSeats);
291
- await new Promise(resolve => setTimeout(resolve, 1000));
292
- setBookedSeats(prev => [...prev, ...seatsToBook.map(_ref2 => {
293
- let {
294
- seat,
295
- priceage
296
- } = _ref2;
297
- return {
298
- ssId: seat.ssId,
299
- r: seat.r,
300
- c: seat.c,
301
- showingId: showingId,
302
- pId: priceage.paId,
303
- p: priceage.p,
304
- paName: priceage.paName
289
+ const succeeded = [];
290
+ try {
291
+ for (let seat of seatsToBook) {
292
+ try {
293
+ await fetch(apiUrl, {
294
+ method: "POST",
295
+ body: JSON.stringify({
296
+ priceAgeId: seat.priceage.paId,
297
+ seatId: seat.seat.ssId,
298
+ price: seat.priceage.p,
299
+ connectedShowings: connectedShowings
300
+ }),
301
+ headers: {
302
+ "content-type": "application/json",
303
+ "basket-key": sessionId
304
+ }
305
+ });
306
+ succeeded.push(seat);
307
+ } catch (error) {
308
+ console.error("Failed to book seat ".concat(seat, ":"), error);
309
+ throw new Error("Booking failed for seat ".concat(seat));
310
+ }
311
+ }
312
+ setBookedSeats(prev => [...prev, ...seatsToBook.map(_ref2 => {
313
+ let {
314
+ seat,
315
+ priceage
316
+ } = _ref2;
317
+ return {
318
+ ssId: seat.ssId,
319
+ r: seat.r,
320
+ c: seat.c,
321
+ showingId: showingId,
322
+ pId: priceage.paId,
323
+ p: priceage.p,
324
+ paName: priceage.paName
325
+ };
326
+ })]);
327
+ updatedSeats.seats.forEach(s => {
328
+ if (seatIds.includes(s.ssId)) {
329
+ s.s = _utils.statuses.USER_PENDING;
330
+ s.bookedPrice = price;
331
+ s.loading = false;
332
+ }
333
+ });
334
+ setSeats(updatedSeats);
335
+ const event = {
336
+ type: "cart-change-add",
337
+ details: [...bookedSeats, ...seatsToBook.map(_ref3 => {
338
+ let {
339
+ seat,
340
+ priceage
341
+ } = _ref3;
342
+ return {
343
+ ssId: seat.ssId,
344
+ r: seat.r,
345
+ c: seat.c,
346
+ showingId: showingId,
347
+ pId: priceage.paId,
348
+ p: priceage.p,
349
+ paName: priceage.paName
350
+ };
351
+ })]
305
352
  };
306
- })]);
307
- updatedSeats.seats.forEach(s => {
308
- if (seatIds.includes(s.ssId)) {
309
- s.s = _utils.statuses.USER_PENDING;
310
- s.bookedPrice = price;
311
- s.loading = false;
353
+ callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
354
+ } catch (error) {
355
+ console.error("Failed to book seats:", error);
356
+ for (let seat of succeeded) {
357
+ await fetch("".concat(apiUrl, "/seat/").concat(seat.ssId), {
358
+ method: "DELETE",
359
+ headers: {
360
+ "basket-key": sessionId
361
+ }
362
+ });
312
363
  }
313
- });
314
- setSeats(updatedSeats);
364
+ updatedSeats.seats.forEach(s => {
365
+ if (seatIds.includes(s.ssId)) {
366
+ s.loading = false;
367
+ }
368
+ });
369
+ setSeats(updatedSeats);
370
+ const event = {
371
+ type: "error",
372
+ details: {
373
+ error: {
374
+ code: 500,
375
+ message: "Oops! Something went wrong. Please try again."
376
+ }
377
+ }
378
+ };
379
+ callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
380
+ }
381
+ _initialFetch(true);
315
382
  };
316
383
  const batchRemoveTicketsFromCart = async seatsToRemove => {
317
- if (!canMultiSelect || seatsToRemove.length === 0) {
384
+ if (!canMultiSelect && !seats.preventOrphanedSeats || seatsToRemove.length === 0) {
318
385
  return;
319
386
  }
320
387
  const updatedSeats = _objectSpread({}, seats);
@@ -325,16 +392,53 @@ const SeatingPlan = _ref => {
325
392
  }
326
393
  });
327
394
  setSeats(updatedSeats);
328
- await new Promise(resolve => setTimeout(resolve, 1000));
329
- setBookedSeats(prev => [...prev.filter(v => !seatIds.includes(v.ssId))]);
395
+ const succeededIds = [];
396
+ try {
397
+ for (let seat of seatsToRemove) {
398
+ try {
399
+ await fetch("".concat(apiUrl, "/seat/").concat(seat.ssId), {
400
+ method: "DELETE",
401
+ headers: {
402
+ "basket-key": sessionId
403
+ }
404
+ });
405
+ succeededIds.push(seat.ssId);
406
+ } catch (error) {
407
+ console.error("Failed to remove seat ".concat(seat, ":"), error);
408
+ }
409
+ }
410
+ } catch (_unused) {
411
+ const event = {
412
+ type: "error",
413
+ details: {
414
+ error: {
415
+ code: 500,
416
+ message: "Oops! Something went wrong. Please try again."
417
+ }
418
+ }
419
+ };
420
+ callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
421
+ }
422
+ setBookedSeats(prev => [...prev.filter(v => !succeededIds.includes(v.ssId))]);
330
423
  updatedSeats.seats.forEach(s => {
331
424
  if (seatIds.includes(s.ssId)) {
332
425
  s.loading = false;
333
- s.s = _utils.statuses.UNSOLD;
334
- s.bookedPrice = null;
426
+ if (succeededIds.includes(s.ssId)) {
427
+ s.s = _utils.statuses.UNSOLD;
428
+ s.bookedPrice = null;
429
+ }
335
430
  }
336
431
  });
337
432
  setSeats(updatedSeats);
433
+ setSeatsToRemove([]);
434
+ if (succeededIds.length > 0) {
435
+ const event = {
436
+ type: "cart-change-remove",
437
+ details: bookedSeats.filter(bs => succeededIds.includes(bs.ssId))
438
+ };
439
+ callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
440
+ }
441
+ _initialFetch(true);
338
442
  };
339
443
  const handleClickSeat = (e, s) => {
340
444
  setChosenSeat({
@@ -372,8 +476,9 @@ const SeatingPlan = _ref => {
372
476
  setIsReloading(true);
373
477
  }
374
478
  setInitialiseMessage("Initialising seating plan...");
375
- fetch(// `http://localhost:3155/api/legacy/shop/events/${eventId}/${eventVenueId}/showings/${showingId}/tickets/allocated/${areaId}`,
376
- "".concat(apiUrl).concat(promoCode ? "?promo=".concat(promoCode) : ""), {
479
+ fetch("http://localhost:3155/api/legacy/shop/events/".concat(eventId, "/").concat(eventVenueId, "/showings/").concat(showingId, "/tickets/allocated/").concat(areaId),
480
+ // `${apiUrl}${promoCode ? `?promo=${promoCode}` : ""}`,
481
+ {
377
482
  headers: {
378
483
  "basket-key": sessionId,
379
484
  Authorization: "Bearer ".concat(apiKey)
@@ -414,6 +519,9 @@ const SeatingPlan = _ref => {
414
519
  setHeight(img.height * 0.5);
415
520
  setWidth(img.width * 0.5);
416
521
  setSeats(data);
522
+ if (data.preventOrphanedSeats && !isReload) {
523
+ setSelectQuantityPopupOpen(true);
524
+ }
417
525
  };
418
526
  setIsReloading(false);
419
527
  }).catch(error => {
@@ -451,6 +559,14 @@ const SeatingPlan = _ref => {
451
559
  // in full screen mode, render the map in the body, otherwise render in the seating-plan-root div
452
560
  const mapContainer = mounted && (isFullScreen ? (_document = document) === null || _document === void 0 ? void 0 : _document.body : (_document2 = document) === null || _document2 === void 0 ? void 0 : _document2.getElementById("seating-plan-root"));
453
561
  const backdropContainer = mounted && ((_document3 = document) === null || _document3 === void 0 ? void 0 : _document3.body);
562
+ const selectedSeatsWithPricing = selectedSeats.map(s => {
563
+ const priceages = seats.pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && price.psId === s.psId);
564
+ const availablePriceages = priceages.filter(p => p.is_available !== false);
565
+ return {
566
+ seat: s,
567
+ priceage: availablePriceages.length > 0 ? availablePriceages[0] : null
568
+ };
569
+ });
454
570
  const groupedSelectedSeats = selectedSeats.reduce((acc, curr) => {
455
571
  if (curr.psId) {
456
572
  const priceages = seats.pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && price.psId === curr.psId);
@@ -469,36 +585,40 @@ const SeatingPlan = _ref => {
469
585
  setPricingPopupOpen(false);
470
586
  setSelectedSeats([]);
471
587
  };
472
- const themeStyles = {
473
- "--accent": theme.accent,
474
- "--accent-dark": theme.accentDark,
475
- "--accent-light": theme.accentLight,
476
- "--flexi-accent": theme.flexiAccent,
477
- "--flexi-accent-light": theme.flexiAccentLight,
478
- "--flexi-accent-dark": theme.flexiAccentDark
479
- };
480
588
 
481
589
  // return seating plan
482
590
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
483
591
  className: "seating-plan-root",
484
- id: "seating-plan-root",
485
- style: themeStyles
592
+ id: "seating-plan-root"
486
593
  }, error ? /*#__PURE__*/_react.default.createElement("div", {
487
594
  className: "loading"
488
595
  }, /*#__PURE__*/_react.default.createElement("h1", null, "OOPS!"), /*#__PURE__*/_react.default.createElement("div", null, error.response.data.message)) : position && area === areaId ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, backdropContainer && /*#__PURE__*/(0, _reactDom.createPortal)(/*#__PURE__*/_react.default.createElement("div", {
489
596
  className: "seating-plan-backdrop ".concat(isFullScreen ? "full-screen" : ""),
490
- onClick: () => setIsFullScreen(false),
491
- style: themeStyles
597
+ onClick: () => setIsFullScreen(false)
492
598
  }), backdropContainer), mapContainer && /*#__PURE__*/(0, _reactDom.createPortal)(/*#__PURE__*/_react.default.createElement("div", {
493
599
  className: "seating-plan-container ".concat(isFullScreen ? "full-screen" : ""),
494
- "data-mode": mode,
495
- style: themeStyles
496
- }, pricingPopupOpen && canMultiSelect && /*#__PURE__*/_react.default.createElement(_PricingPopup.default, {
497
- cancelPriceSelect: cancelPriceSelect,
600
+ "data-mode": mode
601
+ }, pricingPopupOpen && (canMultiSelect || seats.preventOrphanedSeats) ? /*#__PURE__*/_react.default.createElement(_PricingPopup.default, {
602
+ cancel: cancelPriceSelect,
498
603
  groupedSelectedSeats: groupedSelectedSeats,
604
+ selectedSeatsWithPricing: selectedSeatsWithPricing,
499
605
  priceSectionIds: priceSectionIds,
500
606
  pricing: seats.pricing,
501
- batchAddTicketsToCart: batchAddTicketsToCart
607
+ batchAddTicketsToCart: batchAddTicketsToCart,
608
+ singleSeats: seats.preventOrphanedSeats
609
+ }) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null), selectQuantityPopupOpen && /*#__PURE__*/_react.default.createElement(_SelectQuantityPopup.default, {
610
+ quantity: desiredSeatQuantity,
611
+ setQuantity: v => {
612
+ setDesiredSeatQuantity(v);
613
+ setSelectedSeats([]);
614
+ },
615
+ onClose: () => setSelectQuantityPopupOpen(false)
616
+ }), removeMultipleSeatsPopupOpen && /*#__PURE__*/_react.default.createElement(_RemoveMultipleSeatsPopup.default, {
617
+ onConfirm: () => {
618
+ batchRemoveTicketsFromCart(seatsToRemove);
619
+ setRemoveMultipleSeatsPopupOpen(false);
620
+ },
621
+ onClose: () => setRemoveMultipleSeatsPopupOpen(false)
502
622
  }), /*#__PURE__*/_react.default.createElement(_reactLeaflet.MapContainer, {
503
623
  zoomSnap: 0,
504
624
  zoomDelta: 1,
@@ -536,7 +656,12 @@ const SeatingPlan = _ref => {
536
656
  pricingPopupOpen: pricingPopupOpen,
537
657
  setPricingPopupOpen: setPricingPopupOpen,
538
658
  selectedSeats: selectedSeats,
539
- setSelectedSeats: setSelectedSeats
659
+ setSelectedSeats: setSelectedSeats,
660
+ selectQuantityPopupOpen: selectQuantityPopupOpen,
661
+ setSelectQuantityPopupOpen: setSelectQuantityPopupOpen,
662
+ desiredSeatQuantity: desiredSeatQuantity,
663
+ setSeatsToRemove: setSeatsToRemove,
664
+ setRemoveMultipleSeatsPopupOpen: setRemoveMultipleSeatsPopupOpen
540
665
  }))), mapContainer)) : /*#__PURE__*/_react.default.createElement("div", {
541
666
  className: "loading"
542
667
  }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("svg", {
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = SelectQuantityPopup;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _encodedSvgs = require("./assets/encodedSvgs");
9
+ var _TicketIcon = _interopRequireDefault(require("./icons/TicketIcon"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ 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); }
12
+ 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; }
13
+ const PriceSelect = _ref => {
14
+ let {
15
+ newQuantity,
16
+ setNewQuantity
17
+ } = _ref;
18
+ return /*#__PURE__*/_react.default.createElement("div", {
19
+ className: "price-select"
20
+ }, /*#__PURE__*/_react.default.createElement("select", {
21
+ onChange: e => {
22
+ setNewQuantity(parseInt(e.target.value));
23
+ },
24
+ value: newQuantity
25
+ }, Array.from({
26
+ length: 10
27
+ }, (_, i) => /*#__PURE__*/_react.default.createElement("option", {
28
+ key: i,
29
+ value: i + 1
30
+ }, i + 1))));
31
+ };
32
+ function SelectQuantityPopup(_ref2) {
33
+ let {
34
+ quantity,
35
+ setQuantity,
36
+ onClose
37
+ } = _ref2;
38
+ const [newQuantity, setNewQuantity] = (0, _react.useState)(quantity);
39
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
40
+ className: "pricing-popup-backdrop",
41
+ onClick: onClose
42
+ }), /*#__PURE__*/_react.default.createElement("div", {
43
+ className: "pricing-popup",
44
+ role: "dialog",
45
+ "aria-modal": "true"
46
+ }, /*#__PURE__*/_react.default.createElement("div", {
47
+ className: "popup-header"
48
+ }, /*#__PURE__*/_react.default.createElement(_TicketIcon.default, {
49
+ className: "ticket-icon",
50
+ height: "86px",
51
+ width: "86px"
52
+ }), /*#__PURE__*/_react.default.createElement("button", {
53
+ className: "close-button",
54
+ "aria-label": "close popup",
55
+ onClick: onClose
56
+ }, /*#__PURE__*/_react.default.createElement("img", {
57
+ src: _encodedSvgs.closeIconWhite,
58
+ alt: "close",
59
+ height: "20px",
60
+ width: "20px"
61
+ })), /*#__PURE__*/_react.default.createElement("h3", null, "Choose seats")), /*#__PURE__*/_react.default.createElement("div", {
62
+ className: "pricing-popup-content"
63
+ }, /*#__PURE__*/_react.default.createElement("h4", {
64
+ className: "quantity-heading"
65
+ }, "How many seats would you like to book?"), /*#__PURE__*/_react.default.createElement("div", {
66
+ className: "seat-list"
67
+ }, /*#__PURE__*/_react.default.createElement(PriceSelect, {
68
+ setNewQuantity: setNewQuantity,
69
+ newQuantity: newQuantity
70
+ })), /*#__PURE__*/_react.default.createElement("div", {
71
+ className: "buttons"
72
+ }, /*#__PURE__*/_react.default.createElement("button", {
73
+ className: "cancel",
74
+ onClick: onClose
75
+ }, "Cancel"), /*#__PURE__*/_react.default.createElement("button", {
76
+ className: "add-cart",
77
+ onClick: () => {
78
+ setQuantity(newQuantity);
79
+ onClose();
80
+ }
81
+ }, "Confirm")))));
82
+ }
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.wheelchairIcon = exports.userIcon = exports.handIcon = exports.flexiIcon = exports.expandIcon = exports.editIcon = exports.cursorIcon = exports.collapseIcon = exports.closeIcon = void 0;
6
+ exports.wheelchairIcon = exports.userIcon = exports.handIcon = exports.flexiIcon = exports.expandIcon = exports.editIcon = exports.cursorIcon = exports.collapseIcon = exports.closeIconWhite = exports.closeIcon = void 0;
7
7
  const expandIcon = exports.expandIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIyNCIgd2lkdGg9IjI0IiBmaWxsPSJjdXJyZW50Q29sb3IiIHN0cm9rZT0iY3VycmVudENvbG9yIj4KIDxwYXRoIGQ9Ik03IDE0SDV2NWg1di0ySDd6bS0yLTRoMlY3aDNWNUg1em0xMiA3aC0zdjJoNXYtNWgtMnpNMTQgNXYyaDN2M2gyVjV6Ij48L3BhdGg+Cjwvc3ZnPgo=";
8
8
  const collapseIcon = exports.collapseIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIyNCIgd2lkdGg9IjI0IiBmaWxsPSJjdXJyZW50Q29sb3IiIHN0cm9rZT0iY3VycmVudENvbG9yIj4KPHBhdGggZD0iTTUgMTZoM3YzaDJ2LTVINXptMy04SDV2Mmg1VjVIOHptNiAxMWgydi0zaDN2LTJoLTV6bTItMTFWNWgtMnY1aDVWOHoiPjwvcGF0aD4KPC9zdmc+Cg==";
9
9
  const closeIcon = exports.closeIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxsaW5lIHgxPSIxOCIgeTE9IjYiIHgyPSI2IiB5Mj0iMTgiLz48bGluZSB4MT0iNiIgeTE9IjYiIHgyPSIxOCIgeTI9IjE4Ii8+PC9zdmc+";
@@ -12,4 +12,5 @@ const wheelchairIcon = exports.wheelchairIcon = "data:image/svg+xml;base64,PD94b
12
12
  const handIcon = exports.handIcon = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48cGF0aCBmaWxsPSJjdXJyZW50Q29sb3IiIGQ9Ik00NDggMjQwdjk2YzAgMy4xLS40IDYuMi0xLjEgOS4ybC0zMiAxMzZDNDEwLjcgNDk5LjIgMzk0LjYgNTEyIDM3NiA1MTJIMTY4YTQwIDQwIDAgMCAxIC0zMi40LTE2LjVsLTEyOC0xNzZjLTEzLTE3LjktOS00Mi45IDguOC01NS45IDE3LjktMTMgNDIuOS05IDU1LjkgOC44TDEwNCAzMTZWNDBjMC0yMi4xIDE3LjktNDAgNDAtNDBzNDAgMTcuOSA0MCA0MHYyMDBoOHYtNDBjMC0yMi4xIDE3LjktNDAgNDAtNDBzNDAgMTcuOSA0MCA0MHY0MGg4di0yNGMwLTIyLjEgMTcuOS00MCA0MC00MHM0MCAxNy45IDQwIDQwdjI0aDhjMC0yMi4xIDE3LjktNDAgNDAtNDBzNDAgMTcuOSA0MCA0MHptLTI1NiA4MGgtOHY5Nmg4di05NnptODggMGgtOHY5Nmg4di05NnptODggMGgtOHY5Nmg4di05NnoiLz48L3N2Zz4=";
13
13
  const cursorIcon = exports.cursorIcon = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDMyMCA1MTIiPjwhLS0hRm9udCBBd2Vzb21lIEZyZWUgNi43LjEgYnkgQGZvbnRhd2Vzb21lIC0gaHR0cHM6Ly9mb250YXdlc29tZS5jb20gTGljZW5zZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tL2xpY2Vuc2UvZnJlZSBDb3B5cmlnaHQgMjAyNCBGb250aWNvbnMsIEluYy4tLT48cGF0aCBkPSJNMCA1NS4yTDAgNDI2YzAgMTIuMiA5LjkgMjIgMjIgMjJjNi4zIDAgMTIuNC0yLjcgMTYuNi03LjVMMTIxLjIgMzQ2bDU4LjEgMTE2LjNjNy45IDE1LjggMjcuMSAyMi4yIDQyLjkgMTQuM3MyMi4yLTI3LjEgMTQuMy00Mi45TDE3OS44IDMyMGwxMTguMSAwYzEyLjIgMCAyMi4xLTkuOSAyMi4xLTIyLjFjMC02LjMtMi43LTEyLjMtNy40LTE2LjVMMzguNiAzNy45QzM0LjMgMzQuMSAyOC45IDMyIDIzLjIgMzJDMTAuNCAzMiAwIDQyLjQgMCA1NS4yeiIvPjwvc3ZnPg==";
14
14
  const flexiIcon = exports.flexiIcon = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDI0IDI0IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIGNsYXNzPSJzaXplLTYiPgogIDxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTIuMjUgMTggOSAxMS4yNWw0LjMwNiA0LjMwNmExMS45NSAxMS45NSAwIDAgMSA1LjgxNC01LjUxOGwyLjc0LTEuMjJtMCAwLTUuOTQtMi4yODFtNS45NCAyLjI4LTIuMjggNS45NDEiIC8+Cjwvc3ZnPg==";
15
- const editIcon = exports.editIcon = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDI0IDI0IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIGNsYXNzPSJzaXplLTYiPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0ibTE2Ljg2MiA0LjQ4NyAxLjY4Ny0xLjY4OGExLjg3NSAxLjg3NSAwIDEgMSAyLjY1MiAyLjY1MkwxMC41ODIgMTYuMDdhNC41IDQuNSAwIDAgMS0xLjg5NyAxLjEzTDYgMThsLjgtMi42ODVhNC41IDQuNSAwIDAgMSAxLjEzLTEuODk3bDguOTMyLTguOTMxWm0wIDBMMTkuNSA3LjEyNU0xOCAxNHY0Ljc1QTIuMjUgMi4yNSAwIDAgMSAxNS43NSAyMUg1LjI1QTIuMjUgMi4yNSAwIDAgMSAzIDE4Ljc1VjguMjVBMi4yNSAyLjI1IDAgMCAxIDUuMjUgNkgxMCIgLz48L3N2Zz4=";
15
+ const editIcon = exports.editIcon = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDI0IDI0IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIGNsYXNzPSJzaXplLTYiPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0ibTE2Ljg2MiA0LjQ4NyAxLjY4Ny0xLjY4OGExLjg3NSAxLjg3NSAwIDEgMSAyLjY1MiAyLjY1MkwxMC41ODIgMTYuMDdhNC41IDQuNSAwIDAgMS0xLjg5NyAxLjEzTDYgMThsLjgtMi42ODVhNC41IDQuNSAwIDAgMSAxLjEzLTEuODk3bDguOTMyLTguOTMxWm0wIDBMMTkuNSA3LjEyNU0xOCAxNHY0Ljc1QTIuMjUgMi4yNSAwIDAgMSAxNS43NSAyMUg1LjI1QTIuMjUgMi4yNSAwIDAgMSAzIDE4Ljc1VjguMjVBMi4yNSAyLjI1IDAgMCAxIDUuMjUgNkgxMCIgLz48L3N2Zz4=";
16
+ const closeIconWhite = exports.closeIconWhite = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48bGluZSB4MT0iMTgiIHkxPSI2IiB4Mj0iNiIgeTI9IjE4Ii8+PGxpbmUgeDE9IjYiIHkxPSI2IiB4Mj0iMTgiIHkyPSIxOCIvPjwvc3ZnPg==";
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = EditIcon;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ function EditIcon(_ref) {
10
+ let {
11
+ height = "18px",
12
+ width = "18px",
13
+ color = "currentColor",
14
+ strokeWidth = "1.5",
15
+ className
16
+ } = _ref;
17
+ return /*#__PURE__*/_react.default.createElement("svg", {
18
+ width: width,
19
+ height: height,
20
+ xmlns: "http://www.w3.org/2000/svg",
21
+ fill: "none",
22
+ viewBox: "0 0 24 24",
23
+ strokeWidth: strokeWidth,
24
+ stroke: color,
25
+ className: className
26
+ }, /*#__PURE__*/_react.default.createElement("path", {
27
+ strokeLinecap: "round",
28
+ strokeLinejoin: "round",
29
+ d: "m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"
30
+ }));
31
+ }
@@ -27,12 +27,12 @@ button {
27
27
  }
28
28
 
29
29
  .seating-plan-container {
30
- /* --accent: #6366f1;
31
- --accent-dark: #3730a3;
32
- --accent-light: #e0e7ff;
33
- --flexi-accent: #e32664;
34
- --flexi-accent-light: #ffd3e2;
35
- --flexi-accent-dark: #be003f; */
30
+ --accent: rgb(99 102 241);
31
+ --accent-dark: rgb(55 48 163);
32
+ --accent-light: rgb(224 231 255);
33
+ --flexi-accent: rgb(227 38 100);
34
+ --flexi-accent-light: rgb(255 211 226);
35
+ --flexi-accent-dark: rgb(190 0 63);
36
36
  font-family: inherit;
37
37
  }
38
38
 
@@ -41,7 +41,6 @@ button {
41
41
  padding: 0.5rem 0.8rem;
42
42
  border-radius: 3px;
43
43
  text-align: left;
44
- color: #333;
45
44
  }
46
45
 
47
46
  .legend-header {
@@ -677,6 +676,31 @@ svg.leaflet-image-layer.leaflet-interactive path {
677
676
  justify-content: center;
678
677
  }
679
678
 
679
+ .extra-controls.seat-quantity-control {
680
+ border: none;
681
+ transition: border-color 0.2s;
682
+ border-radius: 6px;
683
+ }
684
+
685
+ .extra-controls .leaflet-control-seat-quantity {
686
+ border: none;
687
+ background: var(--accent);
688
+ color: white;
689
+ cursor: pointer;
690
+ display: flex;
691
+ align-items: center;
692
+ font-size: 0.875rem;
693
+ gap: 0.25rem;
694
+ padding: 5px 10px;
695
+ transition: all 0.2s;
696
+ font-weight: bold;
697
+ }
698
+
699
+ .extra-controls .leaflet-control-seat-quantity:hover {
700
+ background: var(--accent-light);
701
+ color: var(--accent-dark);
702
+ }
703
+
680
704
  .leaflet-control-zoom-in.reload-seating-plan {
681
705
  border-radius: 0 0 0 0;
682
706
  border-top: 1px solid #ccc;
@@ -11,6 +11,12 @@
11
11
  animation: fade-in 400ms;
12
12
  }
13
13
 
14
+ .pricing-popup-content {
15
+ padding: 1rem;
16
+ flex: 1;
17
+ overflow-y: auto;
18
+ }
19
+
14
20
  .pricing-popup {
15
21
  position: absolute;
16
22
  z-index: 1002;
@@ -21,19 +27,39 @@
21
27
  background-color: #fff;
22
28
  /* font-family: "Helvetica Neue", Arial, Helvetica, sans-serif; */
23
29
  font-family: inherit;
24
- padding: 1rem;
25
30
  color: #333;
26
31
  box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
27
32
  border-radius: 12px;
28
33
  min-width: 20rem;
34
+ max-height: 95%;
35
+ display: flex;
36
+ flex-direction: column;
37
+ }
38
+
39
+ @media screen and (max-width: 600px) {
40
+ .pricing-popup {
41
+ width: 100%;
42
+ min-width: unset;
43
+ }
44
+ }
45
+
46
+ .pricing-popup.remove-multiple-seats-popup {
47
+ min-width: unset;
48
+ max-width: 28rem;
29
49
  }
30
50
 
31
51
  .pricing-popup .popup-header {
32
52
  margin-top: 0;
53
+ padding: 1rem;
54
+ border-radius: 12px 12px 0px 0px;
55
+ flex-direction: column;
56
+ text-align: left;
57
+ gap: 0.5rem;
33
58
  }
34
59
 
35
60
  .pricing-popup .popup-header .close-button {
36
61
  margin: -2px -2px 0px 0px;
62
+ align-self: flex-end;
37
63
  }
38
64
 
39
65
  .pricing-popup h3,
@@ -42,6 +68,13 @@
42
68
  margin: 0;
43
69
  }
44
70
 
71
+ .pricing-popup .quantity-heading {
72
+ font-weight: normal;
73
+ text-align: left;
74
+ font-size: 0.875rem;
75
+ margin-bottom: 8px;
76
+ }
77
+
45
78
  .pricing-popup p {
46
79
  margin: 0;
47
80
  max-width: 30rem;
@@ -56,7 +89,6 @@
56
89
  display: flex;
57
90
  flex-direction: column;
58
91
  gap: 1rem;
59
- margin-top: 1rem;
60
92
  }
61
93
 
62
94
  .pricing-popup .seat-group {
@@ -76,6 +108,8 @@
76
108
  .pricing-popup select {
77
109
  flex: 1;
78
110
  padding: 0.3rem 0.2rem;
111
+ border: 1px solid #ccc;
112
+ border-radius: 0.25rem;
79
113
  }
80
114
 
81
115
  .pricing-popup .buttons {
@@ -98,6 +132,24 @@
98
132
  margin-bottom: 0;
99
133
  }
100
134
 
135
+ .pricing-popup .buttons button.add-cart {
136
+ background: var(--accent);
137
+ color: white;
138
+ font-weight: bold;
139
+ border: none;
140
+ }
141
+
142
+ .pricing-popup .buttons button.add-cart:hover:not(:disabled) {
143
+ background: var(--accent-light);
144
+ color: var(--accent-dark);
145
+ }
146
+
147
+ @media screen and (max-width: 600px) {
148
+ .pricing-popup .buttons button {
149
+ min-width: 8rem;
150
+ }
151
+ }
152
+
101
153
  .pricing-popup .buttons button:disabled {
102
154
  cursor: default;
103
155
  color: #bdc3c7;
@@ -115,7 +167,7 @@
115
167
  }
116
168
 
117
169
  .pricing-popup button.cancel {
118
- background: #ecf0f1;
170
+ background: #dcdcdc;
119
171
  border: none;
120
172
  }
121
173
 
@@ -12,7 +12,6 @@ const statusColors = exports.statusColors = {
12
12
  pending: "#e74c3c",
13
13
  booked: "#e74c3c",
14
14
  bookedWithDifferentPrice: "#fab1a0",
15
- // TODO temporary selected state
16
15
  selected: "#049CDB"
17
16
  };
18
17
  const statuses = exports.statuses = {
@@ -3,20 +3,26 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getInitialColor = exports.calculateCenterOfMap = exports.NZDollar = void 0;
6
+ exports.getValidSeats = exports.getRowSection = exports.getInitialColor = exports.getAdjacentBookedSeats = exports.createsOrphan = exports.canSelectSingleSeatGivenOrphanRules = exports.calculateCenterOfMap = exports.NZDollar = void 0;
7
7
  var _enums = require("./enums");
8
- const getInitialColor = (s, price, selected) => {
9
- // TEST selected state for multiselect
10
- // if (selected) {
11
- // return {
12
- // fillColor: statusColors.selected,
13
- // color: "none",
14
- // fillOpacity: s.loading ? 0 : 1,
15
- // };
16
- // }
17
-
8
+ const getInitialColor = (s, price, disabled, selected, greyedOut) => {
9
+ // selected state for multiselect
10
+ if (selected) {
11
+ return {
12
+ fillColor: _enums.statusColors.selected,
13
+ color: "none",
14
+ fillOpacity: s.loading ? 0 : 1
15
+ };
16
+ }
17
+ if (greyedOut) {
18
+ return {
19
+ fillColor: _enums.statusColors.unknown,
20
+ color: "none",
21
+ fillOpacity: s.loading ? 0 : 1
22
+ };
23
+ }
18
24
  return {
19
- fillColor: s.s === _enums.statuses.UNSOLD ? _enums.statusColors.available : s.s === _enums.statuses.USER_PENDING ? s.bookedPrice === price ? _enums.statusColors.booked : _enums.statusColors.bookedWithDifferentPrice : _enums.statusColors.sold,
25
+ fillColor: s.s === _enums.statuses.UNSOLD && !disabled ? _enums.statusColors.available : s.s === _enums.statuses.USER_PENDING ? s.bookedPrice === price ? _enums.statusColors.booked : _enums.statusColors.bookedWithDifferentPrice : _enums.statusColors.sold,
20
26
  color: "none",
21
27
  fillOpacity: s.loading ? 0 : 1,
22
28
  stroke: false
@@ -37,4 +43,121 @@ exports.calculateCenterOfMap = calculateCenterOfMap;
37
43
  const NZDollar = exports.NZDollar = new Intl.NumberFormat("en-NZ", {
38
44
  style: "currency",
39
45
  currency: "NZD"
40
- });
46
+ });
47
+ const createsOrphan = (seat, seats, isRemove, selectedSeats) => {
48
+ const selectedIds = selectedSeats ? selectedSeats.map(s => s.sId) : null;
49
+ const filteredSeats = selectedIds ? seats.filter(s => !selectedIds.includes(s.sId)) : seats;
50
+ const sa = filteredSeats.find(s => s.sId === seat.sa);
51
+ const saa = filteredSeats.find(s => s.sId === (sa === null || sa === void 0 ? void 0 : sa.sa));
52
+ const sb = filteredSeats.find(s => s.sId === seat.sb);
53
+ const sbb = filteredSeats.find(s => s.sId === (sb === null || sb === void 0 ? void 0 : sb.sb));
54
+ if (isRemove) {
55
+ if (sa && sb && sa.s !== _enums.statuses.UNSOLD && sb.s === _enums.statuses.USER_PENDING || sa && sb && sa.s === _enums.statuses.USER_PENDING && sb.s !== _enums.statuses.UNSOLD || sa && !sb && sa.s === _enums.statuses.USER_PENDING || sb && !sa && sb.s === _enums.statuses.USER_PENDING) {
56
+ return true;
57
+ }
58
+ return false;
59
+ }
60
+ if (sb && sbb && sb.s === _enums.statuses.UNSOLD && sbb.s !== _enums.statuses.UNSOLD || sa && saa && sa.s === _enums.statuses.UNSOLD && saa.s !== _enums.statuses.UNSOLD || sb && !sbb && sb.s === _enums.statuses.UNSOLD || sa && !saa && sa.s === _enums.statuses.UNSOLD) {
61
+ return true;
62
+ }
63
+ return false;
64
+ };
65
+ exports.createsOrphan = createsOrphan;
66
+ const getRowSection = (startSeat, seatsMap) => {
67
+ const row = [];
68
+ let seat = startSeat;
69
+ while (seat && seat.sId !== undefined) {
70
+ row.unshift(seat);
71
+ seat = seatsMap.get(seat.sb);
72
+ }
73
+ seat = seatsMap.get(startSeat.sa);
74
+ while (seat && seat.sId !== undefined) {
75
+ row.push(seat);
76
+ seat = seatsMap.get(seat.sa);
77
+ }
78
+ return row;
79
+ };
80
+ exports.getRowSection = getRowSection;
81
+ const canSelectSingleSeatGivenOrphanRules = (seat, rowSection) => {
82
+ const isRemove = seat.s === _enums.statuses.USER_PENDING;
83
+ const selectedSeatCreatesOrphan = createsOrphan(seat, rowSection, isRemove);
84
+ if (selectedSeatCreatesOrphan) {
85
+ let hasOtherOptions = false;
86
+ for (let i = 0; i < rowSection.length; i++) {
87
+ if (rowSection[i].sId !== seat.sId && rowSection[i].s === (isRemove ? _enums.statuses.USER_PENDING : _enums.statuses.UNSOLD) && !createsOrphan(rowSection[i], rowSection, isRemove)) {
88
+ hasOtherOptions = true;
89
+ break;
90
+ }
91
+ }
92
+ return hasOtherOptions ? false : true;
93
+ }
94
+ return true;
95
+ };
96
+ exports.canSelectSingleSeatGivenOrphanRules = canSelectSingleSeatGivenOrphanRules;
97
+ const getValidSeats = (s, seatsMap, desiredSeatQuantity) => {
98
+ let seatsToBook = [s];
99
+ const rowSection = getRowSection(s, seatsMap);
100
+ if (seatsToBook.length < desiredSeatQuantity) {
101
+ const traverse = (seat, direction) => {
102
+ const nextSeatId = direction === "left" ? seat.sb : seat.sa;
103
+ if (nextSeatId) {
104
+ const nextSeat = rowSection.find(v => v.sId === nextSeatId);
105
+ if (nextSeat && nextSeat.s === _enums.statuses.UNSOLD && seatsToBook.length < desiredSeatQuantity && !(seatsToBook.length === desiredSeatQuantity - 1 && createsOrphan(nextSeat, rowSection, false, seatsToBook))) {
106
+ if (direction === "left") {
107
+ seatsToBook.unshift(nextSeat);
108
+ } else {
109
+ seatsToBook.push(nextSeat);
110
+ }
111
+ if (seatsToBook.length < desiredSeatQuantity) {
112
+ traverse(nextSeat, direction);
113
+ }
114
+ }
115
+ }
116
+ };
117
+ traverse(s, "right");
118
+ if (seatsToBook.length < desiredSeatQuantity) {
119
+ traverse(s, "left");
120
+ }
121
+ const firstSeat = seatsToBook[0];
122
+ const sb = rowSection.find(v => v.sId === firstSeat.sb);
123
+ const sbb = rowSection.find(v => v.sId === (sb === null || sb === void 0 ? void 0 : sb.sb));
124
+ const orphanToLeft = sb && sbb && sb.s === _enums.statuses.UNSOLD && sbb.s !== _enums.statuses.UNSOLD || sb && !sbb && sb.s === _enums.statuses.UNSOLD;
125
+ if (seatsToBook.length < desiredSeatQuantity || orphanToLeft) {
126
+ seatsToBook = [s];
127
+ traverse(s, "left");
128
+ if (seatsToBook.length < desiredSeatQuantity) {
129
+ traverse(s, "right");
130
+ }
131
+ }
132
+ }
133
+ if (seatsToBook.length === 1 && desiredSeatQuantity === 1) {
134
+ return canSelectSingleSeatGivenOrphanRules(s, rowSection) ? seatsToBook : [];
135
+ }
136
+ if (seatsToBook.length === desiredSeatQuantity && !(seatsToBook.length === 1 && createsOrphan(s, rowSection, false, seatsToBook))) {
137
+ return seatsToBook;
138
+ }
139
+ return [];
140
+ };
141
+ exports.getValidSeats = getValidSeats;
142
+ const getAdjacentBookedSeats = (seat, seatsMap) => {
143
+ const rowSection = getRowSection(seat, seatsMap);
144
+ const adjacentBookedSeats = [seat];
145
+ const traverse = (seat, direction) => {
146
+ const nextSeatId = direction === "left" ? seat.sb : seat.sa;
147
+ if (nextSeatId) {
148
+ const nextSeat = rowSection.find(v => v.sId === nextSeatId);
149
+ if (nextSeat && nextSeat.s === _enums.statuses.USER_PENDING) {
150
+ if (direction === "left") {
151
+ adjacentBookedSeats.unshift(nextSeat);
152
+ } else {
153
+ adjacentBookedSeats.push(nextSeat);
154
+ }
155
+ traverse(nextSeat, direction);
156
+ }
157
+ }
158
+ };
159
+ traverse(seat, "right");
160
+ traverse(seat, "left");
161
+ return adjacentBookedSeats;
162
+ };
163
+ exports.getAdjacentBookedSeats = getAdjacentBookedSeats;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "iticket-seatingplan-dev",
3
3
  "description": "Seating plan with FLEXi pricing",
4
4
  "author": "gedwyne",
5
- "version": "1.6.6",
5
+ "version": "1.6.8",
6
6
  "private": false,
7
7
  "keywords": [
8
8
  "iticket",
@@ -20,9 +20,10 @@
20
20
  "@types/leaflet-draw": "^1.0.11",
21
21
  "leaflet": "^1.9.3",
22
22
  "leaflet-draw": "^1.0.4",
23
- "react": "^19.0.0",
24
- "react-dom": "^19.0.0",
25
- "react-leaflet": "^5.0.0-rc.2",
23
+ "react": "^18.3.1",
24
+ "react-dom": "^18.3.1",
25
+ "react-leaflet": "^4.2.1",
26
+ "react-leaflet-custom-control": "^1.3.5",
26
27
  "react-leaflet-draw": "^0.20.4",
27
28
  "react-scripts": "^5.0.1"
28
29
  },