kupos-ui-components-lib 9.6.6 → 9.6.7

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.
@@ -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, showLoginModal, isLoggedIn, showLoginOption }: ServiceItemProps & {
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, }: ServiceItemProps & {
4
4
  currencySign?: string;
5
5
  }): React.ReactElement;
6
6
  export default ServiceItemPB;
@@ -32,6 +32,8 @@ import KuposButton from "../../ui/KuposButton/KuposButton";
32
32
  import BottomAmenities from "../../ui/BottomAmenities/BottomAmenities";
33
33
  import SeatSection from "../../ui/SeatSection/SeatSection";
34
34
  import DateTimeSection from "../../ui/DateTimeSection/DateTimeSection";
35
+ import FeatureServiceUi from "../../ui/FeatureServiceUI/FeatureServiceUi";
36
+ import thunderAnimation from "../../assets/images/anims/service_list/thunder_icon.json";
35
37
  import ServiceBadges from "../../ui/ServiceBadges/ServiceBadges";
36
38
  const SEAT_EXCEPTIONS = ["Asiento mascota"];
37
39
  const ANIMATION_MAP = {
@@ -64,6 +66,9 @@ const ANIMATION_MAP = {
64
66
  bombAnimation: {
65
67
  kupos: bombAnimation,
66
68
  },
69
+ thunderAnimation: {
70
+ kupos: thunderAnimation,
71
+ },
67
72
  dotAnimation: {
68
73
  kupos: dotAnimation,
69
74
  },
@@ -74,7 +79,7 @@ const ANIMATION_MAP = {
74
79
  kupos: femaleAnimation,
75
80
  },
76
81
  };
77
- 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, showLoginModal, isLoggedIn, showLoginOption }) {
82
+ 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, }) {
78
83
  var _a;
79
84
  const getAnimationIcon = (icon) => {
80
85
  var _a;
@@ -243,7 +248,7 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
243
248
  },
244
249
  ];
245
250
  const otherItems = items.filter((i) => i.key !== "pet" && i.key !== "flexible" && !!i.condition);
