iticket-seatingplan-dev 1.7.1 → 1.7.3

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.
@@ -24,6 +24,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
24
24
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
25
25
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
26
26
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
27
+ const MAX_RETRIES = 5;
27
28
  const SeatingPlan = _ref => {
28
29
  var _document, _document2, _document3;
29
30
  let {
@@ -97,7 +98,7 @@ const SeatingPlan = _ref => {
97
98
  }
98
99
  return;
99
100
  }
100
- if (priceage.is_available === false) {
101
+ if (priceage.q !== null && priceage.q <= 0) {
101
102
  const event = {
102
103
  type: "error",
103
104
  details: {
@@ -310,8 +311,8 @@ const SeatingPlan = _ref => {
310
311
  }
311
312
  succeeded.push(seat);
312
313
  } catch (error) {
313
- console.error("Failed to book seat ".concat(seat, ":"), error);
314
- throw new Error("Booking failed for seat ".concat(seat));
314
+ console.error("Failed to book seat ".concat(seat.seat.r, " ").concat(seat.seat.c, ":"), error);
315
+ throw new Error(error === "429" ? error : "Booking failed for seat ".concat(seat.seat.r, " ").concat(seat.seat.c));
315
316
  }
316
317
  }
317
318
  setBookedSeats(prev => [...prev, ...seatsToBook.map(_ref2 => {
@@ -376,14 +377,15 @@ const SeatingPlan = _ref => {
376
377
  type: "error",
377
378
  details: {
378
379
  error: {
379
- code: 500,
380
- message: "Oops! Something went wrong. Please try again."
380
+ code: error === "429" ? 429 : 500,
381
+ message: error === "429" ? "Someone else selected these first. Please try again." : "Oops! Something went wrong. Please try again."
381
382
  }
382
383
  }
383
384
  };
384
385
  callbackFunction === null || callbackFunction === void 0 || callbackFunction(event);
386
+ } finally {
387
+ _initialFetch(true);
385
388
  }
386
- _initialFetch(true);
387
389
  };
388
390
  const batchRemoveTicketsFromCart = async seatsToRemove => {
389
391
  if (!canMultiSelect && !seats.preventOrphanedSeats || seatsToRemove.length === 0) {
@@ -466,7 +468,8 @@ const SeatingPlan = _ref => {
466
468
  return;
467
469
  }
468
470
  if (s.s === _utils.statuses.UNSOLD) {
469
- const availablePrices = seats.pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && s.psId === price.psId);
471
+ var _seats$pricing;
472
+ const availablePrices = ((_seats$pricing = seats.pricing) === null || _seats$pricing === void 0 ? void 0 : _seats$pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && s.psId === price.psId)) || [];
470
473
  const isSingleFlexi = availablePrices.length === 1 && !!availablePrices[0].pMax && !!availablePrices[0].pMin && availablePrices[0].pMax > availablePrices[0].pMin;
471
474
  if (availablePrices.length === 1 && !isSingleFlexi) {
472
475
  addTicketToCart(s, availablePrices[0], {
@@ -478,32 +481,38 @@ const SeatingPlan = _ref => {
478
481
  removeTicketFromCart(s, e);
479
482
  }
480
483
  };
481
- const _initialFetch = function initialFetch() {
484
+ const _initialFetch = async function initialFetch() {
482
485
  let isReload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
486
+ let retryCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
483
487
  if (isReload) {
484
488
  setIsReloading(true);
485
489
  }
486
490
  setInitialiseMessage("Initialising seating plan...");
487
- fetch(// `http://localhost:3155/api/legacy/shop/events/${eventId}/${eventVenueId}/showings/${showingId}/tickets/allocated/${areaId}`,
488
- "".concat(apiUrl).concat(promoCode ? "?promo=".concat(promoCode) : ""), {
489
- headers: {
490
- "basket-key": sessionId,
491
- Authorization: "Bearer ".concat(apiKey)
491
+ try {
492
+ const response = await fetch(// `http://localhost:3155/api/legacy/shop/events/${eventId}/${eventVenueId}/showings/${showingId}/tickets/allocated/${areaId}`,
493
+ "".concat(apiUrl).concat(promoCode ? "?promo=".concat(promoCode) : ""), {
494
+ headers: {
495
+ "basket-key": sessionId,
496
+ Authorization: "Bearer ".concat(apiKey)
497
+ }
498
+ });
499
+ if (response.status === 429) {
500
+ if (retryCount >= MAX_RETRIES) {
501
+ throw new Error("We're experiencing high demand. Please try again later.");
502
+ }
503
+ const delay = (0, _utils.getRetryDelay)(response, retryCount);
504
+ setInitialiseMessage("We're experiencing high demand. Please wait while we try again...");
505
+ await new Promise(resolve => setTimeout(resolve, delay));
506
+ return _initialFetch(isReload, retryCount + 1);
492
507
  }
493
- }).then(async response => {
494
508
  const data = await response.json();
495
- data.retryAfter = response.headers.get("Retry-After");
496
- return data;
497
- }).then(data => {
498
- if (data.statusCode === 429) {
499
- setInitialiseMessage("Looks like it's busy. Stand by. Trying again in ".concat(data.retryAfter, " second").concat(data.retryAfter > 1 ? "s" : "", "."));
500
- return setTimeout(_initialFetch, data.retryAfter * 1000);
501
- }
502
- if (data.statusCode === 403) {
503
- if (!sessionId || data.message === "Invalid Session id.") {
509
+ if (!response.ok || !(data !== null && data !== void 0 && data.seats)) {
510
+ if (!sessionId || data.message === "Invalid Session id." || data.message === "Session not found") {
504
511
  throw new Error("Looks like your cart has expired. Please refresh the page to try again.");
505
- } else {
512
+ } else if (data.statusCode === 403) {
506
513
  throw new Error("Invalid API Key or unauthorized URL");
514
+ } else {
515
+ throw new Error("Something went wrong. Please try again or contact support.");
507
516
  }
508
517
  }
509
518
  const img = new Image();
@@ -531,7 +540,7 @@ const SeatingPlan = _ref => {
531
540
  }
532
541
  };
533
542
  setIsReloading(false);
534
- }).catch(error => {
543
+ } catch (error) {
535
544
  var _error$message;
536
545
  // console.log(error);
537
546
  setError({
@@ -542,7 +551,7 @@ const SeatingPlan = _ref => {
542
551
  }
543
552
  });
544
553
  setIsReloading(false);
545
- });
554
+ }
546
555
  };
547
556
  (0, _react.useEffect)(() => {
548
557
  if (!error && areaId !== area) {
@@ -551,13 +560,6 @@ const SeatingPlan = _ref => {
551
560
  setPosition(null);
552
561
  }
553
562
  }, [areaId]);
554
- (0, _react.useEffect)(() => {
555
- if (ticketPopupOpen) {
556
- chosenSeat === null || chosenSeat === void 0 || chosenSeat.circle.target.setStyle({
557
- fillOpacity: 0
558
- });
559
- }
560
- }, [ticketPopupOpen, chosenSeat]);
561
563
 
562
564
  // TEST
563
565
  // useEffect(() => console.log("Booked: ", bookedSeats), [bookedSeats]);
@@ -566,28 +568,6 @@ const SeatingPlan = _ref => {
566
568
  // in full screen mode, render the map in the body, otherwise render in the seating-plan-root div
567
569
  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"));
568
570
  const backdropContainer = mounted && ((_document3 = document) === null || _document3 === void 0 ? void 0 : _document3.body);
569
- const selectedSeatsWithPricing = selectedSeats.map(s => {
570
- const priceages = seats.pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && price.psId === s.psId);
571
- const availablePriceages = priceages.filter(p => p.is_available !== false);
572
- return {
573
- seat: s,
574
- priceage: availablePriceages.length > 0 ? availablePriceages[0] : null
575
- };
576
- });
577
- const groupedSelectedSeats = selectedSeats.reduce((acc, curr) => {
578
- if (curr.psId) {
579
- const priceages = seats.pricing.filter(price => (!priceSectionIds || priceSectionIds.includes(price.psId)) && price.psId === curr.psId);
580
- const availablePriceages = priceages.filter(p => p.is_available !== false);
581
- if (!acc[curr.psId]) {
582
- acc[curr.psId] = {
583
- seats: [],
584
- priceage: availablePriceages.length > 0 ? availablePriceages[0] : undefined
585
- };
586
- }
587
- acc[curr.psId].seats.push(curr);
588
- }
589
- return acc;
590
- }, {});
591
571
 
592
572
  // return seating plan
593
573
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
@@ -601,17 +581,15 @@ const SeatingPlan = _ref => {
601
581
  }), backdropContainer), mapContainer && /*#__PURE__*/(0, _reactDom.createPortal)(/*#__PURE__*/_react.default.createElement("div", {
602
582
  className: "seating-plan-container ".concat(isFullScreen ? "full-screen" : ""),
603
583
  "data-mode": mode
604
- }, pricingPopupOpen && (canMultiSelect || seats.preventOrphanedSeats) ? /*#__PURE__*/_react.default.createElement(_PricingPopup.default, {
584
+ }, pricingPopupOpen && seats && seats.pricing && (canMultiSelect || seats.preventOrphanedSeats) ? /*#__PURE__*/_react.default.createElement(_PricingPopup.default, {
605
585
  onClose: () => {
606
586
  setPricingPopupOpen(false);
607
587
  setSelectedSeats([]);
608
588
  },
609
- groupedSelectedSeats: groupedSelectedSeats,
610
- selectedSeatsWithPricing: selectedSeatsWithPricing,
611
- priceSectionIds: priceSectionIds,
589
+ selectedSeats: selectedSeats,
612
590
  pricing: seats.pricing,
613
- batchAddTicketsToCart: batchAddTicketsToCart,
614
- isSingleSeats: seats.preventOrphanedSeats
591
+ priceSectionIds: priceSectionIds,
592
+ batchAddTicketsToCart: batchAddTicketsToCart
615
593
  }) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null), seats.preventOrphanedSeats && selectQuantityPopupOpen ? /*#__PURE__*/_react.default.createElement(_SelectQuantityPopup.default, {
616
594
  quantity: desiredSeatQuantity,
617
595
  setQuantity: v => {
@@ -665,7 +643,6 @@ const SeatingPlan = _ref => {
665
643
  setPricingPopupOpen: setPricingPopupOpen,
666
644
  selectedSeats: selectedSeats,
667
645
  setSelectedSeats: setSelectedSeats,
668
- selectQuantityPopupOpen: selectQuantityPopupOpen,
669
646
  setSelectQuantityPopupOpen: setSelectQuantityPopupOpen,
670
647
  desiredSeatQuantity: desiredSeatQuantity,
671
648
  setSeatsToRemove: setSeatsToRemove,
@@ -16,7 +16,7 @@ const PriceSelect = _ref => {
16
16
  setNewQuantity
17
17
  } = _ref;
18
18
  return /*#__PURE__*/_react.default.createElement("div", {
19
- className: "price-select"
19
+ className: "seat-qty-select"
20
20
  }, /*#__PURE__*/_react.default.createElement("select", {
21
21
  onChange: e => {
22
22
  setNewQuantity(parseInt(e.target.value));
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = MinusIcon;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ function MinusIcon(_ref) {
10
+ let {
11
+ height = "14px",
12
+ width = "14px",
13
+ color = "currentColor",
14
+ strokeWidth = "1.5",
15
+ className
16
+ } = _ref;
17
+ return /*#__PURE__*/_react.default.createElement("svg", {
18
+ xmlns: "http://www.w3.org/2000/svg",
19
+ fill: "none",
20
+ viewBox: "0 0 24 24",
21
+ height: height,
22
+ width: width,
23
+ strokeWidth: strokeWidth,
24
+ stroke: color,
25
+ className: className
26
+ }, /*#__PURE__*/_react.default.createElement("path", {
27
+ strokeLinecap: "round",
28
+ strokeLinejoin: "round",
29
+ d: "M5 12h14"
30
+ }));
31
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = PlusIcon;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ function PlusIcon(_ref) {
10
+ let {
11
+ height = "14px",
12
+ width = "14px",
13
+ color = "currentColor",
14
+ strokeWidth = "1.5",
15
+ className
16
+ } = _ref;
17
+ return /*#__PURE__*/_react.default.createElement("svg", {
18
+ xmlns: "http://www.w3.org/2000/svg",
19
+ fill: "none",
20
+ viewBox: "0 0 24 24",
21
+ height: height,
22
+ width: width,
23
+ strokeWidth: strokeWidth,
24
+ stroke: color,
25
+ className: className
26
+ }, /*#__PURE__*/_react.default.createElement("path", {
27
+ strokeLinecap: "round",
28
+ strokeLinejoin: "round",
29
+ d: "M12 4.5v15m7.5-7.5h-15"
30
+ }));
31
+ }
@@ -15,13 +15,14 @@
15
15
  color: #333;
16
16
  box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
17
17
  border-radius: 12px;
18
+ min-width: 320px;
18
19
  }
19
20
 
20
21
  .flexi-popup-content {
21
22
  overflow: hidden;
22
23
  }
23
24
 
24
- .flexi-popup-content .popup-header {
25
+ .flexi-popup-header.popup-header {
25
26
  margin-top: 0;
26
27
  background: var(--flexi-accent);
27
28
  color: white;
@@ -43,6 +44,12 @@
43
44
  margin-top: -2px;
44
45
  }
45
46
 
47
+ .flexi-popup .flexi-popup-content .flexi-content.open {
48
+ border: none;
49
+ margin-top: 0;
50
+ padding: 1rem;
51
+ }
52
+
46
53
  .flexi-popup-content .flexi-content.open {
47
54
  margin-top: 0.5rem;
48
55
  padding: 0.5rem;
@@ -168,13 +175,24 @@
168
175
 
169
176
  .min-max p {
170
177
  margin: 0;
171
- font-size: 0.9rem;
178
+ font-size: 0.875rem;
172
179
  }
173
180
 
174
181
  .slider-container .value {
175
182
  text-align: center;
176
- font-size: 1.8rem;
183
+ font-size: 1.8rem !important;
177
184
  font-weight: bold;
178
185
  margin: 0 0 0.5rem 0;
179
186
  color: var(--flexi-accent);
180
187
  }
188
+
189
+ .flexi-checkbox {
190
+ display: flex;
191
+ align-items: center;
192
+ gap: 0.25rem;
193
+ margin: 1rem 0;
194
+ }
195
+
196
+ .flexi-checkbox input[type="checkbox"] {
197
+ accent-color: var(--flexi-accent);
198
+ }