kupos-ui-components-lib 9.3.9 → 9.3.10

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, }: 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, showLoginModal, isLoggedIn, }: ServiceItemProps & {
4
4
  currencySign?: string;
5
5
  }): React.ReactElement;
6
6
  export default ServiceItemPB;
@@ -66,8 +66,9 @@ const ANIMATION_MAP = {
66
66
  kupos: dotAnimation,
67
67
  },
68
68
  };
69
- 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, }) {
69
+ 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, }) {
70
70
  var _a;
71
+ console.log("🚀 ~ ServiceItemPB ~ serviceItem:", serviceItem);
71
72
  const getAnimationIcon = (icon) => {
72
73
  var _a;
73
74
  const animation = ANIMATION_MAP[icon];
@@ -108,13 +109,14 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
108
109
  const discountedSeats = seats.map((seat) => (Object.assign(Object.assign({}, seat), CommonService.calculateDiscountedPrice(seat.fare, serviceItem))));
109
110
  const hasDiscount = discountedSeats.some((seat) => seat.originalPrice !== seat.discountedPrice);
110
111
  const offerGradient = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"} 0%, ${colors.leftGradiantColor || "#ff8842"} 100%)`;
111
- const serviceCardStyle = hasOfferText
112
+ const serviceCardStyle = hasOfferText || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled)
112
113
  ? {
113
114
  borderColor: "transparent",
114
115
  borderStyle: "solid",
115
- borderWidth: "6px 6px 0 6px",
116
+ borderWidth: "3px 3px 0 3px",
116
117
  borderRadius: isItemExpanded || coachKey ? "18px 18px 0 0" : "18px",
117
118
  background: `linear-gradient(#fff, #fff) padding-box, ${offerGradient} border-box`,
119
+ zIndex: 2,
118
120
  }
119
121
  : {};
120
122
  const renderIcon = (iconKey, size = "14px") => {
@@ -230,12 +232,12 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
230
232
  },
231
233
  ];
232
234
  const otherItems = items.filter((i) => i.key !== "pet" && i.key !== "flexible" && !!i.condition);
233
- 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 ${hasOfferText ? "mb-[55px]" : "mb-[10px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
235
+ 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 ${hasOfferText || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) ? "mb-[55px]" : "mb-[10px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
234
236
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.train_type_label) === "Tren Express (Nuevo)" ||
235
237
  showTopLabel
236
238
  ? "mt-[24px]"
