kupos-ui-components-lib 9.3.2 → 9.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/images/anims/service_list/60_percent_anim.json +1 -0
- package/dist/components/ServiceItem/ServiceItemDesktop.js +18 -84
- package/dist/components/ServiceItem/ServiceItemMobile.js +27 -97
- package/dist/components/ServiceItem/types.d.ts +2 -0
- package/dist/styles.css +37 -0
- package/dist/ui/SeatSection/SeatSection.js +17 -2
- package/dist/ui/ServiceBadges/ServiceBadges.d.ts +17 -0
- package/dist/ui/ServiceBadges/ServiceBadges.js +33 -0
- package/dist/ui/mobileweb/DateTimeSectionMobile.d.ts +2 -1
- package/dist/ui/mobileweb/DateTimeSectionMobile.js +2 -2
- package/dist/ui/mobileweb/SeatSectionMobile.d.ts +2 -1
- package/dist/ui/mobileweb/SeatSectionMobile.js +8 -4
- package/dist/ui/mobileweb/ServiceBadgesMobile.d.ts +17 -0
- package/dist/ui/mobileweb/ServiceBadgesMobile.js +35 -0
- package/dist/utils/CommonService.d.ts +7 -0
- package/dist/utils/CommonService.js +61 -0
- package/package.json +1 -1
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +35 -131
- package/src/components/ServiceItem/ServiceItemMobile.tsx +57 -165
- package/src/components/ServiceItem/types.ts +2 -0
- package/src/styles.css +10 -0
- package/src/ui/SeatSection/SeatSection.tsx +24 -2
- package/src/ui/ServiceBadges/ServiceBadges.tsx +92 -0
- package/src/ui/mobileweb/DateTimeSectionMobile.tsx +3 -0
- package/src/ui/mobileweb/SeatSectionMobile.tsx +12 -3
- package/src/ui/mobileweb/ServiceBadgesMobile.tsx +92 -0
- package/src/utils/CommonService.ts +86 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface ServiceBadgesMobileProps {
|
|
3
|
+
showTopLabel?: string;
|
|
4
|
+
isSoldOut: boolean;
|
|
5
|
+
colors: any;
|
|
6
|
+
renderIcon: (iconKey: string, size?: string) => React.ReactNode;
|
|
7
|
+
translation?: {
|
|
8
|
+
directService?: string;
|
|
9
|
+
};
|
|
10
|
+
serviceItem: {
|
|
11
|
+
is_direct_trip?: boolean;
|
|
12
|
+
train_type_label?: string;
|
|
13
|
+
};
|
|
14
|
+
isConexion?: boolean;
|
|
15
|
+
}
|
|
16
|
+
declare const ServiceBadgesMobile: React.FC<ServiceBadgesMobileProps>;
|
|
17
|
+
export default ServiceBadgesMobile;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
const ServiceBadgesMobile = ({ showTopLabel, isSoldOut, colors, renderIcon, serviceItem, isConexion, }) => {
|
|
3
|
+
return (React.createElement("div", { className: "absolute -top-[9px] left-0 w-full flex items-center justify-end gap-[12px] pr-[20px] z-10" },
|
|
4
|
+
showTopLabel && (React.createElement("div", { className: `flex items-center gap-[2px] py-[4px] px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] z-20`, style: {
|
|
5
|
+
backgroundColor: "#fff",
|
|
6
|
+
border: `1px solid ${colors.topLabelColor}`,
|
|
7
|
+
color: colors.topLabelColor,
|
|
8
|
+
} },
|
|
9
|
+
React.createElement("div", { className: isSoldOut ? "grayscale" : "" }, renderIcon("specialDeparture", "12px")),
|
|
10
|
+
React.createElement("div", { style: {
|
|
11
|
+
color: colors.topLabelColor,
|
|
12
|
+
} }, showTopLabel))),
|
|
13
|
+
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) && (React.createElement("div", { className: `flex items-center gap-[2px] py-[5px] px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] z-20`, style: {
|
|
14
|
+
backgroundColor: "#fff",
|
|
15
|
+
border: `1px solid ${colors.topLabelColor}`,
|
|
16
|
+
color: colors.topLabelColor,
|
|
17
|
+
} },
|
|
18
|
+
renderIcon("directo", "12px"),
|
|
19
|
+
React.createElement("div", { className: "ml-[5px]" }, "Directo"))),
|
|
20
|
+
isConexion && (React.createElement("div", { className: `flex items-center gap-[2px] py-[5px] text-white px-[10px] rounded-[38px] min-[420]:text-[12px] text-[11px] z-20`, style: {
|
|
21
|
+
backgroundColor: "#fff",
|
|
22
|
+
border: `1px solid ${colors.topLabelColor}`,
|
|
23
|
+
color: colors.topLabelColor,
|
|
24
|
+
} },
|
|
25
|
+
renderIcon("airportIcon", "14px"),
|
|
26
|
+
React.createElement("div", null, "Conexi\u00F3n"))),
|
|
27
|
+
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.train_type_label) === "Tren Express (Nuevo)" && (React.createElement("div", { className: `flex items-center gap-[2px] py-[5px] text-white px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] z-20`, style: {
|
|
28
|
+
backgroundColor: "#fff",
|
|
29
|
+
border: `1px solid ${colors.topLabelColor}`,
|
|
30
|
+
color: colors.topLabelColor,
|
|
31
|
+
} },
|
|
32
|
+
renderIcon("directo", "12px"),
|
|
33
|
+
React.createElement("div", null, "Tren Express")))));
|
|
34
|
+
};
|
|
35
|
+
export default ServiceBadgesMobile;
|
|
@@ -17,5 +17,12 @@ declare const commonService: {
|
|
|
17
17
|
originalPrice: number;
|
|
18
18
|
discountedPrice: number;
|
|
19
19
|
};
|
|
20
|
+
startViewerCount: (node: HTMLSpanElement | null, viewersConfig?: {
|
|
21
|
+
min: number;
|
|
22
|
+
max: number;
|
|
23
|
+
interval?: number;
|
|
24
|
+
}) => void;
|
|
25
|
+
startCountdown: (node: HTMLSpanElement | null, countdownSeconds?: number) => void;
|
|
26
|
+
startComprandoCount: (node: HTMLSpanElement | null, min?: number, max?: number) => void;
|
|
20
27
|
};
|
|
21
28
|
export default commonService;
|
|
@@ -284,5 +284,66 @@ const commonService = {
|
|
|
284
284
|
const discountedPrice = Math.max(0, price - finalDiscount);
|
|
285
285
|
return { originalPrice: price, discountedPrice };
|
|
286
286
|
},
|
|
287
|
+
startViewerCount: (node, viewersConfig) => {
|
|
288
|
+
if (!node || !viewersConfig)
|
|
289
|
+
return;
|
|
290
|
+
const prevId = node.dataset.viewerId;
|
|
291
|
+
if (prevId)
|
|
292
|
+
clearInterval(Number(prevId));
|
|
293
|
+
const { min, max, interval = 5000 } = viewersConfig;
|
|
294
|
+
const clamp = (v) => Math.min(max, Math.max(min, v));
|
|
295
|
+
const initialValue = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
296
|
+
node.textContent = String(initialValue);
|
|
297
|
+
const id = setInterval(() => {
|
|
298
|
+
const current = Number(node.textContent) || initialValue;
|
|
299
|
+
const delta = Math.ceil(current * 0.2);
|
|
300
|
+
const next = current + Math.floor(Math.random() * (2 * delta + 1)) - delta;
|
|
301
|
+
node.textContent = String(clamp(Math.round(next)));
|
|
302
|
+
}, interval);
|
|
303
|
+
node.dataset.viewerId = String(id);
|
|
304
|
+
},
|
|
305
|
+
startCountdown: (node, countdownSeconds = 599) => {
|
|
306
|
+
if (!node)
|
|
307
|
+
return;
|
|
308
|
+
const prevId = node.dataset.countdownId;
|
|
309
|
+
if (prevId)
|
|
310
|
+
clearInterval(Number(prevId));
|
|
311
|
+
let remaining = countdownSeconds * 1000; // Convert to milliseconds
|
|
312
|
+
const formatTime = (totalMs) => {
|
|
313
|
+
const m = Math.floor(totalMs / 60000);
|
|
314
|
+
const s = Math.floor((totalMs % 60000) / 1000);
|
|
315
|
+
const ms = Math.floor((totalMs % 1000) / 10); // Show 2 digits for milliseconds
|
|
316
|
+
return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}:${String(ms).padStart(2, "0")}`;
|
|
317
|
+
};
|
|
318
|
+
node.textContent = formatTime(remaining);
|
|
319
|
+
const id = setInterval(() => {
|
|
320
|
+
remaining -= 100; // Decrease by 100ms
|
|
321
|
+
if (remaining <= 0) {
|
|
322
|
+
remaining = countdownSeconds * 1000;
|
|
323
|
+
}
|
|
324
|
+
node.textContent = formatTime(remaining);
|
|
325
|
+
}, 100); // Update every 100ms
|
|
326
|
+
node.dataset.countdownId = String(id);
|
|
327
|
+
},
|
|
328
|
+
startComprandoCount: (node, min = 4, max = 16) => {
|
|
329
|
+
if (!node)
|
|
330
|
+
return;
|
|
331
|
+
const prevId = node.dataset.comprandoId;
|
|
332
|
+
if (prevId)
|
|
333
|
+
clearInterval(Number(prevId));
|
|
334
|
+
const initialValue = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
335
|
+
node.textContent = String(initialValue);
|
|
336
|
+
const id = setInterval(() => {
|
|
337
|
+
const current = Number(node.textContent) || initialValue;
|
|
338
|
+
const changePercent = 0.05; // 5% change
|
|
339
|
+
const change = Math.ceil(current * changePercent);
|
|
340
|
+
const direction = Math.random() > 0.5 ? 1 : -1;
|
|
341
|
+
let next = current + (change * direction);
|
|
342
|
+
// Clamp within min and max
|
|
343
|
+
next = Math.min(max, Math.max(min, next));
|
|
344
|
+
node.textContent = String(next);
|
|
345
|
+
}, 5000); // Update every 5 seconds
|
|
346
|
+
node.dataset.comprandoId = String(id);
|
|
347
|
+
},
|
|
287
348
|
};
|
|
288
349
|
export default commonService;
|
package/package.json
CHANGED
|
@@ -28,15 +28,14 @@ import dotAnimation from "../../assets/images/anims/service_list/dot_animation.j
|
|
|
28
28
|
|
|
29
29
|
import RatingBlock from "../../ui/RatingBlock";
|
|
30
30
|
import DurationBlock from "../../ui/DurationBlock";
|
|
31
|
-
import DirectoBlock from "../../ui/DirectoBlock";
|
|
32
31
|
import PetBlock from "../../ui/PetBlock";
|
|
33
32
|
import FlexibleBlock from "../../ui/FlexibleBlock";
|
|
34
33
|
import AmenitiesBlock from "../../ui/AmenitiesBlock";
|
|
35
34
|
import KuposButton from "../../ui/KuposButton/KuposButton";
|
|
36
|
-
import TopAmenities from "../../ui/TopAmenities/TopAmenities";
|
|
37
35
|
import BottomAmenities from "../../ui/BottomAmenities/BottomAmenities";
|
|
38
36
|
import SeatSection from "../../ui/SeatSection/SeatSection";
|
|
39
37
|
import DateTimeSection from "../../ui/DateTimeSection/DateTimeSection";
|
|
38
|
+
import ServiceBadges from "../../ui/ServiceBadges/ServiceBadges";
|
|
40
39
|
|
|
41
40
|
const SEAT_EXCEPTIONS = ["Asiento mascota"];
|
|
42
41
|
|
|
@@ -107,28 +106,6 @@ function ServiceItemPB({
|
|
|
107
106
|
coachKey,
|
|
108
107
|
viewersConfig,
|
|
109
108
|
}: ServiceItemProps & { currencySign?: string }): React.ReactElement {
|
|
110
|
-
const startViewerCount = (node: HTMLSpanElement | null) => {
|
|
111
|
-
if (!node || !viewersConfig) return;
|
|
112
|
-
|
|
113
|
-
const prevId = node.dataset.viewerId;
|
|
114
|
-
if (prevId) clearInterval(Number(prevId));
|
|
115
|
-
|
|
116
|
-
const { min, max, interval = 5000 } = viewersConfig;
|
|
117
|
-
const clamp = (v: number) => Math.min(max, Math.max(min, v));
|
|
118
|
-
const initialValue = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
119
|
-
|
|
120
|
-
node.textContent = String(initialValue);
|
|
121
|
-
|
|
122
|
-
const id = setInterval(() => {
|
|
123
|
-
const current = Number(node.textContent) || initialValue;
|
|
124
|
-
const delta = Math.ceil(current * 0.2);
|
|
125
|
-
const next =
|
|
126
|
-
current + Math.floor(Math.random() * (2 * delta + 1)) - delta;
|
|
127
|
-
node.textContent = String(clamp(Math.round(next)));
|
|
128
|
-
}, interval);
|
|
129
|
-
|
|
130
|
-
node.dataset.viewerId = String(id);
|
|
131
|
-
};
|
|
132
109
|
const getAnimationIcon = (icon: string) => {
|
|
133
110
|
const animation = ANIMATION_MAP[icon];
|
|
134
111
|
if (!animation) return null;
|
|
@@ -187,18 +164,16 @@ function ServiceItemPB({
|
|
|
187
164
|
|
|
188
165
|
let isSoldOut = serviceItem.available_seats <= 0;
|
|
189
166
|
|
|
190
|
-
const showPromo = Math.random() > 0.5;
|
|
191
|
-
|
|
192
167
|
const isItemExpanded = serviceItem.id === isExpand || isExpand === true;
|
|
193
168
|
const grayscaleClass = isSoldOut ? "grayscale" : "";
|
|
194
169
|
const hasOfferText = Boolean(serviceItem?.offer_text);
|
|
195
|
-
const offerGradient =
|
|
170
|
+
const offerGradient = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"} 0%, ${colors.leftGradiantColor || "#ff8842"} 100%)`;
|
|
196
171
|
const serviceCardStyle: React.CSSProperties = hasOfferText
|
|
197
172
|
? {
|
|
198
173
|
borderColor: "transparent",
|
|
199
174
|
borderStyle: "solid",
|
|
200
175
|
borderWidth: "6px 6px 0 6px",
|
|
201
|
-
borderRadius: isItemExpanded ? "18px 18px 0 0" : "18px",
|
|
176
|
+
borderRadius: isItemExpanded || coachKey ? "18px 18px 0 0" : "18px",
|
|
202
177
|
background: `linear-gradient(#fff, #fff) padding-box, ${offerGradient} border-box`,
|
|
203
178
|
}
|
|
204
179
|
: {};
|
|
@@ -303,34 +278,6 @@ function ServiceItemPB({
|
|
|
303
278
|
|
|
304
279
|
onBookButtonPress();
|
|
305
280
|
};
|
|
306
|
-
const countdownSeconds = 599;
|
|
307
|
-
|
|
308
|
-
const startCountdown = (node: HTMLSpanElement | null) => {
|
|
309
|
-
if (!node) return;
|
|
310
|
-
|
|
311
|
-
const prevId = node.dataset.countdownId;
|
|
312
|
-
if (prevId) clearInterval(Number(prevId));
|
|
313
|
-
|
|
314
|
-
let remaining = countdownSeconds;
|
|
315
|
-
|
|
316
|
-
const formatTime = (totalSecs: number) => {
|
|
317
|
-
const m = Math.floor(totalSecs / 60);
|
|
318
|
-
const s = totalSecs % 60;
|
|
319
|
-
return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
node.textContent = formatTime(remaining);
|
|
323
|
-
|
|
324
|
-
const id = setInterval(() => {
|
|
325
|
-
remaining -= 1;
|
|
326
|
-
if (remaining <= 0) {
|
|
327
|
-
remaining = countdownSeconds;
|
|
328
|
-
}
|
|
329
|
-
node.textContent = formatTime(remaining);
|
|
330
|
-
}, 1000);
|
|
331
|
-
|
|
332
|
-
node.dataset.countdownId = String(id);
|
|
333
|
-
};
|
|
334
281
|
|
|
335
282
|
const items = [
|
|
336
283
|
{
|
|
@@ -456,14 +403,15 @@ function ServiceItemPB({
|
|
|
456
403
|
padding: coachKey
|
|
457
404
|
? "15px 15px 20px 15px"
|
|
458
405
|
: "20px 15px 11px 15px",
|
|
406
|
+
marginTop: hasOfferText ? "14px" : "0",
|
|
459
407
|
}}
|
|
460
408
|
>
|
|
461
409
|
<div
|
|
462
410
|
className="grid text-[#464647] w-full [grid-template-columns:22%_28%_2.5%_24%_15.5%] gap-x-[2%] items-center"
|
|
463
|
-
style={{
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
}}
|
|
411
|
+
// style={{
|
|
412
|
+
// marginTop:
|
|
413
|
+
// showTopLabel || serviceItem?.is_direct_trip ? "8px" : "",
|
|
414
|
+
// }}
|
|
467
415
|
>
|
|
468
416
|
{/* OPERATOR LOGO */}
|
|
469
417
|
<div className="flex flex-col gap-[5px]">
|
|
@@ -530,7 +478,7 @@ function ServiceItemPB({
|
|
|
530
478
|
{/* BUTTON */}
|
|
531
479
|
|
|
532
480
|
<div className="relative">
|
|
533
|
-
{showLastSeats ? (
|
|
481
|
+
{/* {showLastSeats ? (
|
|
534
482
|
<div
|
|
535
483
|
className="flex justify-end mr-[11px] w-[100%] right-[0px] absolute"
|
|
536
484
|
style={{
|
|
@@ -544,7 +492,7 @@ function ServiceItemPB({
|
|
|
544
492
|
</div>
|
|
545
493
|
)}
|
|
546
494
|
</div>
|
|
547
|
-
) : null}
|
|
495
|
+
) : null} */}
|
|
548
496
|
<KuposButton
|
|
549
497
|
isSoldOut={isSoldOut}
|
|
550
498
|
isLoading={serviceDetailsLoading}
|
|
@@ -556,7 +504,7 @@ function ServiceItemPB({
|
|
|
556
504
|
/>
|
|
557
505
|
{showLastSeats ? (
|
|
558
506
|
<div
|
|
559
|
-
className="flex justify-
|
|
507
|
+
className="flex justify-center mr-[11px] w-[100%] right-[0px]"
|
|
560
508
|
style={{
|
|
561
509
|
top: serviceDetailsLoading ? "-17px" : "-20px",
|
|
562
510
|
}}
|
|
@@ -654,7 +602,7 @@ function ServiceItemPB({
|
|
|
654
602
|
| Termina en
|
|
655
603
|
<span
|
|
656
604
|
className="bold-text text-end"
|
|
657
|
-
ref={startCountdown}
|
|
605
|
+
ref={(node) => CommonService.startCountdown(node, 599)}
|
|
658
606
|
style={{
|
|
659
607
|
fontVariantNumeric: "tabular-nums",
|
|
660
608
|
display: "inline-block",
|
|
@@ -675,84 +623,40 @@ function ServiceItemPB({
|
|
|
675
623
|
<span className="ml-[6px]">
|
|
676
624
|
<span
|
|
677
625
|
className="bold-text"
|
|
678
|
-
ref={
|
|
626
|
+
ref={(node) =>
|
|
627
|
+
CommonService.startViewerCount(node, viewersConfig)
|
|
628
|
+
}
|
|
679
629
|
style={{ fontVariantNumeric: "tabular-nums" }}
|
|
680
630
|
/>{" "}
|
|
681
631
|
<span className="bold-text">personas</span>{" "}
|
|
682
632
|
<span>
|
|
683
633
|
{" "}
|
|
684
|
-
{viewersConfig?.label || "
|
|
634
|
+
{viewersConfig?.label || " viendo"} |{" "}
|
|
635
|
+
<span className="">
|
|
636
|
+
⚡ Quedan pocos{" "}
|
|
637
|
+
<span
|
|
638
|
+
className="bold-text"
|
|
639
|
+
ref={(node) =>
|
|
640
|
+
CommonService.startComprandoCount(node, 4, 16)
|
|
641
|
+
}
|
|
642
|
+
style={{ fontVariantNumeric: "tabular-nums" }}
|
|
643
|
+
/>{" "}
|
|
644
|
+
comprando
|
|
645
|
+
</span>
|
|
685
646
|
</span>
|
|
686
647
|
</span>
|
|
687
648
|
</div>
|
|
688
649
|
</div>
|
|
689
650
|
</div>
|
|
690
651
|
)}
|
|
691
|
-
<
|
|
692
|
-
{showTopLabel
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
}}
|
|
700
|
-
>
|
|
701
|
-
<div className={isSoldOut ? "grayscale" : ""}>
|
|
702
|
-
{renderIcon("specialDeparture", "12px")}
|
|
703
|
-
</div>
|
|
704
|
-
<div
|
|
705
|
-
className={
|
|
706
|
-
isSoldOut ? "text-white" : `text-[${colors.topLabelColor}]`
|
|
707
|
-
}
|
|
708
|
-
>
|
|
709
|
-
{showTopLabel}
|
|
710
|
-
</div>
|
|
711
|
-
</div>
|
|
712
|
-
)}
|
|
713
|
-
{serviceItem?.is_transpordo && (
|
|
714
|
-
<div
|
|
715
|
-
className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-20`}
|
|
716
|
-
style={{
|
|
717
|
-
backgroundColor: "#fff",
|
|
718
|
-
border: `1px solid ${colors.topLabelColor}`,
|
|
719
|
-
color: colors.topLabelColor,
|
|
720
|
-
}}
|
|
721
|
-
>
|
|
722
|
-
{renderIcon("connectingServiceIcon", "12px")}
|
|
723
|
-
|
|
724
|
-
<div>{"Conexión"}</div>
|
|
725
|
-
</div>
|
|
726
|
-
)}
|
|
727
|
-
{serviceItem?.is_direct_trip && (
|
|
728
|
-
<div
|
|
729
|
-
className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-20 `}
|
|
730
|
-
style={{
|
|
731
|
-
backgroundColor: "#fff",
|
|
732
|
-
border: `1px solid ${colors.topLabelColor}`,
|
|
733
|
-
color: colors.topLabelColor,
|
|
734
|
-
}}
|
|
735
|
-
>
|
|
736
|
-
{renderIcon("directo", "12px")}
|
|
737
|
-
|
|
738
|
-
<div>{translation?.directService}</div>
|
|
739
|
-
</div>
|
|
740
|
-
)}
|
|
741
|
-
{serviceItem?.train_type_label === "Tren Express (Nuevo)" && (
|
|
742
|
-
<div
|
|
743
|
-
className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-20 `}
|
|
744
|
-
style={{
|
|
745
|
-
backgroundColor: "#fff",
|
|
746
|
-
border: `1px solid ${colors.topLabelColor}`,
|
|
747
|
-
color: colors.topLabelColor,
|
|
748
|
-
}}
|
|
749
|
-
>
|
|
750
|
-
{renderIcon("directo", "12px")}
|
|
751
|
-
|
|
752
|
-
<div>{"Tren Express"}</div>
|
|
753
|
-
</div>
|
|
754
|
-
)}
|
|
755
|
-
</div>
|
|
652
|
+
<ServiceBadges
|
|
653
|
+
showTopLabel={showTopLabel}
|
|
654
|
+
isSoldOut={isSoldOut}
|
|
655
|
+
colors={colors}
|
|
656
|
+
renderIcon={renderIcon}
|
|
657
|
+
translation={translation}
|
|
658
|
+
serviceItem={serviceItem}
|
|
659
|
+
/>
|
|
756
660
|
</div>
|
|
757
661
|
)}
|
|
758
662
|
</>
|