246
- return (React.createElement(React.Fragment, null, isPeruSites ? (React.createElement(PeruServiceItemDesktop, { serviceItem: serviceItem, onBookButtonPress: onBookButtonPress, colors: colors, metaData: metaData, children: children, busStage: busStage, serviceDetailsLoading: serviceDetailsLoading, cityOrigin: cityOrigin, cityDestination: cityDestination, translation: translation, orignLabel: orignLabel, destinationLabel: destinationLabel, currencySign: currencySign, isCiva: isCiva, showRating: showRating, showLastSeats: showLastSeats, removeArrivalTime: removeArrivalTime, removeDuplicateSeats: removeDuplicateSeats, isPeruSites: isPeruSites, t: (key) => t(key), showAvailableSeats: showAvailableSeats, isSeatIcon: isSeatIcon, isPeru: isPeru, siteType: siteType, isAllinBus: isAllinBus })) : (React.createElement("div", { className: `relative hover:z-[150] ${hasOfferText || hasDpEnabled ? "mb-[55px]" : "mb-[10px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
251
+ return (React.createElement(React.Fragment, null, isPeruSites ? (React.createElement(PeruServiceItemDesktop, { serviceItem: serviceItem, onBookButtonPress: onBookButtonPress, colors: colors, metaData: metaData, children: children, busStage: busStage, serviceDetailsLoading: serviceDetailsLoading, cityOrigin: cityOrigin, cityDestination: cityDestination, translation: translation, orignLabel: orignLabel, destinationLabel: destinationLabel, currencySign: currencySign, isCiva: isCiva, showRating: showRating, showLastSeats: showLastSeats, removeArrivalTime: removeArrivalTime, removeDuplicateSeats: removeDuplicateSeats, isPeruSites: isPeruSites, t: (key) => t(key), showAvailableSeats: showAvailableSeats, isSeatIcon: isSeatIcon, isPeru: isPeru, siteType: siteType, isAllinBus: isAllinBus })) : isNewUi ? (React.createElement(FeatureServiceUi, { serviceItem: serviceItem, showTopLabel: showTopLabel, colors: colors, isSoldOut: isSoldOut, getAnimationIcon: getAnimationIcon, cityOrigin: cityOrigin, cityDestination: cityDestination, renderIcon: renderIcon, viewersConfig: viewersConfig })) : (React.createElement("div", { className: `relative hover:z-[150] ${hasOfferText || hasDpEnabled ? "mb-[55px]" : "mb-[10px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
247
252
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.train_type_label) === "Tren Express (Nuevo)" ||
248
253
  showTopLabel
249
254
  ? "mt-[24px]"
@@ -129,6 +129,12 @@ export interface ServiceItemProps {
129
129
  personIcon?: string;
130
130
  whiteFireIcon?: string;
131
131
  fireIcon?: string;
132
+ whiteOrigin?: string;
133
+ whiteDestination?: string;
134
+ userIcon?: string;
135
+ sheildIcon?: string;
136
+ busIcon?: string;
137
+ whiteDownArrow?: string;
132
138
  [key: string]: string | Record<string, string | undefined> | undefined;
133
139
  };
134
140
  useLottieFor?: string[];
@@ -221,6 +227,7 @@ export interface ServiceItemProps {
221
227
  label?: string;
222
228
  icon?: string;
223
229
  };
230
+ isNewUi?: boolean;
224
231
  showLoginModal?: any;
225
232
  isLoggedIn?: any;
226
233
  showLoginOption?: boolean;
package/dist/styles.css CHANGED
@@ -63,6 +63,9 @@
63
63
  .right-\[0px\] {
64
64
  right: 0px;
65
65
  }
66
+ .right-\[18px\] {
67
+ right: 18px;
68
+ }
66
69
  .-bottom-\[9\%\] {
67
70
  bottom: calc(9% * -1);
68
71
  }
@@ -75,6 +78,9 @@
75
78
  .-bottom-\[36px\] {
76
79
  bottom: calc(36px * -1);
77
80
  }
81
+ .bottom-\[11px\] {
82
+ bottom: 11px;
83
+ }
78
84
  .bottom-\[35px\] {
79
85
  bottom: 35px;
80
86
  }
@@ -189,12 +195,21 @@
189
195
  .mt-\[5px\] {
190
196
  margin-top: 5px;
191
197
  }
198
+ .mt-\[6px\] {
199
+ margin-top: 6px;
200
+ }
201
+ .mt-\[8px\] {
202
+ margin-top: 8px;
203
+ }
192
204
  .mt-\[10px\] {
193
205
  margin-top: 10px;
194
206
  }
195
207
  .mt-\[13px\] {
196
208
  margin-top: 13px;
197
209
  }
210
+ .mt-\[14px\] {
211
+ margin-top: 14px;
212
+ }
198
213
  .mt-\[15px\] {
199
214
  margin-top: 15px;
200
215
  }
@@ -234,6 +249,9 @@
234
249
  .mb-\[5px\] {
235
250
  margin-bottom: 5px;
236
251
  }
252
+ .mb-\[6px\] {
253
+ margin-bottom: 6px;
254
+ }
237
255
  .mb-\[8px\] {
238
256
  margin-bottom: 8px;
239
257
  }
@@ -375,6 +393,9 @@
375
393
  .w-\[20px\] {
376
394
  width: 20px;
377
395
  }
396
+ .w-\[30px\] {
397
+ width: 30px;
398
+ }
378
399
  .w-\[50\%\] {
379
400
  width: 50%;
380
401
  }
@@ -443,6 +464,12 @@
443
464
  .max-w-\[165px\] {
444
465
  max-width: 165px;
445
466
  }
467
+ .max-w-\[220px\] {
468
+ max-width: 220px;
469
+ }
470
+ .max-w-full {
471
+ max-width: 100%;
472
+ }
446
473
  .min-w-\[75px\] {
447
474
  min-width: 75px;
448
475
  }
@@ -485,9 +512,15 @@
485
512
  .grid-cols-2 {
486
513
  grid-template-columns: repeat(2, minmax(0, 1fr));
487
514
  }
515
+ .grid-cols-4 {
516
+ grid-template-columns: repeat(4, minmax(0, 1fr));
517
+ }
488
518
  .grid-cols-\[0\.8fr_auto_26\%_1fr\] {
489
519
  grid-template-columns: 0.8fr auto 26% 1fr;
490
520
  }
521
+ .grid-cols-\[1\.3fr_2fr_1\.2fr\] {
522
+ grid-template-columns: 1.3fr 2fr 1.2fr;
523
+ }
491
524
  .grid-cols-\[1\.5fr_1fr_auto\] {
492
525
  grid-template-columns: 1.5fr 1fr auto;
493
526
  }
@@ -518,6 +551,9 @@
518
551
  .items-start {
519
552
  align-items: flex-start;
520
553
  }
554
+ .items-stretch {
555
+ align-items: stretch;
556
+ }
521
557
  .justify-between {
522
558
  justify-content: space-between;
523
559
  }
@@ -560,6 +596,12 @@
560
596
  .gap-\[14px\] {
561
597
  gap: 14px;
562
598
  }
599
+ .gap-\[16px\] {
600
+ gap: 16px;
601
+ }
602
+ .gap-\[20px\] {
603
+ gap: 20px;
604
+ }
563
605
  .gap-x-\[2\%\] {
564
606
  -moz-column-gap: 2%;
565
607
  column-gap: 2%;
@@ -568,18 +610,29 @@
568
610
  -moz-column-gap: 8px;
569
611
  column-gap: 8px;
570
612
  }
613
+ .truncate {
614
+ overflow: hidden;
615
+ text-overflow: ellipsis;
616
+ white-space: nowrap;
617
+ }
571
618
  .overflow-hidden {
572
619
  overflow: hidden;
573
620
  }
574
621
  .overflow-y-hidden {
575
622
  overflow-y: hidden;
576
623
  }
624
+ .rounded-\[4px\] {
625
+ border-radius: 4px;
626
+ }
577
627
  .rounded-\[8px\] {
578
628
  border-radius: 8px;
579
629
  }
580
630
  .rounded-\[10px\] {
581
631
  border-radius: 10px;
582
632
  }
633
+ .rounded-\[12px\] {
634
+ border-radius: 12px;
635
+ }
583
636
  .rounded-\[14px\] {
584
637
  border-radius: 14px;
585
638
  }
@@ -629,6 +682,10 @@
629
682
  border-top-style: var(--tw-border-style);
630
683
  border-top-width: 8px;
631
684
  }
685
+ .border-r {
686
+ border-right-style: var(--tw-border-style);
687
+ border-right-width: 1px;
688
+ }
632
689
  .border-r-8 {
633
690
  border-right-style: var(--tw-border-style);
634
691
  border-right-width: 8px;
@@ -657,6 +714,10 @@
657
714
  border-bottom-style: var(--tw-border-style);
658
715
  border-bottom-width: 8px;
659
716
  }
717
+ .border-l {
718
+ border-left-style: var(--tw-border-style);
719
+ border-left-width: 1px;
720
+ }
660
721
  .border-l-8 {
661
722
  border-left-style: var(--tw-border-style);
662
723
  border-left-width: 8px;
@@ -673,6 +734,9 @@
673
734
  --tw-border-style: none;
674
735
  border-style: none;
675
736
  }
737
+ .border-\[\#363c48\] {
738
+ border-color: #363c48;
739
+ }
676
740
  .border-\[\#ccc\] {
677
741
  border-color: #ccc;
678
742
  }
@@ -691,9 +755,15 @@
691
755
  .border-l-transparent {
692
756
  border-left-color: transparent;
693
757
  }
758
+ .bg-\[\#0C1421\] {
759
+ background-color: #0C1421;
760
+ }
694
761
  .bg-\[\#E6E6E6\] {
695
762
  background-color: #E6E6E6;
696
763
  }
764
+ .bg-\[\#FF8F45\] {
765
+ background-color: #FF8F45;
766
+ }
697
767
  .bg-\[\#FFF2F2\] {
698
768
  background-color: #FFF2F2;
699
769
  }
@@ -734,6 +804,9 @@
734
804
  .p-\[10px_15px\] {
735
805
  padding: 10px 15px;
736
806
  }
807
+ .p-\[14px\] {
808
+ padding: 14px;
809
+ }
737
810
  .p-\[15px\] {
738
811
  padding: 15px;
739
812
  }
@@ -767,9 +840,15 @@
767
840
  .px-\[15px\] {
768
841
  padding-inline: 15px;
769
842
  }
843
+ .px-\[16px\] {
844
+ padding-inline: 16px;
845
+ }
770
846
  .px-\[20px\] {
771
847
  padding-inline: 20px;
772
848
  }
849
+ .py-\[2px\] {
850
+ padding-block: 2px;
851
+ }
773
852
  .py-\[4px\] {
774
853
  padding-block: 4px;
775
854
  }
@@ -797,6 +876,9 @@
797
876
  .pt-\[10px\] {
798
877
  padding-top: 10px;
799
878
  }
879
+ .pt-\[14px\] {
880
+ padding-top: 14px;
881
+ }
800
882
  .pt-\[20px\] {
801
883
  padding-top: 20px;
802
884
  }
@@ -821,6 +903,9 @@
821
903
  .pr-\[22px\] {
822
904
  padding-right: 22px;
823
905
  }
906
+ .pb-\[6px\] {
907
+ padding-bottom: 6px;
908
+ }
824
909
  .pb-\[7px\] {
825
910
  padding-bottom: 7px;
826
911
  }
@@ -887,6 +972,12 @@
887
972
  .text-\[22px\] {
888
973
  font-size: 22px;
889
974
  }
975
+ .text-\[26px\] {
976
+ font-size: 26px;
977
+ }
978
+ .text-\[28px\] {
979
+ font-size: 28px;
980
+ }
890
981
  .text-\[42px\] {
891
982
  font-size: 42px;
892
983
  }
@@ -894,6 +985,10 @@
894
985
  --tw-leading: 1.3;
895
986
  line-height: 1.3;
896
987
  }
988
+ .leading-\[14px\] {
989
+ --tw-leading: 14px;
990
+ line-height: 14px;
991
+ }
897
992
  .leading-\[20px\] {
898
993
  --tw-leading: 20px;
899
994
  line-height: 20px;
@@ -914,6 +1009,10 @@
914
1009
  --tw-leading: 1;
915
1010
  line-height: 1;
916
1011
  }
1012
+ .font-\[9px\] {
1013
+ --tw-font-weight: 9px;
1014
+ font-weight: 9px;
1015
+ }
917
1016
  .font-\[14px\] {
918
1017
  --tw-font-weight: 14px;
919
1018
  font-weight: 14px;
@@ -935,12 +1034,27 @@
935
1034
  .whitespace-nowrap {
936
1035
  white-space: nowrap;
937
1036
  }
1037
+ .text-\[\#4a4a4a\] {
1038
+ color: #4a4a4a;
1039
+ }
938
1040
  .text-\[\#9f9f9f\] {
939
1041
  color: #9f9f9f;
940
1042
  }
1043
+ .text-\[\#666\] {
1044
+ color: #666;
1045
+ }
1046
+ .text-\[\#171717\] {
1047
+ color: #171717;
1048
+ }
1049
+ .text-\[\#272727\] {
1050
+ color: #272727;
1051
+ }
941
1052
  .text-\[\#464647\] {
942
1053
  color: #464647;
943
1054
  }
1055
+ .text-\[\#FF8F45\] {
1056
+ color: #FF8F45;
1057
+ }
944
1058
  .text-\[\#c0c0c0\] {
945
1059
  color: #c0c0c0;
946
1060
  }
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- declare const FeatureServiceUi: ({ serviceItem, showTopLabel, colors, isSoldOut, getAnimationIcon, cityOrigin, cityDestination, renderIcon, }: {
2
+ declare const FeatureServiceUi: ({ serviceItem, showTopLabel, colors, isSoldOut, getAnimationIcon, cityOrigin, cityDestination, renderIcon, viewersConfig, }: {
3
3
  serviceItem: any;
4
4
  showTopLabel: any;
5
5
  colors: any;
@@ -8,5 +8,6 @@ declare const FeatureServiceUi: ({ serviceItem, showTopLabel, colors, isSoldOut,
8
8
  cityOrigin: any;
9
9
  cityDestination: any;
10
10
  renderIcon: any;
11
+ viewersConfig: any;
11
12
  }) => React.JSX.Element;
12
13
  export default FeatureServiceUi;
@@ -1,22 +1,84 @@
1
1
  import React from "react";
2
2
  import LottiePlayer from "../../assets/LottiePlayer";
3
+ import commonService from "../../utils/CommonService";
3
4
  const HARDCODED_OPERATORS = [
4
5
  {
5
6
  logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Turbus_logo.svg/320px-Turbus_logo.svg.png",
6
7
  name: "Turbus",
8
+ time: "7:00 am",
9
+ seatsAvailable: "3 disponibles",
7
10
  },
8
11
  {
9
12
  logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Pullman_Bus_logo.svg/320px-Pullman_Bus_logo.svg.png",
10
13
  name: "Pullmanbus",
14
+ time: "8:00 am",
15
+ seatsAvailable: "5 disponibles",
11
16
  },
12
17
  {
13
18
  logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Turbus_logo.svg/320px-Turbus_logo.svg.png",
14
19
  name: "Expreso Santa C...",
20
+ time: "9:00 am",
21
+ seatsAvailable: "3 disponibles",
15
22
  },
16
23
  ];
17
24
  const HARDCODED_COUNTDOWN = "09:55";
18
- const FeatureServiceUi = ({ serviceItem, showTopLabel, colors, isSoldOut, getAnimationIcon, cityOrigin, cityDestination, renderIcon, }) => {
19
- var _a, _b, _c, _d, _e, _f, _g;
25
+ const HOW_IT_WORKS_STEPS = [
26
+ {
27
+ icon: "flexible",
28
+ name: "1. Salida flexible",
29
+ text: "Viajas en un horario entre las 07:00 y las 10:00 AM del día elegido.",
30
+ },
31
+ {
32
+ icon: "bus",
33
+ name: "2. Empresa asignada",
34
+ text: "Una de las empresas disponibles confirma tu viaje una vez pagado.",
35
+ },
36
+ {
37
+ icon: "price",
38
+ name: "3. Precio garantizado",
39
+ text: "Al seleccionar este servicio aseguras el precio reducido.",
40
+ },
41
+ {
42
+ icon: "ticket",
43
+ name: "4. ¡Listo!",
44
+ text: "Recibe todos los detalles de tu viaje al instante tras la compra.",
45
+ },
46
+ ];
47
+ const FeatureStepIcon = ({ icon }) => {
48
+ const iconClassName = "h-[30px] w-[30px] text-[#171717]";
49
+ switch (icon) {
50
+ case "flexible":
51
+ return (React.createElement("svg", { className: iconClassName, viewBox: "0 0 40 40", fill: "none", "aria-hidden": "true" },
52
+ React.createElement("path", { d: "M31.5 13.4A13 13 0 0 0 8 12.3", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round" }),
53
+ React.createElement("path", { d: "m7.4 7.7.2 5.2 5.1-1.2M8.5 26.6A13 13 0 0 0 32 27.7", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round" }),
54
+ React.createElement("path", { d: "m32.6 32.3-.2-5.2-5.1 1.2", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round" })));
55
+ case "bus":
56
+ return (React.createElement("svg", { className: iconClassName, viewBox: "0 0 40 40", fill: "none", "aria-hidden": "true" },
57
+ React.createElement("rect", { x: "8", y: "4.5", width: "24", height: "27", rx: "2.5", stroke: "currentColor", strokeWidth: "2.2" }),
58
+ React.createElement("path", { d: "M8 18.5h24M12 9h16M12 26h4m8 0h4M11 31.5v3h5v-3m8 0v3h5v-3M5.5 10v7m29-7v7", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round" })));
59
+ case "price":
60
+ return (React.createElement("svg", { className: iconClassName, viewBox: "0 0 40 40", fill: "none", "aria-hidden": "true" },
61
+ React.createElement("circle", { cx: "20", cy: "20", r: "14", stroke: "currentColor", strokeWidth: "2.2" }),
62
+ React.createElement("path", { d: "M23.7 15.4c-1-.7-2.2-1-3.6-1-2.2 0-3.8 1.1-3.8 2.8 0 4.2 7.4 1.8 7.4 5.8 0 1.8-1.6 2.8-4 2.8-1.5 0-2.9-.4-4-1.2M20 11.7v2.5m0 11.8v2.4", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round" })));
63
+ default:
64
+ return (React.createElement("svg", { className: iconClassName, viewBox: "0 0 40 40", fill: "none", "aria-hidden": "true" },
65
+ React.createElement("path", { d: "M7 11h26v6a3.5 3.5 0 0 0 0 7v6H7v-6a3.5 3.5 0 0 0 0-7v-6Z", stroke: "currentColor", strokeWidth: "2.2", strokeLinejoin: "round" }),
66
+ React.createElement("path", { d: "M22 12.5v3m0 3v3m0 3v4", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round" })));
67
+ }
68
+ };
69
+ const AssuranceIcon = ({ type }) => {
70
+ const iconClassName = "h-[18px] w-[18px] shrink-0 text-white";
71
+ if (type === "pending") {
72
+ return (React.createElement("svg", { className: iconClassName, viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true" },
73
+ React.createElement("path", { d: "M4.2 8.2a6.2 6.2 0 1 1 .5 5.1", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }),
74
+ React.createElement("path", { d: "M4.2 4.8v3.4h3.4", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" })));
75
+ }
76
+ return (React.createElement("svg", { className: iconClassName, viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true" },
77
+ React.createElement("path", { d: "M10 2.2 16.3 4v5c0 4-2.4 6.8-6.3 8.7C6.1 15.8 3.7 13 3.7 9V4L10 2.2Z", stroke: "currentColor", strokeWidth: "1.6", strokeLinejoin: "round" }),
78
+ React.createElement("path", { d: "m6.9 9.7 2.1 2.1 4.3-4.4", stroke: "currentColor", strokeWidth: "1.7", strokeLinecap: "round", strokeLinejoin: "round" })));
79
+ };
80
+ const FeatureServiceUi = ({ serviceItem, showTopLabel, colors, isSoldOut, getAnimationIcon, cityOrigin, cityDestination, renderIcon, viewersConfig, }) => {
81
+ var _a, _b, _c, _d, _e;
20
82
  const operators = ((_a = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.operators) === null || _a === void 0 ? void 0 : _a.length) > 0
21
83
  ? serviceItem.operators
22
84
  : HARDCODED_OPERATORS;
@@ -25,10 +87,36 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, colors, isSoldOut, getAni
25
87
  showTopLabel
26
88
  ? "mt-[24px]"
27
89
  : "mt-[20px]"}` },
28
- React.createElement("div", null,
90
+ React.createElement("div", { className: "", style: {
91
+ border: "1px solid #c0c0c0",
92
+ padding: "14px",
93
+ borderRadius: "14px",
94
+ } },
95
+ React.createElement("div", { className: "flex justify-between items-center px-[14px] pb-[10px] text-[13.33px]" },
96
+ React.createElement("div", { className: "flex items-center gap-[10px]" },
97
+ React.createElement("span", null, "Salida flexible"),
98
+ React.createElement("div", { className: "bold-text font-[9px]", style: {
99
+ backgroundColor: "#FF5C60",
100
+ padding: "1px 8px",
101
+ borderRadius: "4px",
102
+ color: "#fff",
103
+ } },
104
+ React.createElement("span", null, "AHORRAS 60%"))),
105
+ React.createElement("div", null,
106
+ React.createElement("span", null,
107
+ renderIcon("fireIcon", "14px"),
108
+ " ",
109
+ React.createElement("span", { className: "bold-text" }, "Remate"),
110
+ " t\u00E9rmina en",
111
+ " ",
112
+ React.createElement("span", { className: "bold-text text-end", ref: (node) => commonService.startCountdown(node, 599), style: {
113
+ fontVariantNumeric: "tabular-nums",
114
+ display: "inline-block",
115
+ color: "#FF5C60",
116
+ } })))),
29
117
  React.createElement("div", { id: `service-card-${serviceItem.id}`, className: "bg-[#0C1421] text-white mx-auto relative rounded-[14px] p-[14px] text-[13.33px]" },
30
118
  React.createElement("div", { className: "grid grid-cols-[1.3fr_2fr_1.2fr] gap-[16px] items-stretch" },
31
- React.createElement("div", { className: "flex flex-col justify-between gap-[20px] py-[2px]" },
119
+ React.createElement("div", { className: "flex flex-col justify-between gap-[20px] py-[2px] " },
32
120
  React.createElement("div", { className: "flex flex-col gap-[8px]" },
33
121
  React.createElement("div", { className: "flex items-center gap-[8px]" },
34
122
  React.createElement("img", { src: (_b = serviceItem.icons) === null || _b === void 0 ? void 0 : _b.whiteOrigin, alt: "origin", className: `w-[14px] h-[14px] shrink-0 ${isSoldOut ? "grayscale" : ""}` }),
@@ -37,40 +125,64 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, colors, isSoldOut, getAni
37
125
  React.createElement("img", { src: (_c = serviceItem.icons) === null || _c === void 0 ? void 0 : _c.whiteDestination, alt: "destination", className: `w-[16px] h-[16px] shrink-0 ${isSoldOut ? "grayscale" : ""}`, style: { opacity: isSoldOut ? 0.5 : 1 } }),
38
126
  React.createElement("span", { className: "text-[13px] bold-text" }, cityDestination === null || cityDestination === void 0 ? void 0 : cityDestination.label.split(",")[0]))),
39
127
  React.createElement("div", { className: "flex flex-col gap-[8px]" },
40
- React.createElement("div", { className: "flex items-center gap-[6px] rounded-[8px] px-[8px] py-[4px] w-fit mb-[6px]", style: {
41
- border: "1px solid #363c48",
42
- backgroundColor: "#1a202e",
43
- } },
44
- React.createElement("img", { src: (_d = serviceItem.icons) === null || _d === void 0 ? void 0 : _d.busIcon, alt: "bus", style: { width: "20px", height: "20px" } }),
45
- React.createElement("span", { className: "text-[12px] whitespace-nowrap" }, "Salida flexible")),
46
- React.createElement("div", { className: "text-[13px] bold-text whitespace-nowrap" }, "07:00 AM \u2013 10:00 AM"),
47
- React.createElement("div", { className: "text-[12px] bold-text" }, "Vie, 04/11")),
48
- React.createElement("div", { className: "flex items-start gap-[6px] text-[12px] " },
49
- React.createElement("img", { src: (_e = serviceItem.icons) === null || _e === void 0 ? void 0 : _e.sheildIcon, alt: "shield", style: { width: "14px", height: "14px" } }),
50
- React.createElement("span", null, "Tu asiento confirmado al instante."))),
51
- React.createElement("div", { className: "px-[16px] flex flex-col items-center justify-between gap-[12px] py-[2px]" },
128
+ React.createElement("div", { className: "text-[12px] bold-text whitespace-nowrap" }, "Entre 07:00 AM y 10:00 AM"),
129
+ React.createElement("div", { className: "text-[11px] bold-text" }, "Viernes 23 de mayo")),
130
+ React.createElement("div", { className: "flex flex-col items-start gap-[10px] text-[12px] " },
131
+ React.createElement("div", { className: "flex items-center gap-[8px]" },
132
+ React.createElement(AssuranceIcon, { type: "pending" }),
133
+ React.createElement("span", { className: "text-[10px]", style: {
134
+ lineHeight: 1.3,
135
+ } }, "Empresa y hora a confirmar luego del pago.")),
136
+ React.createElement("div", { className: "flex items-center gap-[8px]" },
137
+ React.createElement(AssuranceIcon, { type: "secured" }),
138
+ React.createElement("span", { className: "text-[10px]", style: {
139
+ lineHeight: 1.3,
140
+ } }, "Tu compra est\u00E1 100% asegurada.")))),
141
+ React.createElement("div", { className: "px-[16px] flex flex-col items-center justify-between gap-[12px] py-[2px] border-r border-[#363c48] border-l border-[#363c48]" },
52
142
  React.createElement("div", { className: "text-center" },
53
- React.createElement("div", { className: "bold-text text-[14px]" }, "3 operadores compitiendo por tu compra"),
54
- React.createElement("div", { className: "text-[12px] mt-[8px]" }, "Empresa a confirmar despu\u00E9s de tu pago")),
143
+ React.createElement("div", { className: "bold-text text-[14px]" }, "3 operadores compitiendo por tu compra")),
55
144
  React.createElement("div", { className: "flex items-stretch justify-center gap-[8px] w-full mb-[16px]" }, operators.map((op, idx) => (React.createElement("div", { key: idx, className: "flex flex-col items-center justify-center gap-[8px] rounded-[8px]", style: {
56
145
  width: "140px",
57
- height: "80px",
146
+ // height: "80px",
58
147
  border: "1px solid #363c48",
59
148
  backgroundColor: "#1a202e",
149
+ padding: "14px",
60
150
  } },
61
151
  React.createElement("img", { src: serviceItem.operator_details[0], alt: op.name, className: `h-[24px] w-auto object-contain ${isSoldOut ? "grayscale" : ""}` }),
62
- React.createElement("span", { className: "text-[11px] truncate max-w-full text-center" }, serviceItem.operator_details[2]))))),
63
- React.createElement("div", { className: "flex items-center gap-[6px] text-[12px]" },
64
- React.createElement("img", { src: (_f = serviceItem.icons) === null || _f === void 0 ? void 0 : _f.userIcon, alt: "eye", style: { width: "16px", height: "16px" } }),
152
+ React.createElement("span", { className: "text-[11px] truncate max-w-full text-center" }, serviceItem.operator_details[2]),
153
+ React.createElement("div", { className: "bg-[#FF8F45] text-white text-[12px] font-bold px-[16px] py-[4px] rounded-[4px] bold-text" },
154
+ React.createElement("span", null, op === null || op === void 0 ? void 0 : op.time)),
155
+ React.createElement("span", { className: "text-[10px] mt-[6px]" }, op === null || op === void 0 ? void 0 : op.seatsAvailable))))),
156
+ React.createElement("div", { className: "flex items-center justify-center gap-[6px] text-[12px]", style: {
157
+ border: "1px solid #363c48",
158
+ backgroundColor: "#1a202e",
159
+ padding: "8px 14px",
160
+ borderRadius: "24px",
161
+ width: "430px",
162
+ } },
163
+ React.createElement("img", { src: (_d = serviceItem.icons) === null || _d === void 0 ? void 0 : _d.userIcon, alt: "eye", style: { width: "16px", height: "16px" } }),
65
164
  React.createElement("span", null,
66
- React.createElement("span", { className: "bold-text text-white" }, "50 personas"),
165
+ React.createElement("span", { className: "bold-text text-white" },
166
+ " ",
167
+ React.createElement("span", { className: "bold-text", ref: (node) => commonService.startViewerCount(node, viewersConfig), style: {
168
+ fontVariantNumeric: "tabular-nums",
169
+ color: "#FF5C60",
170
+ } }),
171
+ " ",
172
+ React.createElement("span", { style: {
173
+ color: "#FF5C60",
174
+ } }, "personas")),
175
+ " ",
176
+ "viendo este viaje |",
177
+ " ",
178
+ React.createElement("span", { className: "bold-text", ref: (node) => commonService.startComprandoCount(node, 4, 16), style: { fontVariantNumeric: "tabular-nums" } }),
67
179
  " ",
68
- "est\u00E1n viendo este viaje"))),
180
+ "han comprado"))),
69
181
  React.createElement("div", { className: "flex flex-col justify-center gap-[12px] py-[2px] relative mb-[16px]" },
70
182
  React.createElement("div", { className: "flex flex-col gap-[6px] ", style: {
71
183
  alignItems: "center",
72
184
  } },
73
- React.createElement("span", { className: "text-[#FF8F45] bold-text text-[22px] leading-tight" }, "60% OFF"),
185
+ React.createElement("span", { className: "text-[#FF8F45] bold-text text-[26px] leading-tight" }, "60% OFF"),
74
186
  React.createElement("span", { className: "text-[#666] text-[14px] line-through" }, "$10.000"),
75
187
  React.createElement("span", { className: "text-white bold-text text-[28px] leading-none" }, "$4.000")),
76
188
  React.createElement("button", { className: "flex items-center gap-[6px] px-[20px] py-[10px] rounded-[12px] text-white bold-text text-[13px] mt-[4px] justify-center border-none cursor-pointer", style: {
@@ -83,19 +195,16 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, colors, isSoldOut, getAni
83
195
  animationData: getAnimationIcon("thunderAnimation"), width: "18px", height: "18px" }),
84
196
  React.createElement("span", { className: "whitespace-nowrap" }, "\u00A1Lo quiero!"))),
85
197
  React.createElement("div", { className: "absolute bottom-[11px] right-[18px]" },
86
- React.createElement("img", { src: (_g = serviceItem.icons) === null || _g === void 0 ? void 0 : _g.downArrow, alt: "down arrow", style: {
198
+ React.createElement("img", { src: (_e = serviceItem.icons) === null || _e === void 0 ? void 0 : _e.downArrow, alt: "down arrow", style: {
87
199
  width: "14px",
88
200
  height: "8px",
89
201
  filter: "brightness(0) invert(1)",
90
- } }))))),
91
- React.createElement("div", { className: "absolute -top-[11px] left-0 w-full flex items-center justify-end gap-[12px] pr-[15px] z-10 " },
92
- React.createElement("div", { className: "flex items-center gap-[6px] py-[5px] px-[14px] rounded-[38px] text-[12.5px] bg-[#FF8F45] text-white whitespace-nowrap" },
93
- React.createElement(LottiePlayer, { animationData: getAnimationIcon("bombAnimation"), width: "14px", height: "14px" }),
94
- React.createElement("span", null,
95
- React.createElement("strong", null, "Remate"),
96
- " | Termina en",
97
- " ",
98
- React.createElement("strong", null, HARDCODED_COUNTDOWN),
99
- " min")))));
202
+ } })))),
203
+ React.createElement("div", { className: "px-[16px] pt-[14px] pb-[6px] text-[13.33px]" },
204
+ React.createElement("span", { className: "bold-text" }, "\u00BFC\u00F3mo funciona?"),
205
+ React.createElement("div", { className: "mt-[14px] grid grid-cols-4 gap-[20px] px-[16px] " }, HOW_IT_WORKS_STEPS.map((step) => (React.createElement("div", { key: step.name, className: "flex flex-col items-center text-center text-[#272727]" },
206
+ React.createElement(FeatureStepIcon, { icon: step.icon }),
207
+ React.createElement("span", { className: "bold-text mt-[10px] text-[12px] leading-[14px]" }, step.name),
208
+ React.createElement("span", { className: "mt-[2px] max-w-[220px] text-[12px] leading-[14px] text-[#4a4a4a]" }, step.text)))))))));
100
209
  };
101
210
  export default FeatureServiceUi;
@@ -15,12 +15,7 @@ const StageTooltip = ({ children, stageData, direction = 1, terminals, serviceIt
15
15
  let terminal = arr[i].split("||")[1];
16
16
  let locationName = (terminals === null || terminals === void 0 ? void 0 : terminals[arr[i].split("||")[0].split("|")[0]]) || "";
17
17
  let time = arr[i].split("||")[0].split("|")[1];
18
- if (direction !== 1 && i > 0) {
19
- // skip logic (same as yours)
20
- }
21
- else {
22
- formattedStages.push(`${locationName} ${time}`);
23
- }
18
+ formattedStages.push(`${locationName || terminal} ${time}`);
24
19
  }
25
20
  const extractTiming = (location) => {
26
21
  const timingIndex = location.lastIndexOf(" ") + 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kupos-ui-components-lib",
3
- "version": "9.6.6",
3
+ "version": "9.6.7",
4
4
  "description": "A reusable UI components package",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -0,0 +1 @@
1
+ {"nm":"t","ddd":0,"h":500,"w":500,"meta":{"g":"@lottiefiles/toolkit-js 0.33.2"},"layers":[{"ty":4,"nm":"t","sr":1,"st":60,"op":90,"ip":60,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[256.655,268,0]},"s":{"a":0,"k":[100,100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[256.655,268,0]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":89},{"s":[0],"t":90}]}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"nm":"0","it":[{"ty":"sh","bm":0,"hd":false,"nm":"パ","d":1,"ks":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-35.799,-108.024],[135.03,-108.024],[135.015,-107.976],[-35.905,-107.905]]}],"t":60},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-35.799,-108.024],[135.03,-108.024],[-48.36,108.024],[-135.03,96.72]]}],"t":66}]}},{"ty":"fl","bm":0,"hd":false,"nm":"塗","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":60},{"s":[100],"t":61}]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[245.351,170.024]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]},{"ty":"gr","bm":0,"hd":false,"nm":"0","it":[{"ty":"sh","bm":0,"hd":false,"nm":"パ","d":1,"ks":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-146.335,21.917],[-146.203,22.157],[-111.091,-49.844],[-111.165,-49.681]]}],"t":66},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-146.335,21.917],[66.749,49.681],[146.335,-25.815],[-111.165,-49.681]]}],"t":72}]}},{"ty":"fl","bm":0,"hd":false,"nm":"塗","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":66},{"s":[100],"t":67}]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[256.655,244.827]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]},{"ty":"gr","bm":0,"hd":false,"nm":"0","it":[{"ty":"sh","bm":0,"hd":false,"nm":"パ","d":1,"ks":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[85.348,-127.61],[40.195,-131.89],[134.402,-123.098]]}],"t":66},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[54.848,-47.61],[40.195,-131.89],[134.402,-123.098]]}],"t":72},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-134.402,131.89],[40.195,-131.89],[134.402,-123.098]]}],"t":78}]}},{"ty":"fl","bm":0,"hd":false,"nm":"塗","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":72},{"s":[100],"t":73}]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[268.588,342.11]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]}],"ind":1},{"ty":4,"nm":"t","sr":1,"st":30,"op":60,"ip":30,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[256.655,268,0]},"s":{"a":0,"k":[100,100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[256.655,268,0]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":59},{"s":[0],"t":60}]}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"nm":"0","it":[{"ty":"sh","bm":0,"hd":false,"nm":"パ","d":1,"ks":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-35.799,-108.024],[135.03,-108.024],[135.015,-107.976],[-35.905,-107.905]]}],"t":30},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-35.799,-108.024],[135.03,-108.024],[-48.36,108.024],[-135.03,96.72]]}],"t":36}]}},{"ty":"fl","bm":0,"hd":false,"nm":"塗","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":30},{"s":[100],"t":31}]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[245.351,170.024]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]},{"ty":"gr","bm":0,"hd":false,"nm":"0","it":[{"ty":"sh","bm":0,"hd":false,"nm":"パ","d":1,"ks":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-146.335,21.917],[-146.203,22.157],[-111.091,-49.844],[-111.165,-49.681]]}],"t":36},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-146.335,21.917],[66.749,49.681],[146.335,-25.815],[-111.165,-49.681]]}],"t":42}]}},{"ty":"fl","bm":0,"hd":false,"nm":"塗","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":36},{"s":[100],"t":37}]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[256.655,244.827]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]},{"ty":"gr","bm":0,"hd":false,"nm":"0","it":[{"ty":"sh","bm":0,"hd":false,"nm":"パ","d":1,"ks":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[85.348,-127.61],[40.195,-131.89],[134.402,-123.098]]}],"t":36},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[54.848,-47.61],[40.195,-131.89],[134.402,-123.098]]}],"t":42},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-134.402,131.89],[40.195,-131.89],[134.402,-123.098]]}],"t":48}]}},{"ty":"fl","bm":0,"hd":false,"nm":"塗","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":42},{"s":[100],"t":43}]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[268.588,342.11]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]}],"ind":2},{"ty":4,"nm":"t","sr":1,"st":0,"op":30,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[256.655,268,0]},"s":{"a":0,"k":[100,100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[256.655,268,0]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":29},{"s":[0],"t":30}]}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"nm":"0","it":[{"ty":"sh","bm":0,"hd":false,"nm":"パ","d":1,"ks":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-35.799,-108.024],[135.03,-108.024],[135.015,-107.976],[-35.905,-107.905]]}],"t":0},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-35.799,-108.024],[135.03,-108.024],[-48.36,108.024],[-135.03,96.72]]}],"t":6}]}},{"ty":"fl","bm":0,"hd":false,"nm":"塗","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":0},{"s":[100],"t":1}]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[245.351,170.024]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]},{"ty":"gr","bm":0,"hd":false,"nm":"0","it":[{"ty":"sh","bm":0,"hd":false,"nm":"パ","d":1,"ks":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-146.335,21.917],[-146.203,22.157],[-111.091,-49.844],[-111.165,-49.681]]}],"t":6},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-146.335,21.917],[66.749,49.681],[146.335,-25.815],[-111.165,-49.681]]}],"t":12}]}},{"ty":"fl","bm":0,"hd":false,"nm":"塗","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":6},{"s":[100],"t":7}]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[256.655,244.827]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]},{"ty":"gr","bm":0,"hd":false,"nm":"0","it":[{"ty":"sh","bm":0,"hd":false,"nm":"パ","d":1,"ks":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[85.348,-127.61],[40.195,-131.89],[134.402,-123.098]]}],"t":6},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[54.848,-47.61],[40.195,-131.89],[134.402,-123.098]]}],"t":12},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-134.402,131.89],[40.195,-131.89],[134.402,-123.098]]}],"t":18}]}},{"ty":"fl","bm":0,"hd":false,"nm":"塗","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":12},{"s":[100],"t":13}]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[268.588,342.11]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]}],"ind":3}],"v":"5.9.0","fr":30,"op":90,"ip":0,"assets":[]}
@@ -37,6 +37,9 @@ import KuposButton from "../../ui/KuposButton/KuposButton";
37
37
  import BottomAmenities from "../../ui/BottomAmenities/BottomAmenities";
38
38
  import SeatSection from "../../ui/SeatSection/SeatSection";
39
39
  import DateTimeSection from "../../ui/DateTimeSection/DateTimeSection";
40
+ import FeatureServiceUi from "../../ui/FeatureServiceUI/FeatureServiceUi";
41
+
42
+ import thunderAnimation from "../../assets/images/anims/service_list/thunder_icon.json";
40
43
  import ServiceBadges from "../../ui/ServiceBadges/ServiceBadges";
41
44
 
42
45
  const SEAT_EXCEPTIONS = ["Asiento mascota"];
@@ -71,6 +74,9 @@ const ANIMATION_MAP: Record<string, Record<string, any>> = {
71
74
  bombAnimation: {
72
75
  kupos: bombAnimation,
73
76
  },
77
+ thunderAnimation: {
78
+ kupos: thunderAnimation,
79
+ },
74
80
  dotAnimation: {
75
81
  kupos: dotAnimation,
76
82
  },
@@ -113,9 +119,10 @@ function ServiceItemPB({
113
119
  setIsExpand,
114
120
  coachKey,
115
121
  viewersConfig,
122
+ isNewUi,
116
123
  showLoginModal,
117
124
  isLoggedIn,
118
- showLoginOption
125
+ showLoginOption,
119
126
  }: ServiceItemProps & { currencySign?: string }): React.ReactElement {
120
127
  const getAnimationIcon = (icon: string) => {
121
128
  const animation = ANIMATION_MAP[icon];
@@ -415,6 +422,18 @@ function ServiceItemPB({
415
422
  siteType={siteType}
416
423
  isAllinBus={isAllinBus}
417
424
  />
425
+ ) : isNewUi ? (
426
+ <FeatureServiceUi
427
+ serviceItem={serviceItem}
428
+ showTopLabel={showTopLabel}
429
+ colors={colors}
430
+ isSoldOut={isSoldOut}
431
+ getAnimationIcon={getAnimationIcon}
432
+ cityOrigin={cityOrigin}
433
+ cityDestination={cityDestination}
434
+ renderIcon={renderIcon}
435
+ viewersConfig={viewersConfig}
436
+ />
418
437
  ) : (
419
438
  <div
420
439
  className={`relative hover:z-[150] ${hasOfferText || hasDpEnabled ? "mb-[55px]" : "mb-[10px]"} ${
@@ -132,6 +132,13 @@ export interface ServiceItemProps {
132
132
  whiteFireIcon?: string
133
133
  fireIcon?: string
134
134
 
135
+ whiteOrigin?: string,
136
+ whiteDestination?: string,
137
+ userIcon?: string,
138
+ sheildIcon?: string,
139
+ busIcon?: string,
140
+ whiteDownArrow?: string,
141
+
135
142
  [key: string]: string | Record<string, string | undefined> | undefined;
136
143
  };
137
144
  useLottieFor?: string[];
@@ -223,6 +230,7 @@ export interface ServiceItemProps {
223
230
  label?: string; // e.g. "personas están viendo este viaje"
224
231
  icon?: string; // optional icon URL
225
232
  };
233
+ isNewUi?: boolean
226
234
  showLoginModal?: any
227
235
  isLoggedIn?: any
228
236
  showLoginOption?: boolean
@@ -0,0 +1,547 @@
1
+ import React from "react";
2
+ import LottiePlayer from "../../assets/LottiePlayer";
3
+ import commonService from "../../utils/CommonService";
4
+
5
+ const HARDCODED_OPERATORS = [
6
+ {
7
+ logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Turbus_logo.svg/320px-Turbus_logo.svg.png",
8
+ name: "Turbus",
9
+ time: "7:00 am",
10
+ seatsAvailable: "3 disponibles",
11
+ },
12
+ {
13
+ logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Pullman_Bus_logo.svg/320px-Pullman_Bus_logo.svg.png",
14
+ name: "Pullmanbus",
15
+ time: "8:00 am",
16
+ seatsAvailable: "5 disponibles",
17
+ },
18
+ {
19
+ logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Turbus_logo.svg/320px-Turbus_logo.svg.png",
20
+ name: "Expreso Santa C...",
21
+ time: "9:00 am",
22
+ seatsAvailable: "3 disponibles",
23
+ },
24
+ ];
25
+
26
+ const HARDCODED_COUNTDOWN = "09:55";
27
+
28
+ const HOW_IT_WORKS_STEPS = [
29
+ {
30
+ icon: "flexible",
31
+ name: "1. Salida flexible",
32
+ text: "Viajas en un horario entre las 07:00 y las 10:00 AM del día elegido.",
33
+ },
34
+ {
35
+ icon: "bus",
36
+ name: "2. Empresa asignada",
37
+ text: "Una de las empresas disponibles confirma tu viaje una vez pagado.",
38
+ },
39
+ {
40
+ icon: "price",
41
+ name: "3. Precio garantizado",
42
+ text: "Al seleccionar este servicio aseguras el precio reducido.",
43
+ },
44
+ {
45
+ icon: "ticket",
46
+ name: "4. ¡Listo!",
47
+ text: "Recibe todos los detalles de tu viaje al instante tras la compra.",
48
+ },
49
+ ];
50
+
51
+ const FeatureStepIcon = ({ icon }) => {
52
+ const iconClassName = "h-[30px] w-[30px] text-[#171717]";
53
+
54
+ switch (icon) {
55
+ case "flexible":
56
+ return (
57
+ <svg
58
+ className={iconClassName}
59
+ viewBox="0 0 40 40"
60
+ fill="none"
61
+ aria-hidden="true"
62
+ >
63
+ <path
64
+ d="M31.5 13.4A13 13 0 0 0 8 12.3"
65
+ stroke="currentColor"
66
+ strokeWidth="2.2"
67
+ strokeLinecap="round"
68
+ />
69
+ <path
70
+ d="m7.4 7.7.2 5.2 5.1-1.2M8.5 26.6A13 13 0 0 0 32 27.7"
71
+ stroke="currentColor"
72
+ strokeWidth="2.2"
73
+ strokeLinecap="round"
74
+ strokeLinejoin="round"
75
+ />
76
+ <path
77
+ d="m32.6 32.3-.2-5.2-5.1 1.2"
78
+ stroke="currentColor"
79
+ strokeWidth="2.2"
80
+ strokeLinecap="round"
81
+ strokeLinejoin="round"
82
+ />
83
+ </svg>
84
+ );
85
+ case "bus":
86
+ return (
87
+ <svg
88
+ className={iconClassName}
89
+ viewBox="0 0 40 40"
90
+ fill="none"
91
+ aria-hidden="true"
92
+ >
93
+ <rect
94
+ x="8"
95
+ y="4.5"
96
+ width="24"
97
+ height="27"
98
+ rx="2.5"
99
+ stroke="currentColor"
100
+ strokeWidth="2.2"
101
+ />
102
+ <path
103
+ d="M8 18.5h24M12 9h16M12 26h4m8 0h4M11 31.5v3h5v-3m8 0v3h5v-3M5.5 10v7m29-7v7"
104
+ stroke="currentColor"
105
+ strokeWidth="2.2"
106
+ strokeLinecap="round"
107
+ />
108
+ </svg>
109
+ );
110
+ case "price":
111
+ return (
112
+ <svg
113
+ className={iconClassName}
114
+ viewBox="0 0 40 40"
115
+ fill="none"
116
+ aria-hidden="true"
117
+ >
118
+ <circle
119
+ cx="20"
120
+ cy="20"
121
+ r="14"
122
+ stroke="currentColor"
123
+ strokeWidth="2.2"
124
+ />
125
+ <path
126
+ d="M23.7 15.4c-1-.7-2.2-1-3.6-1-2.2 0-3.8 1.1-3.8 2.8 0 4.2 7.4 1.8 7.4 5.8 0 1.8-1.6 2.8-4 2.8-1.5 0-2.9-.4-4-1.2M20 11.7v2.5m0 11.8v2.4"
127
+ stroke="currentColor"
128
+ strokeWidth="2.2"
129
+ strokeLinecap="round"
130
+ />
131
+ </svg>
132
+ );
133
+ default:
134
+ return (
135
+ <svg
136
+ className={iconClassName}
137
+ viewBox="0 0 40 40"
138
+ fill="none"
139
+ aria-hidden="true"
140
+ >
141
+ <path
142
+ d="M7 11h26v6a3.5 3.5 0 0 0 0 7v6H7v-6a3.5 3.5 0 0 0 0-7v-6Z"
143
+ stroke="currentColor"
144
+ strokeWidth="2.2"
145
+ strokeLinejoin="round"
146
+ />
147
+ <path
148
+ d="M22 12.5v3m0 3v3m0 3v4"
149
+ stroke="currentColor"
150
+ strokeWidth="2.2"
151
+ strokeLinecap="round"
152
+ />
153
+ </svg>
154
+ );
155
+ }
156
+ };
157
+
158
+ const AssuranceIcon = ({ type }) => {
159
+ const iconClassName = "h-[18px] w-[18px] shrink-0 text-white";
160
+
161
+ if (type === "pending") {
162
+ return (
163
+ <svg
164
+ className={iconClassName}
165
+ viewBox="0 0 20 20"
166
+ fill="none"
167
+ aria-hidden="true"
168
+ >
169
+ <path
170
+ d="M4.2 8.2a6.2 6.2 0 1 1 .5 5.1"
171
+ stroke="currentColor"
172
+ strokeWidth="1.8"
173
+ strokeLinecap="round"
174
+ />
175
+ <path
176
+ d="M4.2 4.8v3.4h3.4"
177
+ stroke="currentColor"
178
+ strokeWidth="1.8"
179
+ strokeLinecap="round"
180
+ strokeLinejoin="round"
181
+ />
182
+ </svg>
183
+ );
184
+ }
185
+
186
+ return (
187
+ <svg
188
+ className={iconClassName}
189
+ viewBox="0 0 20 20"
190
+ fill="none"
191
+ aria-hidden="true"
192
+ >
193
+ <path
194
+ d="M10 2.2 16.3 4v5c0 4-2.4 6.8-6.3 8.7C6.1 15.8 3.7 13 3.7 9V4L10 2.2Z"
195
+ stroke="currentColor"
196
+ strokeWidth="1.6"
197
+ strokeLinejoin="round"
198
+ />
199
+ <path
200
+ d="m6.9 9.7 2.1 2.1 4.3-4.4"
201
+ stroke="currentColor"
202
+ strokeWidth="1.7"
203
+ strokeLinecap="round"
204
+ strokeLinejoin="round"
205
+ />
206
+ </svg>
207
+ );
208
+ };
209
+
210
+ const FeatureServiceUi = ({
211
+ serviceItem,
212
+ showTopLabel,
213
+ colors,
214
+ isSoldOut,
215
+ getAnimationIcon,
216
+ cityOrigin,
217
+ cityDestination,
218
+ renderIcon,
219
+ viewersConfig,
220
+ }) => {
221
+ const operators =
222
+ serviceItem?.operators?.length > 0
223
+ ? serviceItem.operators
224
+ : HARDCODED_OPERATORS;
225
+
226
+ return (
227
+ <div
228
+ className={`relative ${
229
+ serviceItem.offer_text ? "mb-[55px]" : "mb-[10px]"
230
+ } ${
231
+ serviceItem?.is_direct_trip ||
232
+ serviceItem?.train_type_label === "Tren Express (Nuevo)" ||
233
+ showTopLabel
234
+ ? "mt-[24px]"
235
+ : "mt-[20px]"
236
+ }`}
237
+ >
238
+ <div
239
+ className=""
240
+ style={{
241
+ border: "1px solid #c0c0c0",
242
+ padding: "14px",
243
+ borderRadius: "14px",
244
+ }}
245
+ >
246
+ <div className="flex justify-between items-center px-[14px] pb-[10px] text-[13.33px]">
247
+ <div className="flex items-center gap-[10px]">
248
+ <span>Salida flexible</span>
249
+ <div
250
+ className="bold-text font-[9px]"
251
+ style={{
252
+ backgroundColor: "#FF5C60",
253
+ padding: "1px 8px",
254
+ borderRadius: "4px",
255
+ color: "#fff",
256
+ }}
257
+ >
258
+ <span>AHORRAS 60%</span>
259
+ </div>
260
+ </div>
261
+ <div>
262
+ <span>
263
+ {renderIcon("fireIcon", "14px")}{" "}
264
+ <span className="bold-text">Remate</span> términa en{" "}
265
+ <span
266
+ className="bold-text text-end"
267
+ ref={(node) => commonService.startCountdown(node, 599)}
268
+ style={{
269
+ fontVariantNumeric: "tabular-nums",
270
+ display: "inline-block",
271
+ color: "#FF5C60",
272
+ }}
273
+ />
274
+ </span>
275
+ </div>
276
+ </div>
277
+ <div
278
+ id={`service-card-${serviceItem.id}`}
279
+ className="bg-[#0C1421] text-white mx-auto relative rounded-[14px] p-[14px] text-[13.33px]"
280
+ >
281
+ <div className="grid grid-cols-[1.3fr_2fr_1.2fr] gap-[16px] items-stretch">
282
+ {/* LEFT: origin, destination, flexible, time, confirmed seat */}
283
+ <div className="flex flex-col justify-between gap-[20px] py-[2px] ">
284
+ <div className="flex flex-col gap-[8px]">
285
+ <div className="flex items-center gap-[8px]">
286
+ <img
287
+ src={serviceItem.icons?.whiteOrigin}
288
+ alt="origin"
289
+ className={`w-[14px] h-[14px] shrink-0 ${
290
+ isSoldOut ? "grayscale" : ""
291
+ }`}
292
+ />
293
+ <span className="text-[13px] bold-text">
294
+ {cityOrigin?.label.split(",")[0]}
295
+ </span>
296
+ </div>
297
+ <div className="flex items-center gap-[8px]">
298
+ <img
299
+ src={serviceItem.icons?.whiteDestination}
300
+ alt="destination"
301
+ className={`w-[16px] h-[16px] shrink-0 ${
302
+ isSoldOut ? "grayscale" : ""
303
+ }`}
304
+ style={{ opacity: isSoldOut ? 0.5 : 1 }}
305
+ />
306
+ <span className="text-[13px] bold-text">
307
+ {cityDestination?.label.split(",")[0]}
308
+ </span>
309
+ </div>
310
+ </div>
311
+
312
+ <div className="flex flex-col gap-[8px]">
313
+ {/* Salida flexible badge — uses flexibleIcon */}
314
+ {/* <div
315
+ className="flex items-center gap-[6px] rounded-[8px] px-[8px] py-[4px] w-fit mb-[6px]"
316
+ style={{
317
+ border: "1px solid #363c48",
318
+ backgroundColor: "#1a202e",
319
+ }}
320
+ >
321
+ <img
322
+ src={serviceItem.icons?.busIcon}
323
+ alt="bus"
324
+ style={{ width: "20px", height: "20px" }}
325
+ />
326
+ <span className="text-[12px] whitespace-nowrap">
327
+ Salida flexible
328
+ </span>
329
+ </div> */}
330
+ <div className="text-[12px] bold-text whitespace-nowrap">
331
+ Entre 07:00 AM y 10:00 AM
332
+ </div>
333
+ <div className="text-[11px] bold-text">Viernes 23 de mayo</div>
334
+ </div>
335
+
336
+ <div className="flex flex-col items-start gap-[10px] text-[12px] ">
337
+ <div className="flex items-center gap-[8px]">
338
+ <AssuranceIcon type="pending" />
339
+
340
+ <span
341
+ className="text-[10px]"
342
+ style={{
343
+ lineHeight: 1.3,
344
+ }}
345
+ >
346
+ Empresa y hora a confirmar luego del pago.
347
+ </span>
348
+ </div>
349
+ <div className="flex items-center gap-[8px]">
350
+ <AssuranceIcon type="secured" />
351
+
352
+ <span
353
+ className="text-[10px]"
354
+ style={{
355
+ lineHeight: 1.3,
356
+ }}
357
+ >
358
+ Tu compra está 100% asegurada.
359
+ </span>
360
+ </div>
361
+ </div>
362
+ </div>
363
+
364
+ {/* MIDDLE: competing operators + viewers */}
365
+ <div className="px-[16px] flex flex-col items-center justify-between gap-[12px] py-[2px] border-r border-[#363c48] border-l border-[#363c48]">
366
+ <div className="text-center">
367
+ <div className="bold-text text-[14px]">
368
+ 3 operadores compitiendo por tu compra
369
+ </div>
370
+ {/* <div className="text-[12px] mt-[8px]">
371
+ Empresa a confirmar después de tu pago
372
+ </div> */}
373
+ </div>
374
+
375
+ <div className="flex items-stretch justify-center gap-[8px] w-full mb-[16px]">
376
+ {operators.map((op, idx) => (
377
+ <div
378
+ key={idx}
379
+ className="flex flex-col items-center justify-center gap-[8px] rounded-[8px]"
380
+ style={{
381
+ width: "140px",
382
+ // height: "80px",
383
+ border: "1px solid #363c48",
384
+ backgroundColor: "#1a202e",
385
+ padding: "14px",
386
+ }}
387
+ >
388
+ <img
389
+ src={serviceItem.operator_details[0]}
390
+ alt={op.name}
391
+ className={`h-[24px] w-auto object-contain ${
392
+ isSoldOut ? "grayscale" : ""
393
+ }`}
394
+ />
395
+ <span className="text-[11px] truncate max-w-full text-center">
396
+ {serviceItem.operator_details[2]}
397
+ </span>
398
+ <div className="bg-[#FF8F45] text-white text-[12px] font-bold px-[16px] py-[4px] rounded-[4px] bold-text">
399
+ <span>{op?.time}</span>
400
+ </div>
401
+ <span className="text-[10px] mt-[6px]">
402
+ {op?.seatsAvailable}
403
+ </span>
404
+ </div>
405
+ ))}
406
+ </div>
407
+
408
+ <div
409
+ className="flex items-center justify-center gap-[6px] text-[12px]"
410
+ style={{
411
+ border: "1px solid #363c48",
412
+ backgroundColor: "#1a202e",
413
+ padding: "8px 14px",
414
+ borderRadius: "24px",
415
+ width: "430px",
416
+ }}
417
+ >
418
+ <img
419
+ src={serviceItem.icons?.userIcon}
420
+ alt="eye"
421
+ style={{ width: "16px", height: "16px" }}
422
+ />
423
+ <span>
424
+ <span className="bold-text text-white">
425
+ {" "}
426
+ <span
427
+ className="bold-text"
428
+ ref={(node) =>
429
+ commonService.startViewerCount(node, viewersConfig)
430
+ }
431
+ style={{
432
+ fontVariantNumeric: "tabular-nums",
433
+ color: "#FF5C60",
434
+ }}
435
+ />{" "}
436
+ <span
437
+ style={{
438
+ color: "#FF5C60",
439
+ }}
440
+ >
441
+ personas
442
+ </span>
443
+ </span>{" "}
444
+ viendo este viaje |{" "}
445
+ <span
446
+ className="bold-text"
447
+ ref={(node) =>
448
+ commonService.startComprandoCount(node, 4, 16)
449
+ }
450
+ style={{ fontVariantNumeric: "tabular-nums" }}
451
+ />{" "}
452
+ han comprado
453
+ </span>
454
+ </div>
455
+ </div>
456
+
457
+ {/* RIGHT: price + button */}
458
+ <div className="flex flex-col justify-center gap-[12px] py-[2px] relative mb-[16px]">
459
+ <div
460
+ className="flex flex-col gap-[6px] "
461
+ style={{
462
+ alignItems: "center",
463
+ }}
464
+ >
465
+ <span className="text-[#FF8F45] bold-text text-[26px] leading-tight">
466
+ 60% OFF
467
+ </span>
468
+ <span className="text-[#666] text-[14px] line-through">
469
+ $10.000
470
+ </span>
471
+ <span className="text-white bold-text text-[28px] leading-none">
472
+ $4.000
473
+ </span>
474
+ </div>
475
+
476
+ <button
477
+ className="flex items-center gap-[6px] px-[20px] py-[10px] rounded-[12px] text-white bold-text text-[13px] mt-[4px] justify-center border-none cursor-pointer"
478
+ style={{
479
+ backgroundColor: "#FF5C60",
480
+ }}
481
+ >
482
+ <LottiePlayer
483
+ // animationData={serviceItem.icons.flexibleAnim}
484
+ animationData={getAnimationIcon("thunderAnimation")}
485
+ width="18px"
486
+ height="18px"
487
+ />
488
+ <span className="whitespace-nowrap">¡Lo quiero!</span>
489
+ </button>
490
+ </div>
491
+
492
+ <div className="absolute bottom-[11px] right-[18px]">
493
+ <img
494
+ src={serviceItem.icons?.downArrow}
495
+ alt="down arrow"
496
+ style={{
497
+ width: "14px",
498
+ height: "8px",
499
+ filter: "brightness(0) invert(1)",
500
+ }}
501
+ />
502
+ </div>
503
+ </div>
504
+ </div>
505
+ <div className="px-[16px] pt-[14px] pb-[6px] text-[13.33px]">
506
+ <span className="bold-text">¿Cómo funciona?</span>
507
+
508
+ <div className="mt-[14px] grid grid-cols-4 gap-[20px] px-[16px] ">
509
+ {HOW_IT_WORKS_STEPS.map((step) => (
510
+ <div
511
+ key={step.name}
512
+ className="flex flex-col items-center text-center text-[#272727]"
513
+ >
514
+ <FeatureStepIcon icon={step.icon} />
515
+ <span className="bold-text mt-[10px] text-[12px] leading-[14px]">
516
+ {step.name}
517
+ </span>
518
+ <span className="mt-[2px] max-w-[220px] text-[12px] leading-[14px] text-[#4a4a4a]">
519
+ {step.text}
520
+ </span>
521
+ </div>
522
+ ))}
523
+ </div>
524
+ </div>
525
+ </div>
526
+
527
+ {/* TOP BADGE — "Remate | Termina en 09:55 min" hardcoded, no countdown hook */}
528
+ {/* {showTopLabel && (
529
+ <div className="absolute -top-[11px] left-0 w-full flex items-center justify-end gap-[12px] pr-[15px] z-10 ">
530
+ <div className="flex items-center gap-[6px] py-[5px] px-[14px] rounded-[38px] text-[12.5px] bg-[#FF8F45] text-white whitespace-nowrap">
531
+ <LottiePlayer
532
+ animationData={getAnimationIcon("bombAnimation")}
533
+ width="14px"
534
+ height="14px"
535
+ />
536
+ <span>
537
+ <strong>Remate</strong> | Termina en{" "}
538
+ <strong>{HARDCODED_COUNTDOWN}</strong> min
539
+ </span>
540
+ </div>
541
+ </div>
542
+ )} */}
543
+ </div>
544
+ );
545
+ };
546
+
547
+ export default FeatureServiceUi;
@@ -33,11 +33,7 @@ const StageTooltip = ({
33
33
  terminals?.[arr[i].split("||")[0].split("|")[0]] || "";
34
34
  let time = arr[i].split("||")[0].split("|")[1];
35
35
 
36
- if (direction !== 1 && i > 0) {
37
- // skip logic (same as yours)
38
- } else {
39
- formattedStages.push(`${locationName} ${time}`);
40
- }
36
+ formattedStages.push(`${locationName || terminal} ${time}`);
41
37
  }
42
38
 
43
39
  const extractTiming = (location: string) => {