237
239
  : "mt-[20px]"} ` },
238
- React.createElement("div", { id: `service-card-${serviceItem.id}`, className: `bg-white mx-auto relative ${hasOfferText
240
+ React.createElement("div", { id: `service-card-${serviceItem.id}`, className: `bg-white mx-auto relative ${hasOfferText || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled)
239
241
  ? "rounded-[18px]"
240
242
  : "rounded-[10px] border border-[#ccc]"}`, style: serviceCardStyle },
241
243
  React.createElement("div", { className: " pt-[20px]", style: {
@@ -257,7 +259,7 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
257
259
  backgroundColor: "#ccc",
258
260
  } }),
259
261
  React.createElement("div", { className: "content-center" },
260
- React.createElement(SeatSection, { seatTypes: serviceItem.seat_types, serviceItem: serviceItem, availableSeats: serviceItem.available_seats, isSoldOut: isSoldOut, priceColor: colors.priceColor, currencySign: currencySign, removeDuplicateSeats: removeDuplicateSeats, isPeru: isPeru, renderIcon: renderIcon })),
262
+ React.createElement(SeatSection, { seatTypes: serviceItem.seat_types, serviceItem: serviceItem, availableSeats: serviceItem.available_seats, isSoldOut: isSoldOut, priceColor: colors.priceColor, dpSeatColor: colors.seatPriceColor, currencySign: currencySign, removeDuplicateSeats: removeDuplicateSeats, isPeru: isPeru, renderIcon: renderIcon })),
261
263
  React.createElement("div", { className: "relative" },
262
264
  React.createElement(KuposButton, { isSoldOut: isSoldOut, isLoading: serviceDetailsLoading, buttonColor: colors.kuposButtonColor, buyLabel: translation === null || translation === void 0 ? void 0 : translation.buyButton, soldOutLabel: translation === null || translation === void 0 ? void 0 : translation.soldOutButton, soldOutIcon: renderIcon("soldOutIcon", "14px"), onClick: checkMidnight }),
263
265
  showLastSeats ? (React.createElement("div", { className: "flex justify-center mr-[11px] w-[100%] right-[0px]", style: {
@@ -272,54 +274,53 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
272
274
  opacity: isItemExpanded ? 1 : 0,
273
275
  transition: "grid-template-rows 0.3s ease-in-out, opacity 0.25s ease-in-out",
274
276
  position: "relative",
275
- zIndex: -1,
277
+ zIndex: 1,
276
278
  } },
277
- React.createElement("div", { style: Object.assign({ overflow: "hidden", minHeight: 0, marginTop: "-10px" }, (hasOfferText
279
+ React.createElement("div", { style: Object.assign({ overflow: "hidden", minHeight: 0, marginTop: "-10px" }, (hasOfferText || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled)
278
280
  ? {
279
- borderLeft: "6px solid #ff5964",
280
- borderRight: "6px solid #ff8842",
281
+ borderLeft: "3px solid #ff5964",
282
+ borderRight: "3px solid #ff8842",
281
283
  borderRadius: "0 0 18px 18px",
282
284
  boxSizing: "border-box",
283
285
  }
284
286
  : {})) },
285
287
  React.createElement(ExpandedDropdown, { serviceItem: serviceItem, isPeru: isPeru, translation: translation, getAnimationIcon: getAnimationIcon, isChangeTicket: serviceItem.is_change_ticket === true })))),
286
288
  children,
287
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) && (React.createElement("div", { className: "text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[36px] pt-[50px] -z-10 rounded-b-[14px] text-[14px]", style: {
289
+ ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled)) && (React.createElement("div", { className: "text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[36px] pt-[50px] rounded-b-[14px] text-[14px]", style: {
288
290
  background: offerGradient,
289
291
  opacity: isSoldOut ? 0.5 : 1,
290
292
  } },
291
293
  React.createElement("div", { className: "flex justify-between items-center w-full" },
292
- React.createElement("div", { className: "flex items-center " },
293
- React.createElement("div", { className: "flex items-center" },
294
- React.createElement(LottiePlayer, { animationData: getAnimationIcon("bombAnimation"), width: "18px", height: "18px" }),
295
- React.createElement("div", { className: "flex items-center mt-[2px]" },
296
- React.createElement("span", { className: "bold-text ml-[6px]" },
297
- ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "").length > 30
298
- ? ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "").slice(0, 30) + "..."
299
- : (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "",
300
- "\u00A0"),
294
+ React.createElement("div", { className: "flex items-center " }, (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) ? (React.createElement("span", null, "Servicio popular entre los usuarios.")) : (React.createElement("div", { className: "flex items-center" },
295
+ React.createElement(LottiePlayer, { animationData: getAnimationIcon("bombAnimation"), width: "18px", height: "18px" }),
296
+ React.createElement("div", { className: "flex items-center mt-[2px]" },
297
+ React.createElement("span", { className: "bold-text ml-[6px]" },
298
+ ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "").length > 30
299
+ ? ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "").slice(0, 30) +
300
+ "..."
301
+ : (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "",
301
302
  " ",
302
- "| Termina en\u00A0",
303
- React.createElement("span", { className: "bold-text text-end", ref: (node) => CommonService.startCountdown(node, 599), style: {
304
- fontVariantNumeric: "tabular-nums",
305
- display: "inline-block",
306
- // minWidth: "70px",
307
- } })))),
303
+ isLoggedIn ? null : (React.createElement("span", { onClick: showLoginModal, className: "cursor-pointer" }, "registro")),
304
+ " ",
305
+ "\u00A0"),
306
+ " ",
307
+ "| Termina en\u00A0",
308
+ React.createElement("span", { className: "bold-text text-end", ref: (node) => CommonService.startCountdown(node, 599), style: {
309
+ fontVariantNumeric: "tabular-nums",
310
+ display: "inline-block",
311
+ } }))))),
308
312
  React.createElement("div", { className: "flex items-center" },
309
313
  React.createElement(LottiePlayer, { animationData: getAnimationIcon("dotAnimation"), width: "12px", height: "12px" }),
310
314
  React.createElement("span", { className: "ml-[6px]" },
311
315
  React.createElement("span", { className: "bold-text", ref: (node) => CommonService.startViewerCount(node, viewersConfig), style: { fontVariantNumeric: "tabular-nums" } }),
312
316
  " ",
313
- React.createElement("span", { className: "bold-text" }, "personas"),
314
- " ",
315
317
  React.createElement("span", null,
316
318
  " ",
317
319
  (viewersConfig === null || viewersConfig === void 0 ? void 0 : viewersConfig.label) || " viendo",
318
320
  " |",
319
321
  " ",
320
322
  React.createElement("span", { className: "" },
321
- "Quedan pocos \u2022",
322
- " ",
323
+ (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) ? null : "Quedan pocos ",
323
324
  React.createElement("span", { className: "bold-text", ref: (node) => CommonService.startComprandoCount(node, 4, 16), style: { fontVariantNumeric: "tabular-nums" } }),
324
325
  " ",
325
326
  "comprando"))))))),
@@ -30,7 +30,7 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
30
30
  const isLongOfferText = (((_b = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) === null || _b === void 0 ? void 0 : _b.length) || 0) > 35;
31
31
  const hasOfferText = Boolean(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text);
32
32
  const offerGradient = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"} 0%, ${colors.leftGradiantColor || "#ff8842"} 100%)`;
33
- const serviceCardStyle = hasOfferText
33
+ const serviceCardStyle = hasOfferText || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled)
34
34
  ? {
35
35
  borderColor: "transparent",
36
36
  borderStyle: "solid",
@@ -86,13 +86,13 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
86
86
  if (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_transpordo) {
87
87
  isConexion = true;
88
88
  }
89
- return (React.createElement("div", { className: `relative ${!serviceItem.offer_text ? "mb-[14px]" : showTopLabel || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ? "mb-[20px]" : "mb-[12px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
89
+ return (React.createElement("div", { className: `relative ${!serviceItem.offer_text || !(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) ? "mb-[14px]" : showTopLabel || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ? "mb-[20px]" : "mb-[12px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
90
90
  isConexion ||
91
91
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.train_type_label) === "Tren Express (Nuevo)" ||
92
92
  showTopLabel
93
93
  ? "mt-[20px]"
94
94
  : "mt-[10px]"} `, style: { backgroundColor: "#fff", zIndex: 1 } },
95
- React.createElement("div", { className: `bg-white z-1 ${hasOfferText
95
+ React.createElement("div", { className: `bg-white z-1 ${hasOfferText || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled)
96
96
  ? "rounded-[18px]"
97
97
  : "rounded-[10px] border border-[#ccc]"}`, style: serviceCardStyle },
98
98
  React.createElement("div", { style: { padding: "12px 12px 8px 12px" } },
@@ -117,7 +117,7 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
117
117
  setIsExpanded(isItemExpanded ? null : serviceItem.id);
118
118
  }, isPeru: isPeru })),
119
119
  React.createElement(ServiceBadgesMobile, { showTopLabel: showTopLabel, isSoldOut: isSoldOut, colors: colors, renderIcon: renderIcon, serviceItem: serviceItem, isConexion: isConexion })),
120
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) && (React.createElement("div", { className: "px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]", style: {
120
+ ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled)) && (React.createElement("div", { className: "px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]", style: {
121
121
  background: isSoldOut ? "#ccc" : offerGradient,
122
122
  opacity: isSoldOut ? 0.5 : 1,
123
123
  borderRadius: "0 0 14px 14px",
@@ -125,7 +125,7 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
125
125
  } },
126
126
  React.createElement("div", { className: "flex flex-col gap-[8px] text-[12px] min-[420px]:text-[12px] text-[#464647]", style: { lineHeight: 1.6 } },
127
127
  React.createElement("div", { className: "flex justify-between items-center" },
128
- React.createElement("div", { className: `flex ${((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "").length > 10 ? "items-start" : "items-center"}` },
128
+ (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) ? (React.createElement("span", { className: "text-[#fff]" }, "Servicio popular entre los usuarios.")) : (React.createElement("div", { className: `flex ${((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "").length > 10 ? "items-start" : "items-center"}` },
129
129
  React.createElement("div", { className: isLongOfferText ? "mt-[2px]" : "" },
130
130
  React.createElement(LottiePlayer, { animationData: serviceItem.icons.bombAnim, width: "14px", height: "14px" })),
131
131
  React.createElement("div", { className: `ml-[4px] flex-1 outline-none ${isLongOfferText ? "mt-[2px]" : ""}`, style: {
@@ -137,7 +137,7 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
137
137
  React.createElement("span", { className: "bold-text", ref: (node) => commonService.startCountdown(node, 599), style: {
138
138
  fontVariantNumeric: "tabular-nums",
139
139
  display: "inline-block",
140
- } })))),
140
+ } }))))),
141
141
  React.createElement("div", { className: "flex flex-col items-end", style: {
142
142
  color: "#fff",
143
143
  } },
@@ -148,15 +148,10 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
148
148
  React.createElement("span", { className: "flex-1", style: { lineHeight: 1.4 } },
149
149
  React.createElement("span", { className: "bold-text", ref: (node) => commonService.startViewerCount(node, viewersConfig), style: { fontVariantNumeric: "tabular-nums" } }),
150
150
  " ",
151
- React.createElement("span", { className: "bold-text" }, "personas"),
152
- " ",
153
- React.createElement("span", null,
154
- " ",
155
- "viendo"))),
151
+ React.createElement("span", null, " viendo"))),
156
152
  React.createElement("div", { className: "flex items-center" },
157
153
  React.createElement("span", { className: "whitespace-nowrap" },
158
- "Quedan pocos \u2022",
159
- " ",
154
+ (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) ? null : "Quedan pocos ",
160
155
  React.createElement("span", { className: "bold-text", ref: (node) => commonService.startComprandoCount(node, 4, 16), style: { fontVariantNumeric: "tabular-nums" } }),
161
156
  " ",
162
157
  "comprando"))))))),
