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,12 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import LottiePlayer from "../../assets/LottiePlayer";
|
|
3
3
|
import commonService from "../../utils/CommonService";
|
|
4
|
-
const TIME_SLOTS = [
|
|
5
|
-
"Entre 07:00 AM y 10:00 AM",
|
|
6
|
-
"Entre 11:00 AM y 14:00 AM",
|
|
7
|
-
"Entre 15:00 PM y 18:00 PM",
|
|
8
|
-
"Entre 19:00 PM y 22:00 PM",
|
|
9
|
-
];
|
|
10
4
|
const HARDCODED_OPERATORS = [
|
|
11
5
|
{
|
|
12
6
|
logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Turbus_logo.svg/320px-Turbus_logo.svg.png",
|
|
@@ -28,7 +22,7 @@ const HARDCODED_OPERATORS = [
|
|
|
28
22
|
},
|
|
29
23
|
];
|
|
30
24
|
const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIcon, cityOrigin, cityDestination, renderIcon, viewersConfig, isFeatureDropDownExpand, onToggleExpand, ticketQuantity = 1, onIncreaseTicketQuantity, onDecreaseTicketQuantity, onBookButtonPress, selectedTimeSlot, onTimeSlotChange, isTimeDropdownOpen, onTimeDropdownToggle, wowDealData = undefined, }) => {
|
|
31
|
-
var _a, _b, _c, _d, _e, _f
|
|
25
|
+
var _a, _b, _c, _d, _e, _f;
|
|
32
26
|
// Use wow_deal services if available, otherwise fall back to serviceItem operators or hardcoded
|
|
33
27
|
const operators = ((_a = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.services) === null || _a === void 0 ? void 0 : _a.length) > 0
|
|
34
28
|
? wowDealData.services.slice(0, 3).map((service) => ({
|
|
@@ -50,6 +44,7 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
50
44
|
const isPostPaymentAssignment = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.is_post_payment_assignment;
|
|
51
45
|
const dealWindowFrom = (wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.deal_window_from) || "07:00";
|
|
52
46
|
const dealWindowTo = (wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.deal_window_to) || "10:00";
|
|
47
|
+
const serviceWindowHours = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.service_window_hours;
|
|
53
48
|
const travelDate = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.travel_date;
|
|
54
49
|
// Calculate countdown seconds from expires_at ISO timestamp
|
|
55
50
|
const getCountdownSeconds = () => {
|
|
@@ -60,24 +55,49 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
60
55
|
const seconds = Math.max(0, Math.floor((expires - now) / 1000));
|
|
61
56
|
return seconds;
|
|
62
57
|
};
|
|
63
|
-
// Generate time
|
|
64
|
-
const
|
|
65
|
-
|
|
58
|
+
// Generate dynamic time slots from deal window + service window hours
|
|
59
|
+
const allTimeSlots = serviceWindowHours
|
|
60
|
+
? commonService.generateTimeSlots(dealWindowFrom, dealWindowTo, serviceWindowHours)
|
|
61
|
+
: [];
|
|
62
|
+
// Filter slots to only those that have at least one service
|
|
63
|
+
const services = (wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.services) || [];
|
|
64
|
+
const availableTimeSlots = allTimeSlots.filter((slot) => services.some((s) => {
|
|
65
|
+
const depMin = commonService.timeToMinutes(s.departure_time);
|
|
66
|
+
return depMin >= slot.start && depMin < slot.end;
|
|
67
|
+
}));
|
|
68
|
+
// Active slot: the one matching selectedTimeSlot label, or the first available
|
|
69
|
+
const activeSlot = availableTimeSlots.find((s) => s.label === selectedTimeSlot) ||
|
|
70
|
+
availableTimeSlots[0];
|
|
71
|
+
// Services that fall within the active slot, sorted by final price ascending
|
|
72
|
+
const servicesInActiveSlot = activeSlot
|
|
73
|
+
? services
|
|
74
|
+
.filter((s) => {
|
|
75
|
+
const depMin = commonService.timeToMinutes(s.departure_time);
|
|
76
|
+
return depMin >= activeSlot.start && depMin < activeSlot.end;
|
|
77
|
+
})
|
|
78
|
+
.sort((a, b) => a.final_price - b.final_price)
|
|
79
|
+
: services;
|
|
80
|
+
// The selected price (final and original) from the cheapest service in the active slot
|
|
81
|
+
const selectedSlotService = servicesInActiveSlot === null || servicesInActiveSlot === void 0 ? void 0 : servicesInActiveSlot[0];
|
|
82
|
+
const displayFinalPrice = selectedSlotService
|
|
83
|
+
? selectedSlotService.final_price
|
|
84
|
+
: finalPrice;
|
|
85
|
+
const displayOriginalPrice = selectedSlotService
|
|
86
|
+
? selectedSlotService.original_price
|
|
87
|
+
: originalPrice;
|
|
88
|
+
const displaySavingsPercent = selectedSlotService && selectedSlotService.original_price
|
|
89
|
+
? Math.round(((selectedSlotService.original_price -
|
|
90
|
+
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}`;
|
|
66
96
|
const isItemExpanded = serviceItem.id === isFeatureDropDownExpand ||
|
|
67
97
|
isFeatureDropDownExpand === true;
|
|
68
98
|
const isThisTimeDropdownOpen = isTimeDropdownOpen === serviceItem.id;
|
|
69
99
|
const canDecreaseTicketQuantity = ticketQuantity > 1;
|
|
70
100
|
const canIncreaseTicketQuantity = ticketQuantity < maxSeatsPerBooking;
|
|
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
101
|
const HOW_IT_WORKS_STEPS = [
|
|
82
102
|
{
|
|
83
103
|
icon: "flexible",
|
|
@@ -143,7 +163,7 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
143
163
|
} },
|
|
144
164
|
React.createElement("span", null,
|
|
145
165
|
"AHORRAS ",
|
|
146
|
-
|
|
166
|
+
displaySavingsPercent,
|
|
147
167
|
"%"))),
|
|
148
168
|
React.createElement("div", { className: "flex items-center" },
|
|
149
169
|
React.createElement("div", { className: "mb-[2px]" },
|
|
@@ -154,7 +174,7 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
154
174
|
animationData: getAnimationIcon("flameAnimation"), width: "18px", height: "18px" })),
|
|
155
175
|
React.createElement("span", { className: "bold-text" }, "Remate"),
|
|
156
176
|
"\u00A0t\u00E9rmina en \u00A0",
|
|
157
|
-
React.createElement("span", { className: "bold-text text-end", ref: (node) => commonService.
|
|
177
|
+
React.createElement("span", { className: "bold-text text-end", ref: (node) => commonService.startDealCountdown(node, getCountdownSeconds()), style: {
|
|
158
178
|
fontVariantNumeric: "tabular-nums",
|
|
159
179
|
display: "inline-block",
|
|
160
180
|
color: "#FF5C60",
|
|
@@ -165,10 +185,10 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
165
185
|
React.createElement("div", { className: "flex flex-col justify-between gap-[20px] mb-[16px] pr-[22px]" },
|
|
166
186
|
React.createElement("div", { className: "flex flex-col gap-[8px]" },
|
|
167
187
|
React.createElement("div", { className: "flex items-center gap-[8px]" },
|
|
168
|
-
React.createElement("img", { src: (
|
|
188
|
+
React.createElement("img", { src: (_c = serviceItem.icons) === null || _c === void 0 ? void 0 : _c.whiteOrigin, alt: "origin", className: `w-[14px] h-[14px] shrink-0 ${isSoldOut ? "grayscale" : ""}` }),
|
|
169
189
|
React.createElement("span", { className: "text-[13px] bold-text" }, cityOrigin === null || cityOrigin === void 0 ? void 0 : cityOrigin.label.split(",")[0])),
|
|
170
190
|
React.createElement("div", { className: "flex items-center gap-[8px]" },
|
|
171
|
-
React.createElement("img", { src: (
|
|
191
|
+
React.createElement("img", { src: (_d = serviceItem.icons) === null || _d === void 0 ? void 0 : _d.whiteDestination, alt: "destination", className: `w-[14px] h-[14px] shrink-0 ${isSoldOut ? "grayscale" : ""}`, style: { opacity: isSoldOut ? 0.5 : 1 } }),
|
|
172
192
|
React.createElement("span", { className: "text-[13px] bold-text" }, cityDestination === null || cityDestination === void 0 ? void 0 : cityDestination.label.split(",")[0]))),
|
|
173
193
|
React.createElement("div", { className: "flex flex-col gap-[10px]" },
|
|
174
194
|
React.createElement("div", { className: "text-[12px] bold-text" }, travelDate
|
|
@@ -178,7 +198,50 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
178
198
|
month: "long",
|
|
179
199
|
})
|
|
180
200
|
: "Viernes 23 de mayo"),
|
|
181
|
-
React.createElement("div", { className: "
|
|
201
|
+
React.createElement("div", { className: "kupos-time-dd relative", tabIndex: 0, onBlur: (e) => {
|
|
202
|
+
if (!e.currentTarget.contains(e.relatedTarget)) {
|
|
203
|
+
onTimeDropdownToggle === null || onTimeDropdownToggle === void 0 ? void 0 : onTimeDropdownToggle(null);
|
|
204
|
+
}
|
|
205
|
+
}, style: { outline: "none" } },
|
|
206
|
+
React.createElement("button", { type: "button", onClick: () => onTimeDropdownToggle === null || onTimeDropdownToggle === void 0 ? void 0 : onTimeDropdownToggle(isThisTimeDropdownOpen ? null : serviceItem.id), className: "flex whitespace-nowrap cursor-pointer select-none items-center gap-[6px] border-none bg-transparent p-0 bold-text text-[12px] text-[white]" },
|
|
207
|
+
React.createElement("span", null, departureRange),
|
|
208
|
+
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: {
|
|
209
|
+
width: "12px",
|
|
210
|
+
height: "8px",
|
|
211
|
+
filter: "brightness(0) invert(1)",
|
|
212
|
+
} })),
|
|
213
|
+
isThisTimeDropdownOpen && (React.createElement(React.Fragment, null,
|
|
214
|
+
React.createElement("div", { className: "absolute left-0 top-[calc(100%+10px)] hover:z-[200]", style: {
|
|
215
|
+
zIndex: 20,
|
|
216
|
+
backgroundColor: "#fff",
|
|
217
|
+
borderRadius: "14px",
|
|
218
|
+
minWidth: "190px",
|
|
219
|
+
boxShadow: "0 8px 32px rgba(0,0,0,0.28)",
|
|
220
|
+
overflow: "hidden",
|
|
221
|
+
padding: "6px 0",
|
|
222
|
+
} }, availableTimeSlots.map((slot) => {
|
|
223
|
+
const isActive = slot.label === selectedTimeSlot ||
|
|
224
|
+
slot === activeSlot;
|
|
225
|
+
// Count services in this slot
|
|
226
|
+
const count = services.filter((s) => {
|
|
227
|
+
const depMin = commonService.timeToMinutes(s.departure_time);
|
|
228
|
+
return depMin >= slot.start && depMin < slot.end;
|
|
229
|
+
}).length;
|
|
230
|
+
return (React.createElement("button", { key: slot.label, type: "button", onClick: () => {
|
|
231
|
+
onTimeSlotChange === null || onTimeSlotChange === void 0 ? void 0 : onTimeSlotChange(slot.label);
|
|
232
|
+
onTimeDropdownToggle === null || onTimeDropdownToggle === void 0 ? void 0 : onTimeDropdownToggle(null);
|
|
233
|
+
const slotServices = services.filter((s) => {
|
|
234
|
+
const depMin = commonService.timeToMinutes(s.departure_time);
|
|
235
|
+
return (depMin >= slot.start && depMin < slot.end);
|
|
236
|
+
});
|
|
237
|
+
console.log("Selected slot label:", slot.label);
|
|
238
|
+
console.log("Services in selected slot:", slotServices);
|
|
239
|
+
}, 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]"}` },
|
|
240
|
+
React.createElement("span", null, slot.label),
|
|
241
|
+
count > 0 && (React.createElement("span", { className: `text-[11px] rounded-full px-[6px] py-[2px] font-bold ${isActive
|
|
242
|
+
? "bg-white text-[#FF5C60]"
|
|
243
|
+
: "bg-[#FF5C60] text-white"}` }, count))));
|
|
244
|
+
})))))),
|
|
182
245
|
React.createElement("div", { className: "flex flex-col items-start gap-[10px] text-[12px] " },
|
|
183
246
|
React.createElement("div", { className: "flex items-justify gap-[8px]" },
|
|
184
247
|
renderIcon("sheildIcon", "16px"),
|
|
@@ -193,12 +256,25 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
193
256
|
React.createElement("div", { className: "min-w-0 px-[22px] flex flex-col items-center justify-between gap-[16px] py-[2px] border-r border-[#363c48] border-l border-[#363c48]" },
|
|
194
257
|
React.createElement("div", { className: "text-center" },
|
|
195
258
|
React.createElement("div", { className: "bold-text text-[13px]" },
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
259
|
+
servicesInActiveSlot.length > 0
|
|
260
|
+
? servicesInActiveSlot.length
|
|
261
|
+
: operatorsCompetingCount,
|
|
262
|
+
" ",
|
|
263
|
+
"operadores compitiendo por tu compra")),
|
|
264
|
+
React.createElement("div", { className: "grid w-full items-stretch gap-[14px]", style: {
|
|
265
|
+
gridTemplateColumns: `repeat(${Math.min(servicesInActiveSlot.length || operators.length, 3)}, 1fr)`,
|
|
266
|
+
} }, (servicesInActiveSlot.length > 0
|
|
267
|
+
? servicesInActiveSlot.slice(0, 3).map((s) => ({
|
|
268
|
+
logo: s.operator_logo_url,
|
|
269
|
+
name: s.operator_name,
|
|
270
|
+
time: s.departure_time,
|
|
271
|
+
seatsAvailable: `${s.available_seats} disponibles`,
|
|
272
|
+
}))
|
|
273
|
+
: 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: {
|
|
274
|
+
// border: "1px solid #363c48",
|
|
275
|
+
// backgroundColor: "#fff",
|
|
200
276
|
border: "1px solid #363c48",
|
|
201
|
-
backgroundColor: "#
|
|
277
|
+
backgroundColor: "#1a202e",
|
|
202
278
|
padding: "14px 10px",
|
|
203
279
|
} },
|
|
204
280
|
React.createElement("img", { src: op.logo, alt: op.name, onError: (e) => {
|
|
@@ -207,10 +283,10 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
207
283
|
((_a = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.operator_details) === null || _a === void 0 ? void 0 : _a[0]) ||
|
|
208
284
|
"/images/service-list/bus-icon.svg";
|
|
209
285
|
}, className: `h-[24px] max-w-full object-contain ${isSoldOut ? "grayscale" : ""}` }),
|
|
210
|
-
React.createElement("span", { className: "text-[11px] truncate max-w-full text-center text-[
|
|
286
|
+
React.createElement("span", { className: "text-[11px] truncate max-w-full text-center text-[white] whitespace-nowrap " }, op.name),
|
|
211
287
|
React.createElement("div", { className: "bg-[#FF8F45] text-white text-[12px] font-bold px-[10px] py-[4px] rounded-[4px] bold-text whitespace-nowrap" },
|
|
212
288
|
React.createElement("span", null, op === null || op === void 0 ? void 0 : op.time)),
|
|
213
|
-
React.createElement("span", { className: "text-[10px] mt-[6px] text-[
|
|
289
|
+
React.createElement("span", { className: "text-[10px] mt-[6px] text-[white]" }, op === null || op === void 0 ? void 0 : op.seatsAvailable))))),
|
|
214
290
|
React.createElement("div", { className: "flex w-full items-center justify-center gap-[6px] text-[12px] rounded-full", style: {
|
|
215
291
|
padding: "8px 14px",
|
|
216
292
|
marginBottom: "6px",
|
|
@@ -244,10 +320,10 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
244
320
|
animation: "pulse-zoom 2s ease-in-out infinite",
|
|
245
321
|
whiteSpace: "nowrap",
|
|
246
322
|
} },
|
|
247
|
-
|
|
323
|
+
displaySavingsPercent,
|
|
248
324
|
"% OFF"),
|
|
249
325
|
React.createElement("span", { className: "text-[13.33px] font-normal leading-[20px] text-[#9f9f9f] relative", style: { position: "relative" } },
|
|
250
|
-
`$${(
|
|
326
|
+
`$${(displayOriginalPrice * ticketQuantity).toLocaleString()}`,
|
|
251
327
|
React.createElement("span", { style: {
|
|
252
328
|
position: "absolute",
|
|
253
329
|
left: "-2px",
|
|
@@ -258,7 +334,7 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
258
334
|
transform: "rotate(-10deg)",
|
|
259
335
|
transformOrigin: "center",
|
|
260
336
|
} })),
|
|
261
|
-
React.createElement("span", { className: "text-white bold-text text-[28px] leading-none" }, `$${(
|
|
337
|
+
React.createElement("span", { className: "text-white bold-text text-[28px] leading-none" }, `$${(displayFinalPrice * ticketQuantity).toLocaleString()}`)),
|
|
262
338
|
React.createElement("div", { className: "mt-[4px] flex flex-col items-center gap-[8px]" },
|
|
263
339
|
React.createElement("span", { className: "text-[12px] text-white" }, "\u00BFCu\u00E1ntos pasajes quieres?"),
|
|
264
340
|
React.createElement("div", { className: "flex w-full items-center justify-between rounded-[16px] ", style: {
|
|
@@ -288,7 +364,7 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, isSoldOut, getAnimationIc
|
|
|
288
364
|
animationData: getAnimationIcon("thunderAnimation"), width: "16px", height: "16px" }),
|
|
289
365
|
React.createElement("span", { className: "whitespace-nowrap" }, "\u00A1Lo quiero!"))),
|
|
290
366
|
React.createElement("div", { className: `absolute bottom-[11px] right-[18px] cursor-pointer transition-transform duration-300 ease-in-out ${isItemExpanded ? "rotate-180" : ""}`, onClick: onToggleExpand },
|
|
291
|
-
React.createElement("img", { src: (
|
|
367
|
+
React.createElement("img", { src: (_f = serviceItem.icons) === null || _f === void 0 ? void 0 : _f.downArrow, alt: "down arrow", style: {
|
|
292
368
|
width: "14px",
|
|
293
369
|
height: "8px",
|
|
294
370
|
filter: "brightness(0) invert(1)",
|
|
@@ -3,8 +3,6 @@ interface SeatType {
|
|
|
3
3
|
label: string;
|
|
4
4
|
fare: number;
|
|
5
5
|
key: any;
|
|
6
|
-
apiSeatType?: string;
|
|
7
|
-
api_seat_type?: string;
|
|
8
6
|
}
|
|
9
7
|
interface SeatSectionProps {
|
|
10
8
|
seatTypes: SeatType[];
|
|
@@ -18,11 +16,7 @@ interface SeatSectionProps {
|
|
|
18
16
|
serviceItem?: any;
|
|
19
17
|
renderIcon?: (iconKey: string, size?: string) => React.ReactNode;
|
|
20
18
|
discountSeatPriceColor?: string;
|
|
21
|
-
isTrain?: boolean;
|
|
22
|
-
selectedSeatKey?: any;
|
|
23
|
-
onSeatSelect?: (key: any, price: number, seatKey: string, apiSeatType?: string) => void;
|
|
24
|
-
topLabelColor?: string;
|
|
25
19
|
tooltipColor?: string;
|
|
26
20
|
}
|
|
27
|
-
declare function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats,
|
|
21
|
+
declare function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, isPeru, serviceItem, renderIcon, dpSeatColor, discountSeatPriceColor, tooltipColor, }: SeatSectionProps): React.ReactElement;
|
|
28
22
|
export default SeatSection;
|
|
@@ -8,13 +8,11 @@ function getAllSeatTypes(seatTypes) {
|
|
|
8
8
|
let seatTypesWithPrices = seatTypes.filter(Boolean).map((val) => ({
|
|
9
9
|
label: val === null || val === void 0 ? void 0 : val.label,
|
|
10
10
|
price: val === null || val === void 0 ? void 0 : val.fare,
|
|
11
|
-
key: val === null || val === void 0 ? void 0 : val.key,
|
|
12
|
-
apiSeatType: (val === null || val === void 0 ? void 0 : val.apiSeatType) || (val === null || val === void 0 ? void 0 : val.api_seat_type),
|
|
13
11
|
}));
|
|
14
12
|
seatTypesWithPrices.sort((a, b) => a.price - b.price);
|
|
15
13
|
return seatTypesWithPrices;
|
|
16
14
|
}
|
|
17
|
-
function getSortedSeatTypes(seatTypes
|
|
15
|
+
function getSortedSeatTypes(seatTypes) {
|
|
18
16
|
if (!(seatTypes === null || seatTypes === void 0 ? void 0 : seatTypes.length)) {
|
|
19
17
|
return [{ label: "Salon cama", price: 0 }];
|
|
20
18
|
}
|
|
@@ -23,9 +21,7 @@ function getSortedSeatTypes(seatTypes, isTrain) {
|
|
|
23
21
|
if (premiumIndex >= 3) {
|
|
24
22
|
seatTypesWithPrices[2] = seatTypesWithPrices[premiumIndex];
|
|
25
23
|
}
|
|
26
|
-
|
|
27
|
-
seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
|
|
28
|
-
}
|
|
24
|
+
seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
|
|
29
25
|
const seenPrices = new Set();
|
|
30
26
|
seatTypesWithPrices = seatTypesWithPrices.filter((seat) => {
|
|
31
27
|
if (seenPrices.has(seat.price))
|
|
@@ -58,10 +54,11 @@ function getUniqueSeats(seatTypes) {
|
|
|
58
54
|
function getNumberOfSeats(seatTypes) {
|
|
59
55
|
return seatTypes.filter((val) => !SEAT_EXCEPTIONS.includes(val.label)).length;
|
|
60
56
|
}
|
|
61
|
-
function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats,
|
|
57
|
+
function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, isPeru, serviceItem, renderIcon, dpSeatColor, discountSeatPriceColor, tooltipColor, }) {
|
|
62
58
|
var _a;
|
|
63
59
|
const uniqueSeats = getUniqueSeats(seatTypes);
|
|
64
|
-
const sortedSeatTypes = getSortedSeatTypes(seatTypes
|
|
60
|
+
const sortedSeatTypes = getSortedSeatTypes(seatTypes);
|
|
61
|
+
console.log("🚀 ~ SeatSection ~ sortedSeatTypes:", sortedSeatTypes);
|
|
65
62
|
const numberOfSeats = getNumberOfSeats(seatTypes);
|
|
66
63
|
const isCentered = numberOfSeats < 2 || removeDuplicateSeats;
|
|
67
64
|
const formatPrice = (price) => availableSeats <= 0
|
|
@@ -69,36 +66,11 @@ function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currenc
|
|
|
69
66
|
: CommonService.currency(price, currencySign);
|
|
70
67
|
const renderSeatNames = () => {
|
|
71
68
|
const seats = removeDuplicateSeats ? uniqueSeats : sortedSeatTypes;
|
|
72
|
-
return seats.map((val, key) => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
: undefined },
|
|
78
|
-
isTrain && (React.createElement("div", { style: {
|
|
79
|
-
border: `1px solid ${val.label === selectedSeatKey ? topLabelColor : "#ccc"}`,
|
|
80
|
-
borderRadius: "50%",
|
|
81
|
-
width: "14px",
|
|
82
|
-
height: "14px",
|
|
83
|
-
minWidth: "14px",
|
|
84
|
-
marginRight: "10px",
|
|
85
|
-
display: "flex",
|
|
86
|
-
alignItems: "center",
|
|
87
|
-
justifyContent: "center",
|
|
88
|
-
} }, val.label === selectedSeatKey && (React.createElement("div", { style: {
|
|
89
|
-
backgroundColor: topLabelColor,
|
|
90
|
-
borderRadius: "50%",
|
|
91
|
-
width: "7px",
|
|
92
|
-
height: "7px",
|
|
93
|
-
} })))),
|
|
94
|
-
React.createElement("span", { key: key, className: `flex items-center justify-between text-[13.33px] ${isSoldOut ? "text-[#c0c0c0]" : ""}` }, typeof val.label === "string" || typeof val.label === "number"
|
|
95
|
-
? removeDuplicateSeats && isPeru
|
|
96
|
-
? CommonService.truncateSeatLabel(val.label)
|
|
97
|
-
: isTrain
|
|
98
|
-
? CommonService.truncateSeatLabel(CommonService.capitalize(String(val.label)), 8)
|
|
99
|
-
: val.label
|
|
100
|
-
: null)));
|
|
101
|
-
});
|
|
69
|
+
return seats.map((val, key) => SEAT_EXCEPTIONS.includes(val.label) ? null : (React.createElement("span", { key: key, className: `flex items-center justify-between text-[13.33px] ${isSoldOut ? "text-[#c0c0c0]" : ""}` }, typeof val.label === "string" || typeof val.label === "number"
|
|
70
|
+
? removeDuplicateSeats && isPeru
|
|
71
|
+
? CommonService.truncateSeatLabel(val.label)
|
|
72
|
+
: val.label
|
|
73
|
+
: null)));
|
|
102
74
|
};
|
|
103
75
|
const renderSeatPrices = () => {
|
|
104
76
|
if (isPeru) {
|
|
@@ -145,13 +117,20 @@ function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currenc
|
|
|
145
117
|
})();
|
|
146
118
|
const renderLabels = () => {
|
|
147
119
|
if (isPeru) {
|
|
120
|
+
const seats = removeDuplicateSeats ? uniqueSeats : sortedSeatTypes;
|
|
121
|
+
const filteredSeats = seats.filter((s) => !SEAT_EXCEPTIONS.includes(s.label));
|
|
122
|
+
const seatLabel = filteredSeats.length > 0
|
|
123
|
+
? removeDuplicateSeats
|
|
124
|
+
? CommonService.truncateSeatLabel(filteredSeats[0].label)
|
|
125
|
+
: filteredSeats[0].label
|
|
126
|
+
: null;
|
|
127
|
+
const operatorServiceName = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.operator_service_name) === "MovilBus";
|
|
128
|
+
const bottomLabel = operatorServiceName || "Desde";
|
|
148
129
|
return (React.createElement(React.Fragment, null,
|
|
149
130
|
hasDiscount && (React.createElement("span", { className: "text-[13.33px]", style: {
|
|
150
131
|
color: "#999",
|
|
151
|
-
// position: "relative",
|
|
152
|
-
// bottom: numberOfSeats ? "10px" : "",
|
|
153
132
|
} }, "Antes")),
|
|
154
|
-
React.createElement("span", { className: "text-[13.33px]" }, "Desde")));
|
|
133
|
+
React.createElement("span", { className: "text-[13.33px] flex flex-col" }, operatorServiceName ? (React.createElement("span", { className: "text-[13.33px]" }, seatLabel)) : (React.createElement("span", { className: "text-[13.33px]" }, "Desde")))));
|
|
155
134
|
}
|
|
156
135
|
return renderSeatNames();
|
|
157
136
|
};
|
|
@@ -22,7 +22,6 @@ interface DateTimeSectionMobileProps {
|
|
|
22
22
|
tooltipBgColor?: string;
|
|
23
23
|
showLastSeats?: boolean;
|
|
24
24
|
discountSeatPriceColor?: string;
|
|
25
|
-
isTrain?: boolean;
|
|
26
25
|
}
|
|
27
|
-
declare function DateTimeSectionMobile({ onBookButtonPress, isCiva, isSoldOut, isLinatal, isPeru, orignLabel, destinationLabel, originIcon, destinationIcon, travelDate, arrivalDate, depTime, arrTime, seatTypes, seatPriceColor, currencySign, availableSeats, removeDuplicateSeats, serviceItem, tooltipBgColor, showLastSeats, discountSeatPriceColor,
|
|
26
|
+
declare function DateTimeSectionMobile({ onBookButtonPress, isCiva, isSoldOut, isLinatal, isPeru, orignLabel, destinationLabel, originIcon, destinationIcon, travelDate, arrivalDate, depTime, arrTime, seatTypes, seatPriceColor, currencySign, availableSeats, removeDuplicateSeats, serviceItem, tooltipBgColor, showLastSeats, discountSeatPriceColor, }: DateTimeSectionMobileProps): React.ReactElement;
|
|
28
27
|
export default DateTimeSectionMobile;
|
|
@@ -23,10 +23,8 @@ const getCleanedDepTime = (raw) => {
|
|
|
23
23
|
};
|
|
24
24
|
const TimeRow = ({ label, icon, alt, date, timeContent, isSoldOut, }) => {
|
|
25
25
|
const formattedDate = DateService.getServiceItemDate(date);
|
|
26
|
-
const dotPositionClass = formattedDate.includes("dom")
|
|
27
|
-
|
|
28
|
-
: "";
|
|
29
|
-
return (React.createElement("div", { className: `flex items-center min-[420]:text-[13px] text-[12px] justify-between ${isSoldOut ? "text-[#c0c0c0]" : ""}` },
|
|
26
|
+
const dotPositionClass = formattedDate.includes("dom") ? "max-[399px]:left-[53%]" : "";
|
|
27
|
+
return React.createElement("div", { className: `flex items-center min-[420]:text-[13px] text-[12px] justify-between ${isSoldOut ? "text-[#c0c0c0]" : ""}` },
|
|
30
28
|
React.createElement("div", { className: "flex items-center", style: { flex: 1 } },
|
|
31
29
|
React.createElement("div", null,
|
|
32
30
|
" ",
|
|
@@ -35,9 +33,9 @@ const TimeRow = ({ label, icon, alt, date, timeContent, isSoldOut, }) => {
|
|
|
35
33
|
React.createElement("div", { className: "flex items-center relative capitalize justify-between", style: { flex: 1 } },
|
|
36
34
|
React.createElement("span", { className: "cursor-pointer black-text" }, formattedDate),
|
|
37
35
|
React.createElement("div", { className: `absolute left-[50%] ${dotPositionClass}` }, "\u2022"),
|
|
38
|
-
React.createElement("div", { className: "font-[900] relative black-text" }, timeContent))))
|
|
36
|
+
React.createElement("div", { className: "font-[900] relative black-text" }, timeContent))));
|
|
39
37
|
};
|
|
40
|
-
function DateTimeSectionMobile({ onBookButtonPress, isCiva, isSoldOut, isLinatal, isPeru, orignLabel, destinationLabel, originIcon, destinationIcon, travelDate, arrivalDate, depTime, arrTime, seatTypes, seatPriceColor, currencySign, availableSeats, removeDuplicateSeats, serviceItem, tooltipBgColor, showLastSeats, discountSeatPriceColor,
|
|
38
|
+
function DateTimeSectionMobile({ onBookButtonPress, isCiva, isSoldOut, isLinatal, isPeru, orignLabel, destinationLabel, originIcon, destinationIcon, travelDate, arrivalDate, depTime, arrTime, seatTypes, seatPriceColor, currencySign, availableSeats, removeDuplicateSeats, serviceItem, tooltipBgColor, showLastSeats, discountSeatPriceColor, }) {
|
|
41
39
|
const { cleaned: cleanedDepTime, hasAM, hasPM } = getCleanedDepTime(depTime);
|
|
42
40
|
const depTimeContent = isLinatal ? (React.createElement("div", null,
|
|
43
41
|
React.createElement("span", null,
|
|
@@ -49,11 +47,7 @@ function DateTimeSectionMobile({ onBookButtonPress, isCiva, isSoldOut, isLinatal
|
|
|
49
47
|
? null
|
|
50
48
|
: DateService.ampmOnly(depTime)))) : (DateService.formatTime(depTime));
|
|
51
49
|
return (React.createElement("div", { className: "flex justify-between gap-[5px] w-full", onClick: onBookButtonPress },
|
|
52
|
-
React.createElement("div", { className:
|
|
53
|
-
justifyContent: isCiva && "center",
|
|
54
|
-
minHeight: isTrain ? undefined : "2.5rem",
|
|
55
|
-
alignSelf: isTrain ? "stretch" : undefined,
|
|
56
|
-
} },
|
|
50
|
+
React.createElement("div", { className: "min-h-[2.5rem] flex flex-col justify-between gap-[4px] w-[50%] ", style: { justifyContent: isCiva && "center" } },
|
|
57
51
|
React.createElement(TimeRow, { label: orignLabel, icon: originIcon, alt: "origin", date: travelDate, timeContent: depTimeContent, isSoldOut: isSoldOut }),
|
|
58
52
|
isCiva ? null : (React.createElement(TimeRow, { label: destinationLabel, icon: destinationIcon, alt: "destination", date: arrivalDate, timeContent: DateService.formatTime(arrTime), isSoldOut: isSoldOut }))),
|
|
59
53
|
React.createElement("div", { style: {
|
|
@@ -62,6 +56,6 @@ function DateTimeSectionMobile({ onBookButtonPress, isCiva, isSoldOut, isLinatal
|
|
|
62
56
|
backgroundColor: "#ccc",
|
|
63
57
|
margin: "auto",
|
|
64
58
|
} }),
|
|
65
|
-
React.createElement(SeatSectionMobile, { seatTypes: seatTypes, isSoldOut: isSoldOut, isPeru: isPeru, seatPriceColor: seatPriceColor, currencySign: currencySign, availableSeats: availableSeats, removeDuplicateSeats: removeDuplicateSeats, serviceItem: serviceItem, tooltipBgColor: tooltipBgColor, showLastSeats: showLastSeats, discountSeatPriceColor: discountSeatPriceColor
|
|
59
|
+
React.createElement(SeatSectionMobile, { seatTypes: seatTypes, isSoldOut: isSoldOut, isPeru: isPeru, seatPriceColor: seatPriceColor, currencySign: currencySign, availableSeats: availableSeats, removeDuplicateSeats: removeDuplicateSeats, serviceItem: serviceItem, tooltipBgColor: tooltipBgColor, showLastSeats: showLastSeats, discountSeatPriceColor: discountSeatPriceColor })));
|
|
66
60
|
}
|
|
67
61
|
export default DateTimeSectionMobile;
|
|
@@ -16,7 +16,6 @@ interface SeatSectionMobileProps {
|
|
|
16
16
|
tooltipBgColor?: string;
|
|
17
17
|
showLastSeats?: boolean;
|
|
18
18
|
discountSeatPriceColor?: string;
|
|
19
|
-
isTrain?: boolean;
|
|
20
19
|
}
|
|
21
|
-
declare function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPriceColor, currencySign, availableSeats, removeDuplicateSeats, serviceItem, tooltipBgColor, showLastSeats, discountSeatPriceColor,
|
|
20
|
+
declare function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPriceColor, currencySign, availableSeats, removeDuplicateSeats, serviceItem, tooltipBgColor, showLastSeats, discountSeatPriceColor, }: SeatSectionMobileProps): React.ReactElement;
|
|
22
21
|
export default SeatSectionMobile;
|
|
@@ -11,7 +11,7 @@ const EXCEPTIONS = [
|
|
|
11
11
|
"blanco",
|
|
12
12
|
"asiento_mascota",
|
|
13
13
|
];
|
|
14
|
-
const SeatRow = ({ type, index, displayLabel, fare, isSoldOut, seatPriceColor, hasMultipleTypes, textSize,
|
|
14
|
+
const SeatRow = ({ type, index, displayLabel, fare, isSoldOut, seatPriceColor, hasMultipleTypes, textSize, }) => {
|
|
15
15
|
if (EXCEPTIONS.includes(type.label))
|
|
16
16
|
return null;
|
|
17
17
|
const rowClass = hasMultipleTypes
|
|
@@ -20,9 +20,7 @@ const SeatRow = ({ type, index, displayLabel, fare, isSoldOut, seatPriceColor, h
|
|
|
20
20
|
const labelColor = isSoldOut ? "#bbb" : "#464647";
|
|
21
21
|
const priceColor = isSoldOut ? "#bbb" : seatPriceColor;
|
|
22
22
|
return (React.createElement("div", { className: rowClass, key: index },
|
|
23
|
-
React.createElement("span", { className: `min-[420]:text-[13px] ${textSize} `, style: { color: labelColor } },
|
|
24
|
-
? commonService.truncateSeatLabel(commonService.capitalize(displayLabel), 8)
|
|
25
|
-
: displayLabel),
|
|
23
|
+
React.createElement("span", { className: `min-[420]:text-[13px] ${textSize} `, style: { color: labelColor } }, displayLabel),
|
|
26
24
|
React.createElement("span", { className: `min-[420]:text-[13px] ${textSize} bold-text`, style: { color: priceColor } }, fare)));
|
|
27
25
|
};
|
|
28
26
|
const getFilteredSeats = (item) => {
|
|
@@ -44,8 +42,8 @@ const getUniqueSeats = (data, limit) => {
|
|
|
44
42
|
.sort((a, b) => a.fare - b.fare)
|
|
45
43
|
.slice(0, limit);
|
|
46
44
|
};
|
|
47
|
-
function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPriceColor, currencySign, availableSeats, removeDuplicateSeats, serviceItem, tooltipBgColor, showLastSeats, discountSeatPriceColor,
|
|
48
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
45
|
+
function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPriceColor, currencySign, availableSeats, removeDuplicateSeats, serviceItem, tooltipBgColor, showLastSeats, discountSeatPriceColor, }) {
|
|
46
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
49
47
|
const hasMultipleTypes = ((_a = seatTypesData === null || seatTypesData === void 0 ? void 0 : seatTypesData.length) !== null && _a !== void 0 ? _a : 0) > 2;
|
|
50
48
|
const getFare = (fare) => {
|
|
51
49
|
if (removeDuplicateSeats && availableSeats <= 0 && !isPeru) {
|
|
@@ -67,12 +65,20 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
|
|
|
67
65
|
return null;
|
|
68
66
|
const priceColor = isSoldOut ? "#bbb" : seatPriceColor;
|
|
69
67
|
const { originalPrice, discountedPrice } = commonService.calculateDiscountedPrice(lowestFare, serviceItem);
|
|
68
|
+
const isMovilBus = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.operator_service_name) === "MovilBus";
|
|
69
|
+
const uniqueSeats = getUniqueSeats(seatTypesData !== null && seatTypesData !== void 0 ? seatTypesData : [], 1);
|
|
70
|
+
const seatLabel = uniqueSeats.length > 0
|
|
71
|
+
? commonService.truncateSeatLabel(uniqueSeats[0].label)
|
|
72
|
+
: null;
|
|
73
|
+
const bottomLabel = isMovilBus ? seatLabel || "Desde" : "Desde";
|
|
70
74
|
return (React.createElement(React.Fragment, null,
|
|
71
75
|
originalPrice !== discountedPrice && (React.createElement("div", { className: "w-[100%] flex flex-row justify-between items-center" },
|
|
72
76
|
React.createElement("span", { className: "min-[420]:text-[13px] text-[12px]", style: { color: "#bbb" } }, "Antes"),
|
|
73
77
|
React.createElement("span", { className: "min-[420]:text-[13px] text-[12px] line-through", style: { color: "#bbb" } }, commonService.currency(originalPrice, currencySign)))),
|
|
74
78
|
React.createElement("div", { className: "w-[100%] flex flex-row justify-between items-center" },
|
|
75
|
-
React.createElement("span", { className: "min-[420]:text-[13px] text-[12px] bold-text", style: { color: isSoldOut ? "#bbb" : "#464647" } }, "
|
|
79
|
+
React.createElement("span", { className: "min-[420]:text-[13px] text-[12px] bold-text", style: { color: isSoldOut ? "#bbb" : "#464647" } }, (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.operator_service_name) === "MovilBus"
|
|
80
|
+
? seatLabel
|
|
81
|
+
: "Desde"),
|
|
76
82
|
React.createElement("span", { className: "min-[420]:text-[13px] text-[12px] bold-text", style: { color: priceColor } }, commonService.currency(discountedPrice, currencySign)))));
|
|
77
83
|
};
|
|
78
84
|
const renderDpSeats = () => {
|
|
@@ -103,24 +109,19 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
|
|
|
103
109
|
React.createElement("span", { className: "min-[420]:text-[13px] text-[12px] text-[#464647]", style: { opacity: isSoldOut ? 0.5 : 1 } }, "Agotado"))) : null));
|
|
104
110
|
};
|
|
105
111
|
const renderSeats = () => {
|
|
106
|
-
var _a, _b;
|
|
112
|
+
var _a, _b, _c;
|
|
107
113
|
if (isPeru) {
|
|
108
114
|
return renderPeruSeats();
|
|
109
115
|
}
|
|
110
116
|
if (removeDuplicateSeats) {
|
|
111
117
|
const uniqueSeats = getUniqueSeats(seatTypesData, 3);
|
|
112
|
-
return uniqueSeats.map((type, i) => (React.createElement(SeatRow, { key: i, type: type, index: i, displayLabel: commonService.truncateSeatLabel(type.label), fare: getFare(type.fare), isSoldOut: isSoldOut, seatPriceColor: seatPriceColor, hasMultipleTypes: hasMultipleTypes, textSize: "text-[11px]"
|
|
118
|
+
return uniqueSeats.map((type, i) => (React.createElement(SeatRow, { key: i, type: type, index: i, displayLabel: commonService.truncateSeatLabel(type.label), fare: getFare(type.fare), isSoldOut: isSoldOut, seatPriceColor: seatPriceColor, hasMultipleTypes: hasMultipleTypes, textSize: "text-[11px]" })));
|
|
113
119
|
}
|
|
114
|
-
|
|
115
|
-
return (_b = (isTrain ? filteredSeats : filteredSeats === null || filteredSeats === void 0 ? void 0 : filteredSeats.slice(0, 2))) === null || _b === void 0 ? void 0 : _b.map((type, i) => (React.createElement(SeatRow, { key: i, type: type, index: i, displayLabel: type.label, fare: getFare(type.fare), isSoldOut: isSoldOut, seatPriceColor: seatPriceColor, hasMultipleTypes: hasMultipleTypes, textSize: "text-[12px]", isTrain: isTrain })));
|
|
120
|
+
return (_c = (_b = (_a = seatTypesData === null || seatTypesData === void 0 ? void 0 : seatTypesData.filter((item) => getFilteredSeats(item.label))) === null || _a === void 0 ? void 0 : _a.sort((a, b) => a.fare - b.fare)) === null || _b === void 0 ? void 0 : _b.slice(0, 2)) === null || _c === void 0 ? void 0 : _c.map((type, i) => (React.createElement(SeatRow, { key: i, type: type, index: i, displayLabel: type.label, fare: getFare(type.fare), isSoldOut: isSoldOut, seatPriceColor: seatPriceColor, hasMultipleTypes: hasMultipleTypes, textSize: "text-[12px]" })));
|
|
116
121
|
};
|
|
117
122
|
const seats = removeDuplicateSeats
|
|
118
123
|
? getUniqueSeats(seatTypesData, 3)
|
|
119
|
-
: (() =>
|
|
120
|
-
var _a;
|
|
121
|
-
const filtered = (_a = seatTypesData === null || seatTypesData === void 0 ? void 0 : seatTypesData.filter((item) => getFilteredSeats(item.label))) === null || _a === void 0 ? void 0 : _a.sort((a, b) => a.fare - b.fare);
|
|
122
|
-
return isTrain ? filtered : filtered === null || filtered === void 0 ? void 0 : filtered.slice(0, 2);
|
|
123
|
-
})();
|
|
124
|
+
: (_c = (_b = seatTypesData === null || seatTypesData === void 0 ? void 0 : seatTypesData.filter((item) => getFilteredSeats(item.label))) === null || _b === void 0 ? void 0 : _b.sort((a, b) => a.fare - b.fare)) === null || _c === void 0 ? void 0 : _c.slice(0, 2);
|
|
124
125
|
const discountedSeats = seats === null || seats === void 0 ? void 0 : seats.map((seat) => (Object.assign(Object.assign({}, seat), commonService.calculateDiscountedPrice(seat.fare, serviceItem))));
|
|
125
126
|
const peruLowestFare = isPeru ? getLowestFare() : null;
|
|
126
127
|
const peruDiscountCalc = isPeru && peruLowestFare != null
|
|
@@ -131,7 +132,7 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
|
|
|
131
132
|
peruDiscountCalc.originalPrice !== peruDiscountCalc.discountedPrice
|
|
132
133
|
: discountedSeats === null || discountedSeats === void 0 ? void 0 : discountedSeats.some((s) => s.originalPrice !== s.discountedPrice);
|
|
133
134
|
const discountSeat = isPeru && peruDiscountCalc
|
|
134
|
-
? Object.assign({ label: "", fare: peruLowestFare }, peruDiscountCalc) : (
|
|
135
|
+
? Object.assign({ label: "", fare: peruLowestFare }, peruDiscountCalc) : (_d = discountedSeats === null || discountedSeats === void 0 ? void 0 : discountedSeats.filter((seat) => !EXCEPTIONS.includes(seat.label))) === null || _d === void 0 ? void 0 : _d.sort((a, b) => a.discountedPrice - b.discountedPrice)[0];
|
|
135
136
|
const discountValue = (() => {
|
|
136
137
|
if ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_type) === "percentage" &&
|
|
137
138
|
typeof (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value) === "number") {
|
|
@@ -154,14 +155,14 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
|
|
|
154
155
|
};
|
|
155
156
|
const originalDpPrice = getMinValue(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.original_dp_price);
|
|
156
157
|
const dpDiscountPercent = getMinValue(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents);
|
|
157
|
-
const firstSeatFare = (
|
|
158
|
+
const firstSeatFare = (_f = (_e = seatTypesData === null || seatTypesData === void 0 ? void 0 : seatTypesData.filter((item) => getFilteredSeats(item.label) && !EXCEPTIONS.includes(item.label))) === null || _e === void 0 ? void 0 : _e.sort((a, b) => a.fare - b.fare)[0]) === null || _f === void 0 ? void 0 : _f.fare;
|
|
158
159
|
const hasDpDiscount = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discounted_seats) &&
|
|
159
160
|
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents) &&
|
|
160
161
|
originalDpPrice != null &&
|
|
161
162
|
dpDiscountPercent != null &&
|
|
162
163
|
firstSeatFare != null;
|
|
163
164
|
return (React.createElement("div", { className: "content-center relative", style: { width: "40%" } }, (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) &&
|
|
164
|
-
!((
|
|
165
|
+
!((_g = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discounted_seats) === null || _g === void 0 ? void 0 : _g.length) &&
|
|
165
166
|
!dpDiscountPercent ? (React.createElement("div", { className: "flex flex-col justify-between h-[2.5rem]", style: { gap: isSoldOut ? "0px" : "5px" } }, renderDpSeats())) : hasDpDiscount ? (React.createElement("div", { className: "relative grid grid-cols-[auto_auto] justify-between gap-x-[8px] " },
|
|
166
167
|
!isNaN(Number(dpDiscountPercent)) &&
|
|
167
168
|
Number(dpDiscountPercent) > 0 && (React.createElement("div", { className: "absolute -top-[18px] right-[0px]", style: {
|
|
@@ -193,7 +194,7 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
|
|
|
193
194
|
React.createElement("span", { className: "flex items-center justify-end gap-[4px] text-[14px] bold-text leading-[24px]", style: {
|
|
194
195
|
color: isSoldOut ? "#bbb" : discountSeatPriceColor || "#ff5964",
|
|
195
196
|
} },
|
|
196
|
-
((
|
|
197
|
+
((_h = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.icons) === null || _h === void 0 ? void 0 : _h.fireIcon) ? (React.createElement("img", { src: serviceItem.icons.fireIcon, alt: "discount", className: "h-[16px] w-[16px] object-contain", style: { filter: isSoldOut ? "grayscale" : "" } })) : null,
|
|
197
198
|
commonService.discountedCurrency(Number(firstSeatFare), currencySign)),
|
|
198
199
|
isSoldOut ? (React.createElement("span", { className: "col-span-2 min-[420]:text-[13px] text-right text-[12px] text-[#ccc]" }, "Agotado")) : null)) : hasDiscount && discountSeat ? (React.createElement("div", null,
|
|
199
200
|
React.createElement("div", { className: "relative grid grid-cols-[auto_auto] justify-between gap-x-[8px] " },
|
|
@@ -227,8 +228,8 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
|
|
|
227
228
|
React.createElement("span", { className: "flex items-center justify-end gap-[4px] text-[14px] bold-text leading-[24px]", style: {
|
|
228
229
|
color: isSoldOut ? "#bbb" : discountSeatPriceColor || "#ff5964",
|
|
229
230
|
} },
|
|
230
|
-
((
|
|
231
|
-
commonService.discountedCurrency(discountSeat.discountedPrice, currencySign))))) : (React.createElement("div", { className:
|
|
231
|
+
((_j = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.icons) === null || _j === void 0 ? void 0 : _j.fireIcon) ? (React.createElement("img", { src: serviceItem.icons.fireIcon, alt: "discount", className: "h-[16px] w-[16px] object-contain", style: { opacity: isSoldOut ? 0.5 : 1 } })) : null,
|
|
232
|
+
commonService.discountedCurrency(discountSeat.discountedPrice, currencySign))))) : (React.createElement("div", { className: "flex flex-col justify-between h-[2.5rem] ", style: {
|
|
232
233
|
gap: isSoldOut ? "0px" : "5px",
|
|
233
234
|
justifyContent: hasMultipleTypes ? "space-between" : "center",
|
|
234
235
|
} },
|
|
@@ -3,7 +3,7 @@ declare const commonService: {
|
|
|
3
3
|
discountedCurrency(amount: number, currencySign?: string): string;
|
|
4
4
|
copyObject: (ob: any) => any;
|
|
5
5
|
getServiceTypeLabelForFilters: (service_type: any) => "Tipo de servicio" | "Punto de embarque" | "Tipo de asiento" | "SERVICIOS" | "";
|
|
6
|
-
truncateSeatLabel: (label: string | number
|
|
6
|
+
truncateSeatLabel: (label: string | number) => string;
|
|
7
7
|
getAmenitiesImage: (name: string, serviceItem: any) => string;
|
|
8
8
|
getAmenityName: (rawAmenity: string) => string;
|
|
9
9
|
getSeatNameForFilters: (rawSeat: any) => any;
|
|
@@ -27,6 +27,14 @@ declare const commonService: {
|
|
|
27
27
|
interval?: number;
|
|
28
28
|
}) => void;
|
|
29
29
|
startCountdown: (node: HTMLSpanElement | null, countdownSeconds?: number) => void;
|
|
30
|
+
startDealCountdown: (node: HTMLSpanElement | null, countdownSeconds: number) => void;
|
|
30
31
|
startComprandoCount: (node: HTMLSpanElement | null, min?: number, max?: number) => void;
|
|
32
|
+
timeToMinutes: (time: string) => number;
|
|
33
|
+
minutesToTime: (minutes: number) => string;
|
|
34
|
+
generateTimeSlots: (from: string, to: string, windowHours: number) => Array<{
|
|
35
|
+
label: string;
|
|
36
|
+
start: number;
|
|
37
|
+
end: number;
|
|
38
|
+
}>;
|
|
31
39
|
};
|
|
32
40
|
export default commonService;
|