iticket-seatingplan-dev 1.7.6 → 1.7.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.
@@ -72,7 +72,7 @@ function HoverPopup(_ref) {
72
72
  opacity: show ? 1 : 0,
73
73
  transitionDelay: show ? "50ms, 0ms, 0ms" : "250ms, 0ms, 0ms",
74
74
  // a way to have smooth animation when hovering over the same row
75
- transitionDuration: prevHovered !== null && prevHovered !== void 0 && prevHovered.r && prevHovered.r === (hoveredSeat === null || hoveredSeat === void 0 ? void 0 : hoveredSeat.r) ? "100ms, 150ms, 150ms" : "100ms, 50ms, 50ms"
75
+ transitionDuration: prevHovered !== null && prevHovered !== void 0 && prevHovered.infoVisible && prevHovered !== null && prevHovered !== void 0 && prevHovered.r && prevHovered.r === (hoveredSeat === null || hoveredSeat === void 0 ? void 0 : hoveredSeat.r) ? "100ms, 150ms, 150ms" : "100ms, 50ms, 50ms"
76
76
  }
77
77
  }, /*#__PURE__*/_react.default.createElement("div", {
78
78
  className: "hover-popup-content"
@@ -79,10 +79,12 @@ function SeatMap(_ref) {
79
79
  const drawRef = (0, _react.useRef)(null);
80
80
  const popupRef = (0, _react.useRef)(null);
81
81
  const prevHovered = (0, _react.useRef)(null);
82
+ const hideTooltipTimeoutRef = (0, _react.useRef)(null);
82
83
  (0, _react.useEffect)(() => {
83
84
  prevHovered.current = hoveredSeat;
84
85
  }, [hoveredSeat]);
85
86
  const map = (0, _reactLeaflet.useMap)();
87
+ const isTouchScreen = (0, _utils.getIsTouchScreen)();
86
88
 
87
89
  // L.drawLocal.draw.toolbar.buttons.rectangle = "Box select";
88
90
 
@@ -176,6 +178,19 @@ function SeatMap(_ref) {
176
178
  const getNorthSeatLat = seat => {
177
179
  return height / 33.33 - height / 33.33 * seat.y * 0.0105 + 1.4;
178
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
+ };
179
194
  const getSeatCenterLatLng = (seat, isIcon) => {
180
195
  return {
181
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),
@@ -218,12 +233,19 @@ function SeatMap(_ref) {
218
233
  }
219
234
  }, [mode, map]);
220
235
  const seatsMap = (0, _react.useMemo)(() => new Map(seats.seats.map(s => [s.sId, s])), [seats.seats]);
221
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_HoverPopup.default, {
236
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
237
+ className: "mobile-tooltip",
238
+ style: {
239
+ opacity: clickedSeat ? 1 : 0,
240
+ top: clickedSeat ? clickedSeat.xy.y - clickedSeat.offset - 12 : -10000,
241
+ left: clickedSeat ? clickedSeat.xy.x : -10000
242
+ }
243
+ }, "Tap again to select"), /*#__PURE__*/_react.default.createElement(_HoverPopup.default, {
222
244
  hoveredSeat: hoveredSeat,
223
- highlightedSeats: highlightedSeats && highlightedSeats.length > 0 ? highlightedSeats : null,
245
+ highlightedSeats: (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0 ? highlightedSeats : null,
224
246
  mousePos: mousePos,
225
- show: (hoveredSeat || (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0) && !ticketPopupOpen && !pricingPopupOpen && !isDragging && isHoveringOnSeat,
226
- availablePrices: highlightedSeats && highlightedSeats.length > 0 ? highlightedSeats.flatMap(s => {
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,
248
+ availablePrices: (highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0 ? highlightedSeats.flatMap(s => {
227
249
  var _seats$pricing;
228
250
  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))) || [];
229
251
  }) : 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,
@@ -430,6 +452,7 @@ function SeatMap(_ref) {
430
452
  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)) || [];
431
453
  const hasSeatPrices = (seatPrices === null || seatPrices === void 0 ? void 0 : seatPrices.length) > 0;
432
454
  const isSingleFlexi = seatPrices.length === 1 && !!seatPrices[0].pMax && !!seatPrices[0].pMin && seatPrices[0].pMax > seatPrices[0].pMin;
455
+ const isOrphanMode = seats.preventOrphanedSeats && desiredSeatQuantity > 0;
433
456
  return /*#__PURE__*/_react.default.createElement("div", {
434
457
  key: i
435
458
  }, (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, {
@@ -458,7 +481,7 @@ function SeatMap(_ref) {
458
481
  }
459
482
 
460
483
  // orphan multi-select mode
461
- if (seats.preventOrphanedSeats && desiredSeatQuantity > 0) {
484
+ if (isOrphanMode) {
462
485
  map.closePopup();
463
486
  if (s.s === _utils.statuses.USER_PENDING) {
464
487
  const newSeatsToRemove = (0, _utils.getAdjacentBookedSeats)(s, seatsMap);
@@ -470,10 +493,14 @@ function SeatMap(_ref) {
470
493
  }
471
494
  return;
472
495
  }
473
- if (highlightedSeats.length > 0 && highlightedSeats.length === desiredSeatQuantity) {
474
- if ((0, _utils.isTouchScreen)() && clickedSeat !== s.ssId) {
475
- setClickedSeat(s.ssId);
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
+ }));
476
502
  } else {
503
+ setClickedSeat(null);
477
504
  const groupedSeats = (0, _utils.groupSeatsByPriceSection)(highlightedSeats, seats.pricing, priceSectionIds);
478
505
  const priceages = Object.values(groupedSeats).flatMap(group => group.priceages.map(pa => pa.priceage));
479
506
  if (priceages.length === 1 && (priceages[0].q === null || priceages[0].q >= desiredSeatQuantity) && !isSingleFlexi) {
@@ -481,6 +508,11 @@ function SeatMap(_ref) {
481
508
  seat: s,
482
509
  priceage: priceages[0]
483
510
  })));
511
+ setHighlightedSeats([]);
512
+ setSelectedSeats([]);
513
+ setHoveredSeat(prev => _objectSpread(_objectSpread({}, prev), {}, {
514
+ infoVisible: false
515
+ }));
484
516
  } else {
485
517
  setSelectedSeats([...highlightedSeats]);
486
518
  setPricingPopupOpen(true);
@@ -496,8 +528,17 @@ function SeatMap(_ref) {
496
528
 
497
529
  // single select mode
498
530
  if (mode === _utils.modes.SINGLE && hasSeatPrices) {
499
- handleClickSeat(e, s);
500
- return;
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
+ }
501
542
  }
502
543
  },
503
544
  popupopen: popup => {
@@ -515,45 +556,65 @@ function SeatMap(_ref) {
515
556
  }
516
557
  }
517
558
  },
518
- mouseover: () => {
559
+ mouseover: e => {
560
+ if (hideTooltipTimeoutRef.current) {
561
+ clearTimeout(hideTooltipTimeoutRef.current);
562
+ }
519
563
  if ((mode === _utils.modes.DRAG || mode === _utils.modes.REMOVE) && isDragging && canMultiSelect && hasSeatPrices) {
520
564
  if (!selectedSeats.find(seat => seat.ssId === s.ssId) && s.s === (mode === _utils.modes.DRAG ? _utils.statuses.UNSOLD : _utils.statuses.USER_PENDING)) {
521
565
  setSelectedSeats(prev => [...prev, s]);
522
566
  }
523
567
  } else {
524
568
  setIsHoveringOnSeat(true);
525
- setHoveredSeat(s);
526
- setClickedSeat(s.ssId);
527
- if (seats.preventOrphanedSeats && desiredSeatQuantity > 0 && s.s === _utils.statuses.UNSOLD && mode === _utils.modes.SINGLE) {
569
+ setHoveredSeat(_objectSpread(_objectSpread({}, s), {}, {
570
+ infoVisible: true
571
+ }));
572
+ if (isOrphanMode && s.s === _utils.statuses.UNSOLD && mode === _utils.modes.SINGLE) {
528
573
  const seatsToBook = (0, _utils.getValidSeats)(s, seatsMap, desiredSeatQuantity);
529
574
  if (seatsToBook.valid) {
530
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
+ }));
531
587
  } else {
532
588
  setGreyedOutSeats(seatsToBook.seats);
589
+ setHighlightedSeats([]);
533
590
  }
591
+ } else if (highlightedSeats.length > 0) {
592
+ setHighlightedSeats([]);
534
593
  }
535
594
  }
536
595
  },
537
- mouseout: () => {
596
+ mouseout: async () => {
538
597
  if (greyedOutSeats.length > 0) {
539
598
  setGreyedOutSeats([]);
540
599
  }
541
600
  if (clickedSeat) {
542
601
  setClickedSeat(null);
543
602
  }
544
- if (hoveredSeat || highlightedSeats) {
545
- setTimeout(() => {
546
- if (hoveredSeat) {
547
- setHoveredSeat(prev => prev && prev === hoveredSeat ? null : prev);
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
+ }));
548
612
  }
549
- if (highlightedSeats) {
550
- setHighlightedSeats(prev => prev && prev === highlightedSeats ? [] : prev);
613
+ if ((highlightedSeats === null || highlightedSeats === void 0 ? void 0 : highlightedSeats.length) > 0) {
614
+ setHighlightedSeats([]);
551
615
  }
552
616
  }, 400);
553
617
  }
554
- if (isHoveringOnSeat) {
555
- setIsHoveringOnSeat(false);
556
- }
557
618
  },
558
619
  mousemove: e => {
559
620
  setMousePos({
@@ -562,11 +623,7 @@ function SeatMap(_ref) {
562
623
  });
563
624
  }
564
625
  }
565
- }, (0, _utils.isTouchScreen)() && /*#__PURE__*/_react.default.createElement(_reactLeaflet.Tooltip, {
566
- className: "mobile-tooltip",
567
- direction: "top",
568
- offset: [0, height * 0.03 + -60]
569
- }, "Tap again to select these seats"), s.s === _utils.statuses.UNSOLD && hasSeatPrices ? /*#__PURE__*/_react.default.createElement(_reactLeaflet.Popup, {
626
+ }, s.s === _utils.statuses.UNSOLD && hasSeatPrices ? /*#__PURE__*/_react.default.createElement(_reactLeaflet.Popup, {
570
627
  className: "ticket-popup popup-".concat(s.sId)
571
628
  }, isSingleFlexi ? /*#__PURE__*/_react.default.createElement("div", {
572
629
  className: "single-flexi"
@@ -22,7 +22,7 @@
22
22
  right: 0;
23
23
  bottom: 0;
24
24
  background: rgba(0, 0, 0, 0.5);
25
- z-index: 461;
25
+ z-index: 1010;
26
26
  pointer-events: none;
27
27
  }
28
28
 
@@ -1571,6 +1571,32 @@ svg.leaflet-image-layer.leaflet-interactive path {
1571
1571
  height: 0.875rem;
1572
1572
  }
1573
1573
 
1574
+ .mobile-tooltip {
1575
+ pointer-events: none;
1576
+ position: absolute;
1577
+ background: rgba(255, 255, 255, 0.9);
1578
+ border-radius: 5px;
1579
+ padding: 0.25rem 0.5rem;
1580
+ transform: translate(-50%, -100%);
1581
+ transition: opacity 0.1s ease-in-out;
1582
+ z-index: 1005;
1583
+ font-size: 0.75rem;
1584
+ color: #333;
1585
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
1586
+ text-align: center;
1587
+ width: max-content;
1588
+ }
1589
+
1590
+ .mobile-tooltip::after {
1591
+ content: "";
1592
+ position: absolute;
1593
+ top: 100%;
1594
+ left: 50%;
1595
+ border: 5px solid transparent;
1596
+ border-top-color: rgba(255, 255, 255, 0.9);
1597
+ transform: translateX(-50%);
1598
+ }
1599
+
1574
1600
  /* Printing */
1575
1601
 
1576
1602
  @media print {
@@ -3,9 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isTouchScreen = exports.groupSeatsByPriceSection = exports.getValidSeats = exports.getRowSection = exports.getRetryDelay = exports.getInitialColor = exports.getAdjacentBookedSeats = exports.createsOrphan = exports.canSelectSingleSeatGivenOrphanRules = exports.calculateCenterOfMap = exports.NZDollar = void 0;
6
+ exports.groupSeatsByPriceSection = exports.getValidSeats = exports.getRowSection = exports.getRetryDelay = exports.getIsTouchScreen = exports.getInitialColor = exports.getAdjacentBookedSeats = exports.createsOrphan = exports.canSelectSingleSeatGivenOrphanRules = exports.calculateCenterOfMap = exports.NZDollar = void 0;
7
7
  var _enums = require("./enums");
8
- const isTouchScreen = () => {
8
+ const getIsTouchScreen = () => {
9
9
  let hasTouchScreen = false;
10
10
  if (typeof window !== "undefined") {
11
11
  if ("maxTouchPoints" in window.navigator) {
@@ -20,7 +20,7 @@ const isTouchScreen = () => {
20
20
  }
21
21
  return hasTouchScreen;
22
22
  };
23
- exports.isTouchScreen = isTouchScreen;
23
+ exports.getIsTouchScreen = getIsTouchScreen;
24
24
  const getInitialColor = (s, price, loading, disabled, selected, greyedOut) => {
25
25
  // selected state for multiselect
26
26
  if (selected) {
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.7.6",
5
+ "version": "1.7.8",
6
6
  "private": false,
7
7
  "keywords": [
8
8
  "iticket",