@@ -166,7 +161,7 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
166
161
  opacity: isItemExpanded ? 1 : 0,
167
162
  transition: "grid-template-rows 0.3s ease-in-out, opacity 0.25s ease-in-out",
168
163
  position: "relative",
169
- zIndex: (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) ? -2 : -1,
164
+ zIndex: (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) ? -2 : -1,
170
165
  } },
171
166
  React.createElement("div", { style: {
172
167
  overflow: "hidden",
@@ -34,6 +34,7 @@ export interface MobileServiceItemProps {
34
34
  change_ticket_hours?: number;
35
35
  duration?: number;
36
36
  train_type_label?: string;
37
+ is_dp_enabled?: boolean;
37
38
  offer_text?: string;
38
39
  is_direct_trip?: boolean;
39
40
  is_train_type?: boolean;
@@ -38,6 +38,7 @@ export interface ServiceItemProps {
38
38
  train_type_label?: string;
39
39
  offer_text?: string;
40
40
  is_direct_trip?: boolean;
41
+ is_dp_enabled?: boolean;
41
42
  is_transpordo?: boolean;
42
43
  is_train_type?: boolean;
43
44
  operator_service_name?: string;
@@ -210,4 +211,6 @@ export interface ServiceItemProps {
210
211
  label?: string;
211
212
  icon?: string;
212
213
  };
214
+ showLoginModal?: any;
215
+ isLoggedIn?: any;
213
216
  }
package/dist/styles.css CHANGED
@@ -27,8 +27,8 @@
27
27
  .-top-\[8px\] {
28
28
  top: calc(8px * -1);
29
29
  }
30
- .-top-\[9px\] {
31
- top: calc(9px * -1);
30
+ .-top-\[10px\] {
31
+ top: calc(10px * -1);
32
32
  }
33
33
  .-top-\[11px\] {
34
34
  top: calc(11px * -1);
@@ -451,6 +451,9 @@
451
451
  .\[grid-template-columns\:22\%_28\%_2\.5\%_24\%_15\.5\%\] {
452
452
  grid-template-columns: 22% 28% 2.5% 24% 15.5%;
453
453
  }
454
+ .grid-cols-2 {
455
+ grid-template-columns: repeat(2, minmax(0, 1fr));
456
+ }
454
457
  .grid-cols-\[0\.8fr_auto_26\%_1fr\] {
455
458
  grid-template-columns: 0.8fr auto 26% 1fr;
456
459
  }
@@ -925,6 +928,9 @@
925
928
  .capitalize {
926
929
  text-transform: capitalize;
927
930
  }
931
+ .normal-case {
932
+ text-transform: none;
933
+ }
928
934
  .uppercase {
929
935
  text-transform: uppercase;
930
936
  }
@@ -8,6 +8,7 @@ function KuposButton({ isSoldOut, isLoading, buttonColor, buyLabel, soldOutLabel
8
8
  } },
9
9
  React.createElement("span", { className: "min-w-[75px] flex justify-center items-center bold-text uppercase gap-[5px]" },
10
10
  isSoldOut ? soldOutIcon : null,
11
- isLoading ? (React.createElement("span", { className: "loader-circle" })) : !isSoldOut ? (buyLabel) : (soldOutLabel))));
11
+ isLoading ? (React.createElement("span", { className: "loader-circle" })) : !isSoldOut ? (React.createElement("span", { className: "normal-case" }, buyLabel.charAt(0).toUpperCase() + buyLabel.slice(1).toLowerCase())) : (React.createElement("span", { className: "normal-case" }, soldOutLabel.charAt(0).toUpperCase() +
12
+ soldOutLabel.slice(1).toLowerCase())))));
12
13
  }
13
14
  export default KuposButton;
@@ -9,11 +9,12 @@ interface SeatSectionProps {
9
9
  availableSeats: number;
10
10
  isSoldOut: boolean;
11
11
  priceColor?: string;
12
+ dpSeatColor?: string;
12
13
  currencySign?: string;
13
14
  removeDuplicateSeats?: boolean;
14
15
  isPeru?: boolean;
15
16
  serviceItem?: any;
16
17
  renderIcon?: (iconKey: string, size?: string) => React.ReactNode;
17
18
  }
18
- declare function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, isPeru, serviceItem, renderIcon, }: SeatSectionProps): React.ReactElement;
19
+ declare function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, isPeru, serviceItem, renderIcon, dpSeatColor, }: SeatSectionProps): React.ReactElement;
19
20
  export default SeatSection;
@@ -54,7 +54,7 @@ function getUniqueSeats(seatTypes) {
54
54
  function getNumberOfSeats(seatTypes) {
55
55
  return seatTypes.filter((val) => !SEAT_EXCEPTIONS.includes(val.label)).length;
56
56
  }
57
- function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, isPeru, serviceItem, renderIcon, }) {
57
+ function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, isPeru, serviceItem, renderIcon, dpSeatColor, }) {
58
58
  const uniqueSeats = getUniqueSeats(seatTypes);
59
59
  const sortedSeatTypes = getSortedSeatTypes(seatTypes);
60
60
  const numberOfSeats = getNumberOfSeats(seatTypes);
@@ -116,14 +116,28 @@ function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currenc
116
116
  }
117
117
  return renderSeatNames();
118
118
  };
