kupos-ui-components-lib 9.10.9 → 9.11.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.
- package/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemDesktop.js +3 -20
- package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemMobile.js +1 -1
- package/dist/components/ServiceItem/mobileTypes.d.ts +0 -1
- package/dist/components/ServiceItem/types.d.ts +0 -7
- package/dist/styles.css +10 -6
- package/dist/ui/FeaturServiceUiMobile/FeatureServiceUiMobile.d.ts +1 -1
- package/dist/ui/FeaturServiceUiMobile/FeatureServiceUiMobile.js +117 -33
- package/dist/ui/FeatureServiceUI/FeatureServiceUi.js +112 -36
- package/dist/ui/SeatSection/SeatSection.d.ts +1 -7
- package/dist/ui/SeatSection/SeatSection.js +20 -41
- package/dist/ui/mobileweb/DateTimeSectionMobile.d.ts +1 -2
- package/dist/ui/mobileweb/DateTimeSectionMobile.js +6 -12
- package/dist/ui/mobileweb/SeatSectionMobile.d.ts +1 -2
- package/dist/ui/mobileweb/SeatSectionMobile.js +23 -22
- package/dist/utils/CommonService.d.ts +9 -1
- package/dist/utils/CommonService.js +66 -7
- package/package.json +1 -1
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +1 -43
- package/src/components/ServiceItem/ServiceItemMobile.tsx +1 -2
- package/src/components/ServiceItem/mobileTypes.ts +26 -31
- package/src/components/ServiceItem/types.ts +0 -12
- package/src/ui/FeaturServiceUiMobile/FeatureServiceUiMobile.tsx +151 -70
- package/src/ui/FeatureServiceUI/FeatureServiceUi.tsx +132 -50
- package/src/ui/SeatSection/SeatSection.tsx +42 -89
- package/src/ui/mobileweb/DateTimeSectionMobile.tsx +35 -44
- package/src/ui/mobileweb/SeatSectionMobile.tsx +22 -27
- package/src/utils/CommonService.ts +84 -11
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ServiceItemProps } from "./types";
|
|
3
|
-
declare function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isPeruSites, showAvailableSeats, isSeatIcon, isLinatal, isPeru, t, siteType, isAllinBus, isExpand, setIsExpand, coachKey, viewersConfig, isNewUi, showLoginModal, isLoggedIn, showLoginOption,
|
|
3
|
+
declare function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isPeruSites, showAvailableSeats, isSeatIcon, isLinatal, isPeru, t, siteType, isAllinBus, isExpand, setIsExpand, coachKey, viewersConfig, isNewUi, showLoginModal, isLoggedIn, showLoginOption, isFeatureDropDownExpand, setIsFeatureDropDownExpand, ticketQuantity, onIncreaseTicketQuantity, onDecreaseTicketQuantity, onRemateUiButtonClick, selectedTimeSlot, onTimeSlotChange, isTimeDropdownOpen, onTimeDropdownToggle, wowDealData, isFlores, operatorLabel, }: ServiceItemProps & {
|
|
4
4
|
currencySign?: string;
|
|
5
5
|
}): React.ReactElement;
|
|
6
6
|
export default ServiceItemPB;
|
|
@@ -87,12 +87,9 @@ const ANIMATION_MAP = {
|
|
|
87
87
|
kupos: flameAnimation,
|
|
88
88
|
},
|
|
89
89
|
};
|
|
90
|
-
function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isPeruSites, showAvailableSeats, isSeatIcon, isLinatal, isPeru, t = (key) => key, siteType, isAllinBus, isExpand, setIsExpand, coachKey, viewersConfig, isNewUi, showLoginModal, isLoggedIn, showLoginOption,
|
|
90
|
+
function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isPeruSites, showAvailableSeats, isSeatIcon, isLinatal, isPeru, t = (key) => key, siteType, isAllinBus, isExpand, setIsExpand, coachKey, viewersConfig, isNewUi, showLoginModal, isLoggedIn, showLoginOption, isFeatureDropDownExpand, setIsFeatureDropDownExpand, ticketQuantity, onIncreaseTicketQuantity, onDecreaseTicketQuantity, onRemateUiButtonClick, selectedTimeSlot, onTimeSlotChange, isTimeDropdownOpen, onTimeDropdownToggle, wowDealData, isFlores, operatorLabel, }) {
|
|
91
91
|
var _a, _b, _c;
|
|
92
|
-
|
|
93
|
-
onClearSeatSelectionError === null || onClearSeatSelectionError === void 0 ? void 0 : onClearSeatSelectionError();
|
|
94
|
-
onSeatSelect === null || onSeatSelect === void 0 ? void 0 : onSeatSelect(key, price, seatKey, apiSeatType);
|
|
95
|
-
};
|
|
92
|
+
console.log("🚀 ~ ServiceItemPB ~ serviceItem:", serviceItem);
|
|
96
93
|
const getAnimationIcon = (icon) => {
|
|
97
94
|
var _a;
|
|
98
95
|
const animation = ANIMATION_MAP[icon];
|
|
@@ -231,16 +228,6 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
|
|
|
231
228
|
});
|
|
232
229
|
return;
|
|
233
230
|
}
|
|
234
|
-
if (isTrain) {
|
|
235
|
-
if (!selectedSeatKey) {
|
|
236
|
-
onShowSeatSelectionError === null || onShowSeatSelectionError === void 0 ? void 0 : onShowSeatSelectionError(serviceItem.id);
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
if (onTrainButtonClick) {
|
|
240
|
-
onTrainButtonClick();
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
231
|
onBookButtonPress();
|
|
245
232
|
};
|
|
246
233
|
const items = [
|
|
@@ -307,13 +294,9 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
|
|
|
307
294
|
backgroundColor: "#ccc",
|
|
308
295
|
} }),
|
|
309
296
|
React.createElement("div", { className: "content-center" },
|
|
310
|
-
React.createElement(SeatSection, { seatTypes: serviceItem.seat_types, serviceItem: serviceItem, availableSeats: serviceItem.available_seats, isSoldOut: isSoldOut, priceColor: colors.priceColor, dpSeatColor: colors.seatPriceColor, currencySign: currencySign, removeDuplicateSeats: removeDuplicateSeats, isPeru: isPeru, renderIcon: renderIcon, discountSeatPriceColor: colors.discountSeatPriceColor,
|
|
297
|
+
React.createElement(SeatSection, { seatTypes: serviceItem.seat_types, serviceItem: serviceItem, availableSeats: serviceItem.available_seats, isSoldOut: isSoldOut, priceColor: colors.priceColor, dpSeatColor: colors.seatPriceColor, currencySign: currencySign, removeDuplicateSeats: removeDuplicateSeats, isPeru: isPeru, renderIcon: renderIcon, discountSeatPriceColor: colors.discountSeatPriceColor, tooltipColor: colors.tooltipColor })),
|
|
311
298
|
React.createElement("div", { className: "relative" },
|
|
312
299
|
React.createElement(KuposButton, { isSoldOut: isSoldOut, isLoading: serviceDetailsLoading, buttonColor: colors.kuposButtonColor, buyLabel: translation === null || translation === void 0 ? void 0 : translation.buyButton, soldOutLabel: translation === null || translation === void 0 ? void 0 : translation.soldOutButton, soldOutIcon: renderIcon("soldOutIcon", "14px"), onClick: checkMidnight }),
|
|
313
|
-
showSeatSelectionError === serviceItem.id && isTrain && (React.createElement("div", { className: "flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]" },
|
|
314
|
-
React.createElement("div", { className: "text-[9px] text-center whitespace-nowrap", style: {
|
|
315
|
-
color: colors.seatPriceColor,
|
|
316
|
-
} }, "Selecciona el tipo de servicio"))),
|
|
317
300
|
showLastSeats ? (React.createElement("div", { className: "flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]" }, (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) < 10 &&
|
|
318
301
|
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) > 0 && (React.createElement("div", { className: "text-[12px] mt-1 text-center", style: {
|
|
319
302
|
color: colors.seatPriceColor,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { MobileServiceItemProps } from "./mobileTypes";
|
|
3
|
-
declare function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig,
|
|
3
|
+
declare function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig, isFeatureDropDownExpand, setIsFeatureDropDownExpand, ticketQuantity, onIncreaseTicketQuantity, onDecreaseTicketQuantity, cityOrigin, cityDestination, isNewUi, onRemateUiButtonClick, selectedTimeSlot, onTimeSlotChange, isTimeDropdownOpen, onTimeDropdownToggle, wowDealData, isFlores, operatorLabel }: MobileServiceItemProps): React.ReactElement;
|
|
4
4
|
export default ServiceItemMobile;
|
|
@@ -18,7 +18,7 @@ const exceptions = [
|
|
|
18
18
|
"blanco",
|
|
19
19
|
"asiento_mascota",
|
|
20
20
|
];
|
|
21
|
-
function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig,
|
|
21
|
+
function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig, isFeatureDropDownExpand, setIsFeatureDropDownExpand, ticketQuantity, onIncreaseTicketQuantity, onDecreaseTicketQuantity, cityOrigin, cityDestination, isNewUi, onRemateUiButtonClick, selectedTimeSlot, onTimeSlotChange, isTimeDropdownOpen, onTimeDropdownToggle, wowDealData, isFlores, operatorLabel }) {
|
|
22
22
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
23
23
|
const isItemExpanded = serviceItem.id === isExpanded;
|
|
24
24
|
const isPetSeat = (Object.keys(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.pet_seat_info) || []).length > 0;
|
|
@@ -245,13 +245,6 @@ export interface ServiceItemProps {
|
|
|
245
245
|
showLoginModal?: any;
|
|
246
246
|
isLoggedIn?: any;
|
|
247
247
|
showLoginOption?: boolean;
|
|
248
|
-
isTrain?: boolean;
|
|
249
|
-
selectedSeatKey?: any;
|
|
250
|
-
onSeatSelect?: (key: any, price: number, seatKey: string, apiSeatType?: string) => void;
|
|
251
|
-
onTrainButtonClick?: any;
|
|
252
|
-
showSeatSelectionError?: string | null;
|
|
253
|
-
onShowSeatSelectionError?: (serviceId: string) => void;
|
|
254
|
-
onClearSeatSelectionError?: () => void;
|
|
255
248
|
selectedTimeSlot?: string;
|
|
256
249
|
onTimeSlotChange?: (slot: string) => void;
|
|
257
250
|
isTimeDropdownOpen?: string | number | null;
|
package/dist/styles.css
CHANGED
|
@@ -572,9 +572,6 @@
|
|
|
572
572
|
.grid-cols-2 {
|
|
573
573
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
574
574
|
}
|
|
575
|
-
.grid-cols-3 {
|
|
576
|
-
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
577
|
-
}
|
|
578
575
|
.grid-cols-4 {
|
|
579
576
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
580
577
|
}
|
|
@@ -854,6 +851,9 @@
|
|
|
854
851
|
.bg-\[lightgray\] {
|
|
855
852
|
background-color: lightgray;
|
|
856
853
|
}
|
|
854
|
+
.bg-\[white\] {
|
|
855
|
+
background-color: white;
|
|
856
|
+
}
|
|
857
857
|
.bg-transparent {
|
|
858
858
|
background-color: transparent;
|
|
859
859
|
}
|
|
@@ -1023,9 +1023,6 @@
|
|
|
1023
1023
|
.text-right {
|
|
1024
1024
|
text-align: right;
|
|
1025
1025
|
}
|
|
1026
|
-
.text-\[9px\] {
|
|
1027
|
-
font-size: 9px;
|
|
1028
|
-
}
|
|
1029
1026
|
.text-\[10px\] {
|
|
1030
1027
|
font-size: 10px;
|
|
1031
1028
|
}
|
|
@@ -1277,6 +1274,13 @@
|
|
|
1277
1274
|
}
|
|
1278
1275
|
}
|
|
1279
1276
|
}
|
|
1277
|
+
.hover\:z-\[200\] {
|
|
1278
|
+
&:hover {
|
|
1279
|
+
@media (hover: hover) {
|
|
1280
|
+
z-index: 200;
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1280
1284
|
.hover\:z-\[500\] {
|
|
1281
1285
|
&:hover {
|
|
1282
1286
|
@media (hover: hover) {
|
|
@@ -14,7 +14,7 @@ declare const FeatureServiceUiMobile: ({ serviceItem, showTopLabel, colors, isSo
|
|
|
14
14
|
onIncreaseTicketQuantity: any;
|
|
15
15
|
onDecreaseTicketQuantity: any;
|
|
16
16
|
onBookButtonPress: any;
|
|
17
|
-
selectedTimeSlot
|
|
17
|
+
selectedTimeSlot: any;
|
|
18
18
|
onTimeSlotChange: any;
|
|
19
19
|
isTimeDropdownOpen: any;
|
|
20
20
|
onTimeDropdownToggle: any;
|
|
@@ -2,12 +2,6 @@ import React from "react";
|
|
|
2
2
|
import LottiePlayer from "../../assets/LottiePlayer";
|
|
3
3
|
import commonService from "../../utils/CommonService";
|
|
4
4
|
import flameAnimation from "../../assets/images/anims/service_list/flame_anim.json";
|
|
5
|
-
const TIME_SLOTS = [
|
|
6
|
-
"Entre 07:00 AM y 10:00 AM",
|
|
7
|
-
"Entre 11:00 AM y 14:00 AM",
|
|
8
|
-
"Entre 15:00 PM y 18:00 PM",
|
|
9
|
-
"Entre 19:00 PM y 22:00 PM",
|
|
10
|
-
];
|
|
11
5
|
const HARDCODED_OPERATORS = [
|
|
12
6
|
{
|
|
13
7
|
logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Turbus_logo.svg/320px-Turbus_logo.svg.png",
|
|
@@ -28,8 +22,8 @@ const HARDCODED_OPERATORS = [
|
|
|
28
22
|
seatsAvailable: "3 disponibles",
|
|
29
23
|
},
|
|
30
24
|
];
|
|
31
|
-
const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut, cityOrigin, cityDestination, renderIcon, viewersConfig, isFeatureDropDownExpand, onToggleExpand, ticketQuantity = 1, onIncreaseTicketQuantity, onDecreaseTicketQuantity, onBookButtonPress, selectedTimeSlot
|
|
32
|
-
var _a, _b, _c, _d, _e, _f
|
|
25
|
+
const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut, cityOrigin, cityDestination, renderIcon, viewersConfig, isFeatureDropDownExpand, onToggleExpand, ticketQuantity = 1, onIncreaseTicketQuantity, onDecreaseTicketQuantity, onBookButtonPress, selectedTimeSlot, onTimeSlotChange, isTimeDropdownOpen, onTimeDropdownToggle, wowDealData = undefined, }) => {
|
|
26
|
+
var _a, _b, _c, _d, _e, _f;
|
|
33
27
|
// Use wow_deal data if available, otherwise fall back to serviceItem operators or hardcoded
|
|
34
28
|
const operators = ((_a = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.services) === null || _a === void 0 ? void 0 : _a.length) > 0
|
|
35
29
|
? wowDealData.services.slice(0, 3).map((service) => ({
|
|
@@ -52,6 +46,7 @@ const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut,
|
|
|
52
46
|
const dealWindowFrom = (wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.deal_window_from) || "07:00";
|
|
53
47
|
const dealWindowTo = (wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.deal_window_to) || "10:00";
|
|
54
48
|
const travelDate = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.travel_date;
|
|
49
|
+
const serviceWindowHours = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.service_window_hours;
|
|
55
50
|
// Calculate countdown seconds from expires_at ISO timestamp
|
|
56
51
|
const getCountdownSeconds = () => {
|
|
57
52
|
if (!expiresAt)
|
|
@@ -61,23 +56,47 @@ const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut,
|
|
|
61
56
|
const seconds = Math.max(0, Math.floor((expires - now) / 1000));
|
|
62
57
|
return seconds;
|
|
63
58
|
};
|
|
64
|
-
// Generate time
|
|
65
|
-
const
|
|
66
|
-
|
|
59
|
+
// Generate dynamic time slots from deal window + service window hours
|
|
60
|
+
const allTimeSlots = serviceWindowHours
|
|
61
|
+
? commonService.generateTimeSlots(dealWindowFrom, dealWindowTo, serviceWindowHours)
|
|
62
|
+
: [];
|
|
63
|
+
// Filter slots to only those that have at least one service
|
|
64
|
+
const services = (wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.services) || [];
|
|
65
|
+
const availableTimeSlots = allTimeSlots.filter((slot) => services.some((s) => {
|
|
66
|
+
const depMin = commonService.timeToMinutes(s.departure_time);
|
|
67
|
+
return depMin >= slot.start && depMin < slot.end;
|
|
68
|
+
}));
|
|
69
|
+
// Active slot: the one matching selectedTimeSlot label, or the first available
|
|
70
|
+
const activeSlot = availableTimeSlots.find((s) => s.label === selectedTimeSlot) ||
|
|
71
|
+
availableTimeSlots[0];
|
|
72
|
+
// Services that fall within the active slot, sorted by final price ascending
|
|
73
|
+
const servicesInActiveSlot = activeSlot
|
|
74
|
+
? services
|
|
75
|
+
.filter((s) => {
|
|
76
|
+
const depMin = commonService.timeToMinutes(s.departure_time);
|
|
77
|
+
return depMin >= activeSlot.start && depMin < activeSlot.end;
|
|
78
|
+
})
|
|
79
|
+
.sort((a, b) => a.final_price - b.final_price)
|
|
80
|
+
: services;
|
|
81
|
+
// The selected price (final and original) from the cheapest service in the active slot
|
|
82
|
+
const selectedSlotService = servicesInActiveSlot === null || servicesInActiveSlot === void 0 ? void 0 : servicesInActiveSlot[0];
|
|
83
|
+
const displayFinalPrice = selectedSlotService
|
|
84
|
+
? selectedSlotService.final_price
|
|
85
|
+
: finalPrice;
|
|
86
|
+
const displayOriginalPrice = selectedSlotService
|
|
87
|
+
? selectedSlotService.original_price
|
|
88
|
+
: originalPrice;
|
|
89
|
+
const displaySavingsPercent = selectedSlotService && selectedSlotService.original_price
|
|
90
|
+
? Math.round(((selectedSlotService.original_price - selectedSlotService.final_price) /
|
|
91
|
+
selectedSlotService.original_price) *
|
|
92
|
+
100)
|
|
93
|
+
: savingsPercent;
|
|
94
|
+
// The label shown on the dropdown button
|
|
95
|
+
const departureRange = (activeSlot === null || activeSlot === void 0 ? void 0 : activeSlot.label) || `Entre ${dealWindowFrom} y ${dealWindowTo}`;
|
|
67
96
|
const isItemExpanded = serviceItem.id === isFeatureDropDownExpand ||
|
|
68
97
|
isFeatureDropDownExpand === true;
|
|
69
98
|
const isThisTimeDropdownOpen = isTimeDropdownOpen === serviceItem.id;
|
|
70
99
|
const canDecreaseTicketQuantity = ticketQuantity > 1;
|
|
71
|
-
const departures = (_d = (_c = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.services) === null || _c === void 0 ? void 0 : _c.map((s) => s.departure_time)) === null || _d === void 0 ? void 0 : _d.filter(Boolean);
|
|
72
|
-
let departureRange = `Entre ${dealWindowFrom} y ${dealWindowTo}`;
|
|
73
|
-
if (departures === null || departures === void 0 ? void 0 : departures.length) {
|
|
74
|
-
const sorted = [...departures].sort((a, b) => {
|
|
75
|
-
const [ah, am] = a.split(":").map(Number);
|
|
76
|
-
const [bh, bm] = b.split(":").map(Number);
|
|
77
|
-
return ah * 60 + am - (bh * 60 + bm);
|
|
78
|
-
});
|
|
79
|
-
departureRange = `Entre ${sorted[0]} y ${sorted[sorted.length - 1]}`;
|
|
80
|
-
}
|
|
81
100
|
const HOW_IT_WORKS_STEPS = [
|
|
82
101
|
{
|
|
83
102
|
icon: "flexible",
|
|
@@ -145,28 +164,91 @@ const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut,
|
|
|
145
164
|
} },
|
|
146
165
|
React.createElement("span", null,
|
|
147
166
|
"AHORRAS ",
|
|
148
|
-
|
|
167
|
+
displaySavingsPercent,
|
|
149
168
|
"%")))),
|
|
150
169
|
React.createElement("div", { id: `service-card-${serviceItem.id}`, className: "bg-[#0C1421] text-white mx-auto relative rounded-[14px] p-[14px] text-[13.33px]" },
|
|
151
170
|
React.createElement("div", { className: "flex flex-col gap-[10px]" },
|
|
152
171
|
React.createElement("div", { className: " text-[white]" },
|
|
153
172
|
React.createElement("div", { className: "flex flex-col gap-[10px] relative" },
|
|
154
173
|
React.createElement("div", { className: "flex items-center gap-[6px]" },
|
|
155
|
-
React.createElement("img", { src: (
|
|
174
|
+
React.createElement("img", { src: (_c = serviceItem.icons) === null || _c === void 0 ? void 0 : _c.whiteOrigin, alt: "origin", className: `w-[13px] h-[13px] shrink-0 ${isSoldOut ? "grayscale" : ""}` }),
|
|
156
175
|
React.createElement("span", { className: "text-[14px] bold-text" }, cityOrigin === null || cityOrigin === void 0 ? void 0 : cityOrigin.label.split(",")[0]),
|
|
157
176
|
React.createElement("span", { className: "mx-[6px] text-[14px] bold-text" }, "\u2192"),
|
|
158
|
-
React.createElement("img", { src: (
|
|
177
|
+
React.createElement("img", { src: (_d = serviceItem.icons) === null || _d === void 0 ? void 0 : _d.whiteDestination, alt: "destination", className: `w-[13px] h-[13px] shrink-0 ${isSoldOut ? "grayscale" : ""}`, style: { opacity: isSoldOut ? 0.5 : 1 } }),
|
|
159
178
|
React.createElement("span", { className: "text-[14px] bold-text" }, cityDestination === null || cityDestination === void 0 ? void 0 : cityDestination.label.split(",")[0])),
|
|
160
179
|
React.createElement("div", { className: "flex items-center gap-[6px]" },
|
|
161
|
-
React.createElement("div", { className: "
|
|
180
|
+
React.createElement("div", { className: "kupos-time-dd relative", tabIndex: 0, onBlur: (e) => {
|
|
181
|
+
if (!e.currentTarget.contains(e.relatedTarget)) {
|
|
182
|
+
onTimeDropdownToggle === null || onTimeDropdownToggle === void 0 ? void 0 : onTimeDropdownToggle(null);
|
|
183
|
+
}
|
|
184
|
+
}, style: { outline: "none" } },
|
|
185
|
+
React.createElement("button", { type: "button", onClick: () => onTimeDropdownToggle === null || onTimeDropdownToggle === void 0 ? void 0 : onTimeDropdownToggle(isThisTimeDropdownOpen ? null : serviceItem.id), className: "flex cursor-pointer select-none items-center gap-[6px] border-none bg-transparent p-0 bold-text text-[13px] text-[white]" },
|
|
186
|
+
React.createElement("span", null, departureRange),
|
|
187
|
+
React.createElement("img", { src: (_e = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.icons) === null || _e === void 0 ? void 0 : _e.downArrow, alt: "down arrow", className: `kupos-time-chevron transition-transform duration-200 ${isThisTimeDropdownOpen ? "rotate-180" : "rotate-0"}`, style: {
|
|
188
|
+
width: "12px",
|
|
189
|
+
height: "8px",
|
|
190
|
+
filter: "brightness(0) invert(1)",
|
|
191
|
+
} })),
|
|
192
|
+
isThisTimeDropdownOpen && (React.createElement(React.Fragment, null,
|
|
193
|
+
React.createElement("div", { className: "absolute left-0 top-[calc(100%+10px)]", style: {
|
|
194
|
+
zIndex: 20,
|
|
195
|
+
backgroundColor: "#fff",
|
|
196
|
+
borderRadius: "14px",
|
|
197
|
+
minWidth: "190px",
|
|
198
|
+
boxShadow: "0 8px 32px rgba(0,0,0,0.28)",
|
|
199
|
+
overflow: "hidden",
|
|
200
|
+
padding: "6px 0",
|
|
201
|
+
} }, availableTimeSlots.map((slot) => {
|
|
202
|
+
const isActive = slot.label === selectedTimeSlot ||
|
|
203
|
+
slot === activeSlot;
|
|
204
|
+
// Count services in this slot
|
|
205
|
+
const count = services.filter((s) => {
|
|
206
|
+
const depMin = commonService.timeToMinutes(s.departure_time);
|
|
207
|
+
return depMin >= slot.start && depMin < slot.end;
|
|
208
|
+
}).length;
|
|
209
|
+
return (React.createElement("button", { key: slot.label, type: "button", onClick: () => {
|
|
210
|
+
onTimeSlotChange === null || onTimeSlotChange === void 0 ? void 0 : onTimeSlotChange(slot.label);
|
|
211
|
+
onTimeDropdownToggle === null || onTimeDropdownToggle === void 0 ? void 0 : onTimeDropdownToggle(null);
|
|
212
|
+
// const slotServices = services.filter((s) => {
|
|
213
|
+
// const depMin = commonService.timeToMinutes(
|
|
214
|
+
// s.departure_time,
|
|
215
|
+
// );
|
|
216
|
+
// return (
|
|
217
|
+
// depMin >= slot.start && depMin < slot.end
|
|
218
|
+
// );
|
|
219
|
+
// });
|
|
220
|
+
// console.log(
|
|
221
|
+
// "Selected slot label:",
|
|
222
|
+
// slot.label,
|
|
223
|
+
// );
|
|
224
|
+
// console.log(
|
|
225
|
+
// "Services in selected slot:",
|
|
226
|
+
// slotServices,
|
|
227
|
+
// );
|
|
228
|
+
}, className: `flex w-full cursor-pointer items-center justify-between gap-[10px] border-none px-[12px] py-[9px] text-left text-[13px] ${isActive ? "bg-[#FF5C60] font-bold text-[white]" : "bg-transparent font-normal text-[#1a1a1a]"}` },
|
|
229
|
+
React.createElement("span", null, slot.label),
|
|
230
|
+
count > 0 && (React.createElement("span", { className: `text-[11px] rounded-full px-[6px] py-[2px] font-bold ${isActive
|
|
231
|
+
? "bg-[white] text-[#FF5C60]"
|
|
232
|
+
: "bg-[#FF5C60] text-[white]"}` }, count))));
|
|
233
|
+
})))))))),
|
|
162
234
|
React.createElement("div", { className: "border-t border-[#363c48] my-[8px]" }),
|
|
163
235
|
React.createElement("div", null,
|
|
164
236
|
React.createElement("span", { className: "block w-full text-[14px] bold-text text-[white] mb-[10px]", style: { textAlign: "center" } },
|
|
165
|
-
|
|
166
|
-
|
|
237
|
+
servicesInActiveSlot.length > 0
|
|
238
|
+
? servicesInActiveSlot.length
|
|
239
|
+
: operatorsCompetingCount,
|
|
240
|
+
" ",
|
|
241
|
+
"operadores compitiendo ",
|
|
167
242
|
React.createElement("br", null),
|
|
168
243
|
"por tu compra"),
|
|
169
|
-
React.createElement("div", { className: "flex gap-[8px] text-[white]", style: { width: "100%" } },
|
|
244
|
+
React.createElement("div", { className: "flex gap-[8px] text-[white]", style: { width: "100%" } }, (servicesInActiveSlot.length > 0
|
|
245
|
+
? servicesInActiveSlot.slice(0, 3).map((s) => ({
|
|
246
|
+
logo: s.operator_logo_url,
|
|
247
|
+
name: s.operator_name,
|
|
248
|
+
time: s.departure_time,
|
|
249
|
+
seatsAvailable: `${s.available_seats} disponibles`,
|
|
250
|
+
}))
|
|
251
|
+
: operators).map((op, idx) => (React.createElement("div", { key: idx, className: "flex min-w-0 flex-col items-center justify-center gap-[8px] rounded-[8px]", style: {
|
|
170
252
|
flex: 1,
|
|
171
253
|
minWidth: 0,
|
|
172
254
|
height: "100px",
|
|
@@ -176,7 +258,9 @@ const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut,
|
|
|
176
258
|
} },
|
|
177
259
|
React.createElement("img", { src: op.logo, alt: op.name, onError: (e) => {
|
|
178
260
|
var _a;
|
|
179
|
-
e.currentTarget.src =
|
|
261
|
+
e.currentTarget.src =
|
|
262
|
+
((_a = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.operator_details) === null || _a === void 0 ? void 0 : _a[0]) ||
|
|
263
|
+
"/images/service-list/bus-icon.svg";
|
|
180
264
|
}, className: `h-[24px] max-w-full object-contain ${isSoldOut ? "grayscale" : ""}` }),
|
|
181
265
|
React.createElement("span", { className: "text-[12px] truncate max-w-full text-center " }, op.name),
|
|
182
266
|
React.createElement("span", { className: "text-[11px] whitespace-nowrap" }, op === null || op === void 0 ? void 0 : op.seatsAvailable))))),
|
|
@@ -220,7 +304,7 @@ const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut,
|
|
|
220
304
|
} },
|
|
221
305
|
React.createElement("div", { className: "flex flex-col" },
|
|
222
306
|
React.createElement("span", { className: "text-[18px] font-normal leading-[20px] text-[#9f9f9f] relative", style: { position: "relative" } },
|
|
223
|
-
`$${(
|
|
307
|
+
`$${(displayOriginalPrice * ticketQuantity).toLocaleString()}`,
|
|
224
308
|
React.createElement("span", { style: {
|
|
225
309
|
position: "absolute",
|
|
226
310
|
left: "-2px",
|
|
@@ -231,12 +315,12 @@ const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut,
|
|
|
231
315
|
transform: "rotate(-10deg)",
|
|
232
316
|
transformOrigin: "center",
|
|
233
317
|
} })),
|
|
234
|
-
React.createElement("span", { className: "text-[white] bold-text text-[24px] leading-none mt-[4px]" }, `$${(
|
|
318
|
+
React.createElement("span", { className: "text-[white] bold-text text-[24px] leading-none mt-[4px]" }, `$${(displayFinalPrice * ticketQuantity).toLocaleString()}`)),
|
|
235
319
|
React.createElement("span", { className: "text-[#FF8F45] bold-text text-[22px] leading-tight", style: {
|
|
236
320
|
animation: "pulse-zoom 2s ease-in-out infinite",
|
|
237
321
|
whiteSpace: "nowrap",
|
|
238
322
|
} },
|
|
239
|
-
|
|
323
|
+
displaySavingsPercent,
|
|
240
324
|
"% OFF")),
|
|
241
325
|
React.createElement("button", { type: "button", onClick: onBookButtonPress, className: "flex items-center gap-[6px] px-[20px] py-[10px] rounded-[16px] text-[white] bold-text text-[13px] mt-[10px] justify-center border-none cursor-pointer", style: {
|
|
242
326
|
backgroundColor: "#FF5C60",
|
|
@@ -246,7 +330,7 @@ const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut,
|
|
|
246
330
|
React.createElement(LottiePlayer, { animationData: serviceItem.icons.thunderAnim, width: "16px", height: "16px" }),
|
|
247
331
|
React.createElement("span", { className: "whitespace-nowrap" }, "\u00A1Lo quiero!")),
|
|
248
332
|
React.createElement("div", { className: "flex justify-end mt-[10px]", onClick: onToggleExpand },
|
|
249
|
-
React.createElement("img", { src: (
|
|
333
|
+
React.createElement("img", { src: (_f = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.icons) === null || _f === void 0 ? void 0 : _f.downArrow, alt: "down arrow", className: `transition-transform duration-300 ease-in-out ${isItemExpanded ? "rotate-180" : ""}`, style: {
|
|
250
334
|
width: "14px",
|
|
251
335
|
height: "8px",
|
|
252
336
|
filter: "brightness(0) invert(1)",
|