119
+ if (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) {
120
+ const dpSeats = (removeDuplicateSeats ? uniqueSeats : sortedSeatTypes).filter((s) => !SEAT_EXCEPTIONS.includes(s.label));
121
+ const lowestFare = dpSeats.length > 0 ? Math.min(...dpSeats.map((s) => Number(s.price))) : 0;
122
+ return (React.createElement("div", { className: "flex flex-col gap-[2px]" },
123
+ React.createElement("span", { className: "text-[12px] bold-text text-right", style: { color: dpSeatColor } }, "Mejor precio"),
124
+ React.createElement("div", { className: "flex items-center justify-between text-[13.33px]" },
125
+ React.createElement("span", { className: "text-[13.33px] font-normal leading-[24px] text-[#464647]" }, "Desde"),
126
+ React.createElement("span", { className: "flex items-center gap-[6px] text-[22px] bold-text leading-[30px]", style: { color: isSoldOut ? "#c0c0c0" : dpSeatColor } },
127
+ renderIcon("fireIcon", "16px"),
128
+ availableSeats <= 0
129
+ ? CommonService.currency(0, currencySign)
130
+ : CommonService.discountedCurrency(lowestFare, currencySign)))));
131
+ }
119
132
  if (hasDiscount && discountSeat) {
120
- return (React.createElement("div", { className: "grid items-center text-[13.33px] relative" },
133
+ return (React.createElement("div", { className: "grid grid-cols-2 items-center text-[13.33px] relative" },
121
134
  React.createElement("div", { className: "col-start-1 row-start-2 flex items-center" },
122
- React.createElement("span", { className: "text-[13.33px] font-normal leading-[22px] text-[#c2c2c2]" }, "Antes")),
123
- React.createElement("div", { className: "col-start-1 row-start-3 flex h-[30px] items-end" },
124
- React.createElement("span", { className: "text-[13.33px] font-normal leading-[24px] text-[#464647]" }, "Desde")),
125
- React.createElement("div", { className: "col-start-2 row-start-1 flex items-center justify-center absolute", style: { top: "-22px", right: "25%" } }, discountValue != null && (React.createElement("span", { className: "rounded-[100px] bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white", style: {
135
+ React.createElement("span", { className: "text-[13.33px] font-normal leading-[22px] text-[#ccc]" }, "Antes")),
136
+ React.createElement("div", { className: "col-start-1 row-start-3 flex h-[20px] items-end" },
137
+ React.createElement("span", { className: "text-[13.33px] font-normal leading-[20px] text-[#464647]" }, "Desde")),
138
+ React.createElement("div", { className: "col-start-2 row-start-1 flex items-center justify-center absolute", style: { top: "-22px", left: "50%", transform: "translateX(-50%)" } }, discountValue != null && (React.createElement("span", { className: "rounded-[100px] bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white", style: {
126
139
  animation: "pulse-zoom 2s ease-in-out infinite",
140
+ whiteSpace: "nowrap",
127
141
  } },
128
142
  discountValue,
129
143
  "% OFF"))),
@@ -142,9 +156,9 @@ function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currenc
142
156
  transform: "rotate(-10deg)",
143
157
  transformOrigin: "center",
144
158
  } }))),
145
- React.createElement("div", { className: "col-start-2 row-start-3 flex h-[30px] items-end justify-center" },
159
+ React.createElement("div", { className: "col-start-2 row-start-3 flex h-[30px] items-end justify-center relative" },
146
160
  React.createElement("span", { className: "flex items-center gap-[6px] text-[22px] bold-text leading-[30px]", style: { color: isSoldOut ? "#c0c0c0" : "#ff5964" } },
147
- renderIcon("fireIcon", "16px"),
161
+ React.createElement("div", { className: "absolute -left-[8px]" }, renderIcon("fireIcon", "16px")),
148
162
  availableSeats <= 0
149
163
  ? CommonService.currency(0, currencySign)
150
164
  : CommonService.discountedCurrency(discountSeat.discountedPrice, currencySign)))));
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  const ServiceBadges = ({ showTopLabel, isSoldOut, colors, renderIcon, translation, serviceItem, }) => {
3
- return (React.createElement("div", { className: "absolute -top-[11px] left-0 w-full flex items-center justify-end gap-[12px] pr-[22px] z-10" },
3
+ return (React.createElement("div", { className: "absolute -top-[10px] left-0 w-full flex items-center justify-end gap-[12px] pr-[22px] z-10" },
4
4
  showTopLabel && (React.createElement("div", { className: `flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-10`, style: {
5
5
  backgroundColor: "#fff",
6
6
  border: `1px solid ${colors.topLabelColor}`,
@@ -73,6 +73,23 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
73
73
  React.createElement("span", { className: "min-[420]:text-[13px] text-[12px] bold-text", style: { color: isSoldOut ? "#bbb" : "#464647" } }, "Desde"),
74
74
  React.createElement("span", { className: "min-[420]:text-[13px] text-[12px] bold-text", style: { color: priceColor } }, commonService.currency(discountedPrice, currencySign)))));
75
75
  };
76
+ const renderDpSeats = () => {
77
+ var _a;
78
+ const lowestFare = getLowestFare();
79
+ if (lowestFare === null)
80
+ return null;
81
+ const { discountedPrice } = commonService.calculateDiscountedPrice(lowestFare, serviceItem);
82
+ const priceColor = isSoldOut ? "#bbb" : tooltipBgColor;
83
+ return (React.createElement("div", { className: "relative flex flex-col justify-center h-full" },
84
+ React.createElement("span", { className: "absolute -top-[10px] right-[0px] min-[420]:text-[13px] text-[12px] bold-text", style: { color: isSoldOut ? "#bbb" : priceColor } }, "Mejor precio"),
85
+ React.createElement("div", { className: "w-[100%] flex flex-row justify-between items-center" },
86
+ React.createElement("span", { className: "min-[420]:text-[13px] text-[12px]", style: { color: isSoldOut ? "#bbb" : "#464647" } }, "Desde"),
87
+ React.createElement("span", { className: "flex items-center gap-[4px] min-[420]:text-[13px] text-[14px] bold-text", style: { color: priceColor } },
88
+ ((_a = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.icons) === null || _a === void 0 ? void 0 : _a.fireIcon) ? (React.createElement("img", { src: serviceItem.icons.fireIcon, alt: "dp", className: "h-[14px] w-[14px] object-contain", style: { filter: isSoldOut ? "grayscale(1)" : "" } })) : null,
89
+ commonService.currency(discountedPrice, currencySign))),
90
+ isSoldOut ? (React.createElement("div", { className: "flex justify-end" },
91
+ React.createElement("span", { className: "min-[420]:text-[13px] text-[12px] text-[#ccc]" }, "Agotado"))) : null));
92
+ };
76
93
  const renderSeats = () => {
77
94
  var _a, _b, _c;
78
95
  if (isPeru) {
@@ -102,7 +119,7 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
102
119
  typeof (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value) === "number"
103
120
  ? Math.round(serviceItem.discount_value)
104
121
  : null;
105
- return (React.createElement("div", { className: "content-center relative", style: { width: "40%" } }, hasDiscount && discountSeat ? (React.createElement("div", { className: "relative grid grid-cols-[auto_auto] justify-between gap-x-[8px] " },
122
+ return (React.createElement("div", { className: "content-center relative", style: { width: "40%" } }, (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) ? (React.createElement("div", { className: "flex flex-col justify-between h-[2.5rem]", style: { gap: isSoldOut ? "0px" : "5px" } }, renderDpSeats())) : hasDiscount && discountSeat ? (React.createElement("div", { className: "relative grid grid-cols-[auto_auto] justify-between gap-x-[8px] " },
106
123
  discountValue != null && (React.createElement("div", { className: "absolute -top-[18px] right-[0px]", style: {
107
124
  animation: "pulse-zoom 2s ease-in-out infinite",
108
125
  } },
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
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-[17px] z-10" },
3
+ return (React.createElement("div", { className: "absolute -top-[10px] left-0 w-full flex items-center justify-end gap-[12px] pr-[17px] z-10" },
4
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
5
  backgroundColor: "#fff",
6
6
  border: `1px solid ${colors.topLabelColor}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kupos-ui-components-lib",
3
- "version": "9.3.9",
3
+ "version": "9.3.10",
4
4
  "description": "A reusable UI components package",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -105,7 +105,10 @@ function ServiceItemPB({
105
105
  setIsExpand,
106
106
  coachKey,
107
107
  viewersConfig,
108
+ showLoginModal,
109
+ isLoggedIn,
108
110
  }: ServiceItemProps & { currencySign?: string }): React.ReactElement {
111
+ console.log("🚀 ~ ServiceItemPB ~ serviceItem:", serviceItem);
109
112
  const getAnimationIcon = (icon: string) => {
110
113
  const animation = ANIMATION_MAP[icon];
111
114
  if (!animation) return null;
@@ -185,15 +188,17 @@ function ServiceItemPB({
185
188
  );
186
189
 
187
190
  const offerGradient = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"} 0%, ${colors.leftGradiantColor || "#ff8842"} 100%)`;
188
- const serviceCardStyle: React.CSSProperties = hasOfferText
189
- ? {
190
- borderColor: "transparent",
191
- borderStyle: "solid",
192
- borderWidth: "6px 6px 0 6px",
193
- borderRadius: isItemExpanded || coachKey ? "18px 18px 0 0" : "18px",
194
- background: `linear-gradient(#fff, #fff) padding-box, ${offerGradient} border-box`,
195
- }
196
- : {};
191
+ const serviceCardStyle: React.CSSProperties =
192
+ hasOfferText || serviceItem?.is_dp_enabled
193
+ ? {
194
+ borderColor: "transparent",
195
+ borderStyle: "solid",
196
+ borderWidth: "3px 3px 0 3px",
197
+ borderRadius: isItemExpanded || coachKey ? "18px 18px 0 0" : "18px",
198
+ background: `linear-gradient(#fff, #fff) padding-box, ${offerGradient} border-box`,
199
+ zIndex: 2,
200
+ }
201
+ : {};
197
202
 
198
203
  const renderIcon = (iconKey: string, size: string = "14px") => {
199
204
  const iconValue = serviceItem.icons?.[iconKey];
@@ -397,7 +402,7 @@ function ServiceItemPB({
397
402
  />
398
403
  ) : (
399
404
  <div
400
- className={`relative ${hasOfferText ? "mb-[55px]" : "mb-[10px]"} ${
405
+ className={`relative ${hasOfferText || serviceItem?.is_dp_enabled ? "mb-[55px]" : "mb-[10px]"} ${
401
406
  serviceItem?.is_direct_trip ||
402
407
  serviceItem?.train_type_label === "Tren Express (Nuevo)" ||
403
408
  showTopLabel
@@ -408,7 +413,7 @@ function ServiceItemPB({
408
413
  <div
409
414
  id={`service-card-${serviceItem.id}`}
410
415
  className={`bg-white mx-auto relative ${
411
- hasOfferText
416
+ hasOfferText || serviceItem?.is_dp_enabled
412
417
  ? "rounded-[18px]"
413
418
  : "rounded-[10px] border border-[#ccc]"
414
419
  }`}
@@ -485,6 +490,7 @@ function ServiceItemPB({
485
490
  availableSeats={serviceItem.available_seats}
486
491
  isSoldOut={isSoldOut}
487
492
  priceColor={colors.priceColor}
493
+ dpSeatColor={colors.seatPriceColor}
488
494
  currencySign={currencySign}
489
495
  removeDuplicateSeats={removeDuplicateSeats}
490
496
  isPeru={isPeru}
@@ -565,7 +571,7 @@ function ServiceItemPB({
565
571
  transition:
566
572
  "grid-template-rows 0.3s ease-in-out, opacity 0.25s ease-in-out",
567
573
  position: "relative",
568
- zIndex: -1,
574
+ zIndex: 1,
569
575
  }}
570
576
  >
571
577
  <div
@@ -573,10 +579,10 @@ function ServiceItemPB({
573
579
  overflow: "hidden",
574
580
  minHeight: 0,
575
581
  marginTop: "-10px",
576
- ...(hasOfferText
582
+ ...(hasOfferText || serviceItem?.is_dp_enabled
577
583
  ? {
578
- borderLeft: "6px solid #ff5964",
579
- borderRight: "6px solid #ff8842",
584
+ borderLeft: "3px solid #ff5964",
585
+ borderRight: "3px solid #ff8842",
580
586
  borderRadius: "0 0 18px 18px",
581
587
  boxSizing: "border-box",
582
588
  }
@@ -596,9 +602,9 @@ function ServiceItemPB({
596
602
 
597
603
  {children}
598
604
  {/* Bottom discount banner */}
599
- {serviceItem?.offer_text && (
605
+ {(serviceItem?.offer_text || serviceItem?.is_dp_enabled) && (
600
606
  <div
601
- className="text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[36px] pt-[50px] -z-10 rounded-b-[14px] text-[14px]"
607
+ className="text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[36px] pt-[50px] rounded-b-[14px] text-[14px]"
602
608
  style={{
603
609
  background: offerGradient,
604
610
  opacity: isSoldOut ? 0.5 : 1,
@@ -606,31 +612,45 @@ function ServiceItemPB({
606
612
  >
607
613
  <div className="flex justify-between items-center w-full">
608
614
  <div className="flex items-center ">
609
- <div className="flex items-center">
610
- <LottiePlayer
611
- animationData={getAnimationIcon("bombAnimation")}
612
- width="18px"
613
- height="18px"
614
- />
615
- <div className="flex items-center mt-[2px]">
616
- <span className="bold-text ml-[6px]">
617
- {(serviceItem?.offer_text || "").length > 30
618
- ? (serviceItem?.offer_text || "").slice(0, 30) + "..."
619
- : serviceItem?.offer_text || ""}
620
- &nbsp;
621
- </span>{" "}
622
- | Termina en&nbsp;
623
- <span
624
- className="bold-text text-end"
625
- ref={(node) => CommonService.startCountdown(node, 599)}
626
- style={{
627
- fontVariantNumeric: "tabular-nums",
628
- display: "inline-block",
629
- // minWidth: "70px",
630
- }}
615
+ {serviceItem?.is_dp_enabled ? (
616
+ <span>Servicio popular entre los usuarios.</span>
617
+ ) : (
618
+ <div className="flex items-center">
619
+ <LottiePlayer
620
+ animationData={getAnimationIcon("bombAnimation")}
621
+ width="18px"
622
+ height="18px"
631
623
  />
624
+ <div className="flex items-center mt-[2px]">
625
+ <span className="bold-text ml-[6px]">
626
+ {(serviceItem?.offer_text || "").length > 30
627
+ ? (serviceItem?.offer_text || "").slice(0, 30) +
628
+ "..."
629
+ : serviceItem?.offer_text || ""}{" "}
630
+ {isLoggedIn ? null : (
631
+ <span
632
+ onClick={showLoginModal}
633
+ className="cursor-pointer"
634
+ >
635
+ registro
636
+ </span>
637
+ )}{" "}
638
+ &nbsp;
639
+ </span>{" "}
640
+ | Termina en&nbsp;
641
+ <span
642
+ className="bold-text text-end"
643
+ ref={(node) =>
644
+ CommonService.startCountdown(node, 599)
645
+ }
646
+ style={{
647
+ fontVariantNumeric: "tabular-nums",
648
+ display: "inline-block",
649
+ }}
650
+ />
651
+ </div>
632
652
  </div>
633
- </div>
653
+ )}
634
654
  </div>
635
655
  <div className="flex items-center">
636
656
  {/* {renderIcon("personIcon", "16px")} */}
@@ -648,12 +668,12 @@ function ServiceItemPB({
648
668
  }
649
669
  style={{ fontVariantNumeric: "tabular-nums" }}
650
670
  />{" "}
651
- <span className="bold-text">personas</span>{" "}
671
+ {/* <span className="bold-text">personas</span>{" "} */}
652
672
  <span>
653
673
  {" "}
654
674
  {viewersConfig?.label || " viendo"} |{" "}
655
675
  <span className="">
656
- Quedan pocos •{" "}
676
+ {serviceItem?.is_dp_enabled ? null : "Quedan pocos • "}
657
677
  <span
658
678
  className="bold-text"
659
679
  ref={(node) =>
@@ -70,15 +70,16 @@ function ServiceItemMobile({
70
70
 
71
71
  const hasOfferText = Boolean(serviceItem?.offer_text);
72
72
  const offerGradient = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"} 0%, ${colors.leftGradiantColor || "#ff8842"} 100%)`;
73
- const serviceCardStyle: React.CSSProperties = hasOfferText
74
- ? {
75
- borderColor: "transparent",
76
- borderStyle: "solid",
77
- borderWidth: "3px 3px 0 3px",
78
- borderRadius: "18px",
79
- background: `linear-gradient(#fff, #fff) padding-box, ${offerGradient} border-box`,
80
- }
81
- : {};
73
+ const serviceCardStyle: React.CSSProperties =
74
+ hasOfferText || serviceItem?.is_dp_enabled
75
+ ? {
76
+ borderColor: "transparent",
77
+ borderStyle: "solid",
78
+ borderWidth: "3px 3px 0 3px",
79
+ borderRadius: "18px",
80
+ background: `linear-gradient(#fff, #fff) padding-box, ${offerGradient} border-box`,
81
+ }
82
+ : {};
82
83
 
83
84
  const labelId =
84
85
  typeof serviceItem.boarding_stages === "string"
@@ -152,7 +153,7 @@ function ServiceItemMobile({
152
153
 
153
154
  return (
154
155
  <div
155
- className={`relative ${!serviceItem.offer_text ? "mb-[14px]" : showTopLabel || serviceItem?.is_direct_trip ? "mb-[20px]" : "mb-[12px]"} ${
156
+ className={`relative ${!serviceItem.offer_text || !serviceItem?.is_dp_enabled ? "mb-[14px]" : showTopLabel || serviceItem?.is_direct_trip ? "mb-[20px]" : "mb-[12px]"} ${
156
157
  serviceItem?.is_direct_trip ||
157
158
  isConexion ||
158
159
  serviceItem?.train_type_label === "Tren Express (Nuevo)" ||
@@ -164,7 +165,7 @@ function ServiceItemMobile({
164
165
  >
165
166
  <div
166
167
  className={`bg-white z-1 ${
167
- hasOfferText
168
+ hasOfferText || serviceItem?.is_dp_enabled
168
169
  ? "rounded-[18px]"
169
170
  : "rounded-[10px] border border-[#ccc]"
170
171
  }`}
@@ -296,7 +297,7 @@ function ServiceItemMobile({
296
297
  </div>
297
298
 
298
299
  {/* 🔹 EXPANDABLE DROPDOWN (below the card) */}
299
- {serviceItem?.offer_text && (
300
+ {(serviceItem?.offer_text || serviceItem?.is_dp_enabled) && (
300
301
  <div
301
302
  className="px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]"
302
303
  style={{
@@ -311,42 +312,42 @@ function ServiceItemMobile({
311
312
  style={{ lineHeight: 1.6 }}
312
313
  >
313
314
  <div className="flex justify-between items-center">
314
- <div
315
- className={`flex ${(serviceItem?.offer_text || "").length > 10 ? "items-start" : "items-center"}`}
316
- >
317
- <div className={isLongOfferText ? "mt-[2px]" : ""}>
318
- <LottiePlayer
319
- animationData={serviceItem.icons.bombAnim}
320
- width="14px"
321
- height="14px"
322
- />
323
- </div>
315
+ {serviceItem?.is_dp_enabled ? (
316
+ <span className="text-[#fff]">
317
+ Servicio popular entre los usuarios.
318
+ </span>
319
+ ) : (
324
320
  <div
325
- className={`ml-[4px] flex-1 outline-none ${isLongOfferText ? "mt-[2px]" : ""}`}
326
- style={{
327
- color: "#fff",
328
- lineHeight: 1.4,
329
- }}
321
+ className={`flex ${(serviceItem?.offer_text || "").length > 10 ? "items-start" : "items-center"}`}
330
322
  >
331
- {/* <span className="min-[380px]:text-[12px] bold-text">
332
- {(serviceItem?.offer_text || "").length > 30
333
- ? (serviceItem?.offer_text || "").slice(0, 30) + "..."
334
- : serviceItem?.offer_text || ""}
335
- </span>{" "}
336
- <span className="min-[380px]:text-[12px]">|</span>{" "} */}
337
- <span className="whitespace-nowrap min-[380px]:text-[12px]">
338
- Termina en&nbsp;
339
- <span
340
- className="bold-text"
341
- ref={(node) => commonService.startCountdown(node, 599)}
342
- style={{
343
- fontVariantNumeric: "tabular-nums",
344
- display: "inline-block",
345
- }}
323
+ <div className={isLongOfferText ? "mt-[2px]" : ""}>
324
+ <LottiePlayer
325
+ animationData={serviceItem.icons.bombAnim}
326
+ width="14px"
327
+ height="14px"
346
328
  />
347
- </span>
329
+ </div>
330
+ <div
331
+ className={`ml-[4px] flex-1 outline-none ${isLongOfferText ? "mt-[2px]" : ""}`}
332
+ style={{
333
+ color: "#fff",
334
+ lineHeight: 1.4,
335
+ }}
336
+ >
337
+ <span className="whitespace-nowrap min-[380px]:text-[12px]">
338
+ Termina en&nbsp;
339
+ <span
340
+ className="bold-text"
341
+ ref={(node) => commonService.startCountdown(node, 599)}
342
+ style={{
343
+ fontVariantNumeric: "tabular-nums",
344
+ display: "inline-block",
345
+ }}
346
+ />
347
+ </span>
348
+ </div>
348
349
  </div>
349
- </div>
350
+ )}
350
351
  <div
351
352
  className="flex flex-col items-end"
352
353
  style={{
@@ -370,17 +371,12 @@ function ServiceItemMobile({
370
371
  }
371
372
  style={{ fontVariantNumeric: "tabular-nums" }}
372
373
  />{" "}
373
- <span className="bold-text">personas</span>{" "}
374
- <span>
375
- {" "}
376
- {/* {viewersConfig.label || " están viendo este viaje"} */}
377
- viendo
378
- </span>
374
+ <span> viendo</span>
379
375
  </span>
380
376
  </div>
381
377
  <div className="flex items-center">
382
378
  <span className="whitespace-nowrap">
383
- Quedan pocos •{" "}
379
+ {serviceItem?.is_dp_enabled ? null : "Quedan pocos • "}
384
380
  <span
385
381
  className="bold-text"
386
382
  ref={(node) =>
@@ -460,7 +456,8 @@ function ServiceItemMobile({
460
456
  transition:
461
457
  "grid-template-rows 0.3s ease-in-out, opacity 0.25s ease-in-out",
462
458
  position: "relative",
463
- zIndex: serviceItem?.offer_text ? -2 : -1,
459
+ zIndex:
460
+ serviceItem?.offer_text || serviceItem?.is_dp_enabled ? -2 : -1,
464
461
  }}
465
462
  >
466
463
  <div
@@ -37,6 +37,7 @@ export interface MobileServiceItemProps {
37
37
  change_ticket_hours?: number;
38
38
  duration?: number;
39
39
  train_type_label?: string;
40
+ is_dp_enabled?: boolean;
40
41
  offer_text?: string;
41
42
  is_direct_trip?: boolean;
42
43
  is_train_type?: boolean;
@@ -40,6 +40,7 @@ export interface ServiceItemProps {
40
40
  train_type_label?: string;
41
41
  offer_text?: string;
42
42
  is_direct_trip?: boolean;
43
+ is_dp_enabled?: boolean;
43
44
  is_transpordo?: boolean;
44
45
  is_train_type?: boolean;
45
46
  operator_service_name?: string;
@@ -212,4 +213,7 @@ export interface ServiceItemProps {
212
213
  label?: string; // e.g. "personas están viendo este viaje"
213
214
  icon?: string; // optional icon URL
214
215
  };
216
+ showLoginModal?: any
217
+ isLoggedIn?: any
218
+
215
219
  }
@@ -37,9 +37,14 @@ function KuposButton({
37
37
  {isLoading ? (
38
38
  <span className="loader-circle"></span>
39
39
  ) : !isSoldOut ? (
40
- buyLabel
40
+ <span className="normal-case">
41
+ {buyLabel.charAt(0).toUpperCase() + buyLabel.slice(1).toLowerCase()}
42
+ </span>
41
43
  ) : (
42
- soldOutLabel
44
+ <span className="normal-case">
45
+ {soldOutLabel.charAt(0).toUpperCase() +
46
+ soldOutLabel.slice(1).toLowerCase()}
47
+ </span>
43
48
  )}
44
49
  </span>
45
50
  </button>
@@ -14,6 +14,7 @@ interface SeatSectionProps {
14
14
  availableSeats: number;
15
15
  isSoldOut: boolean;
16
16
  priceColor?: string;
17
+ dpSeatColor?: string;
17
18
  currencySign?: string;
18
19
  removeDuplicateSeats?: boolean;
19
20
  isPeru?: boolean;
@@ -98,6 +99,7 @@ function SeatSection({
98
99
  isPeru,
99
100
  serviceItem,
100
101
  renderIcon,
102
+ dpSeatColor,
101
103
  }: SeatSectionProps): React.ReactElement {
102
104
  const uniqueSeats = getUniqueSeats(seatTypes);
103
105
  const sortedSeatTypes = getSortedSeatTypes(seatTypes);
@@ -220,30 +222,64 @@ function SeatSection({
220
222
  return renderSeatNames();
221
223
  };
222
224
 
225
+ if (serviceItem?.is_dp_enabled) {
226
+ const dpSeats = (
227
+ removeDuplicateSeats ? uniqueSeats : sortedSeatTypes
228
+ ).filter((s) => !SEAT_EXCEPTIONS.includes(s.label));
229
+ const lowestFare =
230
+ dpSeats.length > 0 ? Math.min(...dpSeats.map((s) => Number(s.price))) : 0;
231
+
232
+ return (
233
+ <div className="flex flex-col gap-[2px]">
234
+ <span
235
+ className="text-[12px] bold-text text-right"
236
+ style={{ color: dpSeatColor }}
237
+ >
238
+ Mejor precio
239
+ </span>
240
+ <div className="flex items-center justify-between text-[13.33px]">
241
+ <span className="text-[13.33px] font-normal leading-[24px] text-[#464647]">
242
+ Desde
243
+ </span>
244
+ <span
245
+ className="flex items-center gap-[6px] text-[22px] bold-text leading-[30px]"
246
+ style={{ color: isSoldOut ? "#c0c0c0" : dpSeatColor }}
247
+ >
248
+ {renderIcon("fireIcon", "16px")}
249
+ {availableSeats <= 0
250
+ ? CommonService.currency(0, currencySign)
251
+ : CommonService.discountedCurrency(lowestFare, currencySign)}
252
+ </span>
253
+ </div>
254
+ </div>
255
+ );
256
+ }
257
+
223
258
  if (hasDiscount && discountSeat) {
224
259
  return (
225
- <div className="grid items-center text-[13.33px] relative">
260
+ <div className="grid grid-cols-2 items-center text-[13.33px] relative">
226
261
  <div className="col-start-1 row-start-2 flex items-center">
227
- <span className="text-[13.33px] font-normal leading-[22px] text-[#c2c2c2]">
262
+ <span className="text-[13.33px] font-normal leading-[22px] text-[#ccc]">
228
263
  Antes
229
264
  </span>
230
265
  </div>
231
266
 
232
- <div className="col-start-1 row-start-3 flex h-[30px] items-end">
233
- <span className="text-[13.33px] font-normal leading-[24px] text-[#464647]">
267
+ <div className="col-start-1 row-start-3 flex h-[20px] items-end">
268
+ <span className="text-[13.33px] font-normal leading-[20px] text-[#464647]">
234
269
  Desde
235
270
  </span>
236
271
  </div>
237
272
 
238
273
  <div
239
274
  className="col-start-2 row-start-1 flex items-center justify-center absolute"
240
- style={{ top: "-22px", right: "25%" }}
275
+ style={{ top: "-22px", left: "50%", transform: "translateX(-50%)" }}
241
276
  >
242
277
  {discountValue != null && (
243
278
  <span
244
279
  className="rounded-[100px] bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white"
245
280
  style={{
246
281
  animation: "pulse-zoom 2s ease-in-out infinite",
282
+ whiteSpace: "nowrap",
247
283
  }}
248
284
  >
249
285
  {discountValue}% OFF
@@ -277,13 +313,15 @@ function SeatSection({
277
313
  </span>
278
314
  </div>
279
315
 
280
- <div className="col-start-2 row-start-3 flex h-[30px] items-end justify-center">
316
+ <div className="col-start-2 row-start-3 flex h-[30px] items-end justify-center relative">
281
317
  <span
282
318
  className="flex items-center gap-[6px] text-[22px] bold-text leading-[30px]"
283
319
  style={{ color: isSoldOut ? "#c0c0c0" : "#ff5964" }}
284
320
  >
285
321
  {/* <span className="text-[18px] leading-[24px]">🔥</span> */}
286
- {renderIcon("fireIcon", "16px")}
322
+ <div className="absolute -left-[8px]">
323
+ {renderIcon("fireIcon", "16px")}
324
+ </div>
287
325
  {availableSeats <= 0
288
326
  ? CommonService.currency(0, currencySign)
289
327
  : CommonService.discountedCurrency(
@@ -24,7 +24,7 @@ const ServiceBadges: React.FC<ServiceBadgesProps> = ({
24
24
  serviceItem,
25
25
  }) => {
26
26
  return (
27
- <div className="absolute -top-[11px] left-0 w-full flex items-center justify-end gap-[12px] pr-[22px] z-10">
27
+ <div className="absolute -top-[10px] left-0 w-full flex items-center justify-end gap-[12px] pr-[22px] z-10">
28
28
  {showTopLabel && (
29
29
  <div
30
30
  className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-10`}
@@ -183,6 +183,57 @@ function SeatSectionMobile({
183
183
  );
184
184
  };
185
185
 
186
+ const renderDpSeats = () => {
187
+ const lowestFare = getLowestFare();
188
+ if (lowestFare === null) return null;
189
+
190
+ const { discountedPrice } = commonService.calculateDiscountedPrice(
191
+ lowestFare,
192
+ serviceItem,
193
+ );
194
+ const priceColor = isSoldOut ? "#bbb" : tooltipBgColor;
195
+
196
+ return (
197
+ <div className="relative flex flex-col justify-center h-full">
198
+ <span
199
+ className="absolute -top-[10px] right-[0px] min-[420]:text-[13px] text-[12px] bold-text"
200
+ style={{ color: isSoldOut ? "#bbb" : priceColor }}
201
+ >
202
+ Mejor precio
203
+ </span>
204
+ <div className="w-[100%] flex flex-row justify-between items-center">
205
+ <span
206
+ className="min-[420]:text-[13px] text-[12px]"
207
+ style={{ color: isSoldOut ? "#bbb" : "#464647" }}
208
+ >
209
+ Desde
210
+ </span>
211
+ <span
212
+ className="flex items-center gap-[4px] min-[420]:text-[13px] text-[14px] bold-text"
213
+ style={{ color: priceColor }}
214
+ >
215
+ {serviceItem?.icons?.fireIcon ? (
216
+ <img
217
+ src={serviceItem.icons.fireIcon}
218
+ alt="dp"
219
+ className="h-[14px] w-[14px] object-contain"
220
+ style={{ filter: isSoldOut ? "grayscale(1)" : "" }}
221
+ />
222
+ ) : null}
223
+ {commonService.currency(discountedPrice, currencySign)}
224
+ </span>
225
+ </div>
226
+ {isSoldOut ? (
227
+ <div className="flex justify-end">
228
+ <span className="min-[420]:text-[13px] text-[12px] text-[#ccc]">
229
+ Agotado
230
+ </span>
231
+ </div>
232
+ ) : null}
233
+ </div>
234
+ );
235
+ };
236
+
186
237
  const renderSeats = () => {
187
238
  if (isPeru) {
188
239
  return renderPeruSeats();
@@ -262,7 +313,14 @@ function SeatSectionMobile({
262
313
 
263
314
  return (
264
315
  <div className="content-center relative" style={{ width: "40%" }}>
265
- {hasDiscount && discountSeat ? (
316
+ {serviceItem?.is_dp_enabled ? (
317
+ <div
318
+ className="flex flex-col justify-between h-[2.5rem]"
319
+ style={{ gap: isSoldOut ? "0px" : "5px" }}
320
+ >
321
+ {renderDpSeats()}
322
+ </div>
323
+ ) : hasDiscount && discountSeat ? (
266
324
  <div className="relative grid grid-cols-[auto_auto] justify-between gap-x-[8px] ">
267
325
  {discountValue != null && (
268
326
  <div
@@ -24,7 +24,7 @@ const ServiceBadgesMobile: React.FC<ServiceBadgesMobileProps> = ({
24
24
  isConexion,
25
25
  }) => {
26
26
  return (
27
- <div className="absolute -top-[9px] left-0 w-full flex items-center justify-end gap-[12px] pr-[17px] z-10">
27
+ <div className="absolute -top-[10px] left-0 w-full flex items-center justify-end gap-[12px] pr-[17px] z-10">
28
28
  {showTopLabel && (
29
29
  <div
30
30
  className={`flex items-center gap-[2px] py-[4px] px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] z-20`}