kupos-ui-components-lib 10.4.28 → 10.4.30

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.
@@ -67,7 +67,7 @@ const ANIMATION_MAP = {
67
67
  },
68
68
  };
69
69
  function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isSeatIcon, showAvailableSeats, isPeru, siteType, isAllinBus, viewersConfig, isExpand, setIsExpand, coachKey, isLoggedIn, showLoginModal, isFlores, isNewUiEnabled, showLoginOption, priority_stage_ids, t = (key) => key, }) {
70
- var _a, _b, _c, _d, _e;
70
+ var _a, _b, _c, _d, _e, _f;
71
71
  const getAnimationIcon = (icon) => {
72
72
  var _a;
73
73
  const animation = ANIMATION_MAP[icon];
@@ -111,6 +111,8 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
111
111
  })();
112
112
  let isSoldOut = serviceItem.available_seats <= 0;
113
113
  const hasDpEnabled = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) === true;
114
+ const peruDiscount = (_a = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discounts) === null || _a === void 0 ? void 0 : _a[0];
115
+ const uiType = peruDiscount === null || peruDiscount === void 0 ? void 0 : peruDiscount.ui_type;
114
116
  const renderIcon = (iconKey, size = "14px") => {
115
117
  var _a;
116
118
  const iconValue = (_a = serviceItem.icons) === null || _a === void 0 ? void 0 : _a[iconKey];
@@ -312,10 +314,10 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
312
314
  const key = Object.keys(stageObj)[0];
313
315
  return stageObj[key][0].split(", ")[0];
314
316
  };
315
- const boardingName = ((_a = serviceItem.stage_details_arr) === null || _a === void 0 ? void 0 : _a.length)
317
+ const boardingName = ((_b = serviceItem.stage_details_arr) === null || _b === void 0 ? void 0 : _b.length)
316
318
  ? extractStage(serviceItem.stage_details_arr, 0)
317
319
  : null;
318
- const dropoffName = ((_b = serviceItem.stage_details_arr) === null || _b === void 0 ? void 0 : _b.length)
320
+ const dropoffName = ((_c = serviceItem.stage_details_arr) === null || _c === void 0 ? void 0 : _c.length)
319
321
  ? extractStage(serviceItem.stage_details_arr, 1)
320
322
  : null;
321
323
  const countdownSeconds = 599;
@@ -388,17 +390,23 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
388
390
  },
389
391
  ];
390
392
  const seats = removeDuplicateSeats
391
- ? ((_c = serviceItem.seat_types) === null || _c === void 0 ? void 0 : _c.filter((seat, index, self) => index === self.findIndex((s) => s.label === seat.label))) || []
393
+ ? ((_d = serviceItem.seat_types) === null || _d === void 0 ? void 0 : _d.filter((seat, index, self) => index === self.findIndex((s) => s.label === seat.label))) || []
392
394
  : serviceItem.seat_types || [];
393
395
  const discountedSeats = seats.map((seat) => (Object.assign(Object.assign({}, seat), CommonService.calculateDiscountedPrice(seat.fare, serviceItem))));
394
396
  const hasDiscount = discountedSeats.some((seat) => seat.originalPrice !== seat.discountedPrice);
395
397
  const otherItems = items.filter((i) => i.key !== "pet" && i.key !== "flexible" && !!i.condition);
396
398
  const isItemExpanded = serviceItem.id === isExpand || isExpand === true;
397
399
  const grayscaleClass = isSoldOut ? "grayscale" : "";
398
- const hasOfferText = Boolean(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text);
400
+ // Offer text is only ever shown when the discount's new UI is enabled
401
+ // (tiers B/C). Tier A must stay unchanged even if the backend still sends
402
+ // an offer_text.
403
+ const hasOfferText = isNewUiEnabled && Boolean(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text);
404
+ // Tier C (ui_type 2) always shows the bottom ribbon — timer, bomb
405
+ // animation and viewers count don't depend on offer_text being present.
406
+ const isFullNewUi = isNewUiEnabled && uiType === 2;
399
407
  const offerGradient = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"} 0%, ${colors.leftGradiantColor || "#ff8842"} 100%)`;
400
408
  const offerGradientWithOpacity = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"}80 0%, ${colors.leftGradiantColor || "#ff8842"}80 100%)`;
401
- const serviceCardStyle = (hasOfferText || isNewUiEnabled || hasDpEnabled || hasDiscount) &&
409
+ const serviceCardStyle = (isFullNewUi || hasDpEnabled) &&
402
410
  !isSoldOut
403
411
  ? {
404
412
  borderColor: "transparent",
@@ -409,24 +417,23 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
409
417
  // zIndex: 1,
410
418
  }
411
419
  : {};
412
- return (React.createElement("div", { className: `relative hover:z-[150] ${(hasOfferText || hasDpEnabled || isNewUiEnabled) && !isSoldOut ? "mb-[65px]" : "mb-[20px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
420
+ return (React.createElement("div", { className: `relative hover:z-[150] ${(hasOfferText || hasDpEnabled || isFullNewUi) && !isSoldOut ? "mb-[65px]" : "mb-[20px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
413
421
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.train_type_label) === "Tren Express (Nuevo)" ||
414
422
  showTopLabel
415
423
  ? "mt-[30px]"
416
424
  : "mt-[20px]"} ` },
417
- ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || hasDpEnabled || hasDiscount) &&
418
- !isSoldOut && (React.createElement(PeruOfferBanner, { offerGradient: offerGradient, isSoldOut: isSoldOut, serviceItem: serviceItem, renderIcon: renderIcon, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, viewersConfig: viewersConfig, getAnimationIcon: getAnimationIcon, showLoginOption: showLoginOption, colors: colors, coachKey: coachKey, isExpand: isExpand, isNewUiEnabled: isNewUiEnabled })),
419
- React.createElement("div", { id: `service-card-${serviceItem.id}`, className: `bg-white mx-auto relative ${(hasOfferText || isNewUiEnabled || hasDiscount || hasDpEnabled) &&
425
+ (hasOfferText || hasDpEnabled || isFullNewUi) && !isSoldOut && (React.createElement(PeruOfferBanner, { offerGradient: offerGradient, isSoldOut: isSoldOut, serviceItem: serviceItem, renderIcon: renderIcon, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, viewersConfig: viewersConfig, getAnimationIcon: getAnimationIcon, showLoginOption: showLoginOption, colors: colors, coachKey: coachKey, isExpand: isExpand, isNewUiEnabled: isNewUiEnabled, uiType: uiType })),
426
+ React.createElement("div", { id: `service-card-${serviceItem.id}`, className: `bg-white mx-auto relative ${(isFullNewUi || hasDpEnabled) &&
420
427
  !isSoldOut
421
428
  ? "z-[3] rounded-[18px]"
422
429
  : "rounded-[10px] border border-[#ccc]"}`, style: serviceCardStyle },
423
430
  React.createElement("div", { className: " pt-[20px]", style: {
424
- padding: hasOfferText
431
+ padding: hasOfferText || isFullNewUi
425
432
  ? "20px 15px 10px 15px"
426
433
  : coachKey
427
434
  ? "20px 15px 20px 15px"
428
435
  : "20px 15px 10px 15px",
429
- marginTop: hasDiscount || hasOfferText ? "14px" : "",
436
+ marginTop: hasDiscount || hasOfferText || isFullNewUi ? "14px" : "",
430
437
  } },
431
438
  React.createElement("div", { className: "grid text-[#464647] w-full [grid-template-columns:14%_40%_0.5%_24%_13.5%] gap-x-[2%] items-center",
432
439
  // style={{ marginTop: showTopLabel ? "8px" : "" }}
@@ -451,10 +458,10 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
451
458
  } },
452
459
  React.createElement("div", { className: "flex flex-col gap-[4px]" },
453
460
  orignLabel ? (React.createElement("div", { className: "w-[60px] h-[20px] flex items-center bold-text" }, orignLabel)) : (React.createElement("div", { className: "h-[20px] flex items-center" },
454
- React.createElement("img", { src: (_d = serviceItem.icons) === null || _d === void 0 ? void 0 : _d.origin, alt: "origin", className: `w-[18px] h-auto mr-[8px] ${isSoldOut ? "grayscale" : ""}` }))),
461
+ React.createElement("img", { src: (_e = serviceItem.icons) === null || _e === void 0 ? void 0 : _e.origin, alt: "origin", className: `w-[18px] h-auto mr-[8px] ${isSoldOut ? "grayscale" : ""}` }))),
455
462
  !isCiva &&
456
463
  (destinationLabel ? (React.createElement("div", { className: "w-[60px] h-[20px] flex items-center bold-text" }, destinationLabel)) : (React.createElement("div", { className: "h-[20px] flex items-center" },
457
- React.createElement("img", { src: (_e = serviceItem.icons) === null || _e === void 0 ? void 0 : _e.destination, className: `w-[18px] h-auto mr-[8px] ${isSoldOut ? "grayscale" : ""}`, style: { opacity: isSoldOut ? 0.5 : 1 } }))))),
464
+ React.createElement("img", { src: (_f = serviceItem.icons) === null || _f === void 0 ? void 0 : _f.destination, className: `w-[18px] h-auto mr-[8px] ${isSoldOut ? "grayscale" : ""}`, style: { opacity: isSoldOut ? 0.5 : 1 } }))))),
458
465
  React.createElement("div", { className: "flex flex-col gap-[4px]" },
459
466
  React.createElement(StageTooltip, { stageData: serviceItem.boarding_stages, direction: 1, terminals: busStage, serviceItem: serviceItem, metaData: metaData, colors: colors },
460
467
  React.createElement("span", { className: "cursor-pointer bold-text capitalize" }, DateService.getServiceItemDate(serviceItem.travel_date))),
@@ -6,6 +6,7 @@ import DateTimeSectionMobile from "../../ui/mobileweb/DateTimeSectionMobile";
6
6
  import ExpandedDropdownMobile from "../../ui/mobileweb/ExpandedDropdownMobile";
7
7
  import ServiceBadgesMobile from "../../ui/mobileweb/ServiceBadgesMobile";
8
8
  const SEAT_EXCEPTIONS = ["Asiento mascota"];
9
+ const OFFER_TEXT_MAX_CHARS = 20;
9
10
  const exceptions = [
10
11
  "gy",
11
12
  ".gy",
@@ -18,7 +19,7 @@ const exceptions = [
18
19
  "asiento_mascota",
19
20
  ];
20
21
  function PeruServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig, operatorLabel, isTrain, isFeatureDropDownExpand, setIsFeatureDropDownExpand, ticketQuantity, onIncreaseTicketQuantity, onDecreaseTicketQuantity, cityOrigin, cityDestination, isNewUiEnabled, onRemateUiButtonClick, selectedTimeSlot, onTimeSlotChange, isTimeDropdownOpen, onTimeDropdownToggle, wowDealData, isFlores, isAllinBus, }) {
21
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
22
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
22
23
  const isItemExpanded = serviceItem.id === isExpanded;
23
24
  const isPetSeat = (Object.keys((_a = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.pet_seat_info) !== null && _a !== void 0 ? _a : {}) || []).length > 0;
24
25
  let isSoldOut = serviceItem.available_seats <= 0;
@@ -28,14 +29,28 @@ function PeruServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStag
28
29
  const discountedSeats = seats.map((seat) => (Object.assign(Object.assign({}, seat), commonService.calculateDiscountedPrice(seat.fare, serviceItem))));
29
30
  const hasDiscount = discountedSeats.some((seat) => seat.originalPrice !== seat.discountedPrice);
30
31
  const isLongOfferText = (((_c = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) === null || _c === void 0 ? void 0 : _c.length) || 0) > 35;
32
+ const offerText = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "";
33
+ const displayOfferText = offerText.length > OFFER_TEXT_MAX_CHARS
34
+ ? `${offerText.slice(0, OFFER_TEXT_MAX_CHARS).trimEnd()}...`
35
+ : offerText;
31
36
  const hasDpEnabled = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) === true;
37
+ const hasDpRibbon = hasDpEnabled && Boolean(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents);
38
+ // ui_type comes from the active discount entry: 1 = offer-text-only tier,
39
+ // 2 = full new-UI tier (timer, bomb animation, viewers).
40
+ const peruDiscount = (_d = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discounts) === null || _d === void 0 ? void 0 : _d[0];
41
+ const uiType = peruDiscount === null || peruDiscount === void 0 ? void 0 : peruDiscount.ui_type;
32
42
  const isDiscountBelow20 = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value) > 0 &&
33
43
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value) < 20;
34
- const hasOfferText = Boolean(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text);
44
+ // Offer text is only ever shown when the discount's new UI is enabled
45
+ // (tiers B/C). Tier A must stay unchanged even if the backend still sends
46
+ // an offer_text.
47
+ const hasOfferText = isNewUiEnabled && Boolean(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text);
48
+ // Tier B: offer text only, no timer/viewers. Tier C: full ribbon.
49
+ const isOfferTextOnly = isNewUiEnabled && uiType === 1 && hasOfferText;
50
+ const isFullNewUi = isNewUiEnabled && uiType === 2;
35
51
  const offerGradient = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"} 0%, ${colors.leftGradiantColor || "#ff8842"} 100%)`;
36
52
  const offerGradientWithOpacity = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"}80 0%, ${colors.leftGradiantColor || "#ff8842"}80 100%)`;
37
- const serviceCardStyle = isNewUiEnabled ||
38
- ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents))
53
+ const serviceCardStyle = isFullNewUi || hasDpRibbon
39
54
  ? {
40
55
  borderColor: isSoldOut ? "#ccc" : "transparent",
41
56
  borderStyle: "solid",
@@ -96,10 +111,10 @@ function PeruServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStag
96
111
  const key = Object.keys(stageObj)[0];
97
112
  return stageObj[key][0].split(", ")[0];
98
113
  };
99
- const boardingName = ((_d = serviceItem.stage_details_arr) === null || _d === void 0 ? void 0 : _d.length)
114
+ const boardingName = ((_e = serviceItem.stage_details_arr) === null || _e === void 0 ? void 0 : _e.length)
100
115
  ? extractStage(serviceItem.stage_details_arr, 0)
101
116
  : null;
102
- const dropoffName = ((_e = serviceItem.stage_details_arr) === null || _e === void 0 ? void 0 : _e.length)
117
+ const dropoffName = ((_f = serviceItem.stage_details_arr) === null || _f === void 0 ? void 0 : _f.length)
103
118
  ? extractStage(serviceItem.stage_details_arr, 1)
104
119
  : null;
105
120
  return (React.createElement("div", { className: `relative ${!hasOfferText || !(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) ||
@@ -109,10 +124,7 @@ function PeruServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStag
109
124
  boardingName
110
125
  ? "mt-[20px]"
111
126
  : "mt-[10px]"} `, style: { zIndex: 1 } },
112
- React.createElement("div", { className: `z-1 ${(isNewUiEnabled ||
113
- ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) &&
114
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents))) &&
115
- !isSoldOut
127
+ React.createElement("div", { className: `z-1 ${(isFullNewUi || hasDpRibbon) && !isSoldOut
116
128
  ? "rounded-[18px]"
117
129
  : "rounded-[10px] border border-[#ccc]"}`, style: Object.assign(Object.assign({}, serviceCardStyle), { backgroundColor: "#fff" }) },
118
130
  React.createElement("div", { style: {
@@ -136,25 +148,22 @@ function PeruServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStag
136
148
  color: isSoldOut ? "#bbb" : "text-[#464647]",
137
149
  } },
138
150
  React.createElement("span", { className: "ml-[3px] min-[420]:text-[13px] text-[12px] text-ellipsis overflow-hidden whitespace-nowrap max-w-[120px]" }, serviceItem.operator_details[2]))))) : null)),
139
- React.createElement(DateTimeSectionMobile, { onBookButtonPress: onBookButtonPress, isCiva: isCiva, isSoldOut: isSoldOut, isLinatal: isLinatal, isPeru: isPeru, orignLabel: orignLabel, destinationLabel: destinationLabel, originIcon: (_f = serviceItem.icons) === null || _f === void 0 ? void 0 : _f.origin, destinationIcon: (_g = serviceItem.icons) === null || _g === void 0 ? void 0 : _g.destination, travelDate: serviceItem.travel_date, arrivalDate: serviceItem.arrival_date, depTime: serviceItem.dep_time, arrTime: serviceItem.arr_time, seatTypes: serviceItem.seat_types, seatPriceColor: colors.seatPriceColor, tooltipBgColor: colors.tooltipBgColor, currencySign: currencySign, availableSeats: serviceItem.available_seats, removeDuplicateSeats: removeDuplicateSeats, serviceItem: serviceItem, showLastSeats: showLastSeats, discountSeatPriceColor: colors.discountSeatPriceColor, isTrain: isTrain }),
151
+ React.createElement(DateTimeSectionMobile, { onBookButtonPress: onBookButtonPress, isCiva: isCiva, isSoldOut: isSoldOut, isLinatal: isLinatal, isPeru: isPeru, orignLabel: orignLabel, destinationLabel: destinationLabel, originIcon: (_g = serviceItem.icons) === null || _g === void 0 ? void 0 : _g.origin, destinationIcon: (_h = serviceItem.icons) === null || _h === void 0 ? void 0 : _h.destination, travelDate: serviceItem.travel_date, arrivalDate: serviceItem.arrival_date, depTime: serviceItem.dep_time, arrTime: serviceItem.arr_time, seatTypes: serviceItem.seat_types, seatPriceColor: colors.seatPriceColor, tooltipBgColor: colors.tooltipBgColor, currencySign: currencySign, availableSeats: serviceItem.available_seats, removeDuplicateSeats: removeDuplicateSeats, serviceItem: serviceItem, showLastSeats: showLastSeats, discountSeatPriceColor: colors.discountSeatPriceColor, isTrain: isTrain }),
140
152
  hasDiscount && (React.createElement("div", { className: "flex justify-end" }, isSoldOut ? (React.createElement("span", { className: "col-span-2 min-[420]:text-[13px] text-right text-[12px] text-[#ccc]" }, "Agotado")) : null)),
141
153
  showLastSeats ? (React.createElement("div", { className: "flex justify-end " }, (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) < 10 &&
142
154
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) > 0 && (React.createElement("div", { className: "text-[10px] text-center", style: {
143
155
  color: colors.tooltipBgColor,
144
156
  } }, "\u00A1\u00DAltimos Asientos!")))) : null,
145
157
  React.createElement("div", { className: "bg-[#E6E6E6] mt-[10px] mb-[8px] h-[1px]" }),
146
- React.createElement(BottomAmenitiesMobile, { isSoldOut: isSoldOut, amenitiesNodes: amenities(), hoursIcon: renderIcon("hours", "14px"), duration: (_h = serviceItem.duration) === null || _h === void 0 ? void 0 : _h.toString(), isDirectTrip: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip, directoColor: colors.directoColor, directoAnim: (_j = serviceItem.icons) === null || _j === void 0 ? void 0 : _j.directoAnim, isChangeTicket: serviceItem.is_change_ticket, isPetSeat: isPetSeat, petSeatInfo: serviceItem.pet_seat_info, petFriendlyAnim: (_k = serviceItem.icons) === null || _k === void 0 ? void 0 : _k.petFriendlyAnim, flexibleAnim: (_l = serviceItem.icons) === null || _l === void 0 ? void 0 : _l.flexibleAnim, isTrackingEnabled: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_tracking_enabled, locationAnim: (_m = serviceItem.icons) === null || _m === void 0 ? void 0 : _m.locationAnim, downArrowIcon: (_o = serviceItem.icons) === null || _o === void 0 ? void 0 : _o.downArrow, showDropdown: isItemExpanded, setShowDropdown: () => setIsExpanded &&
158
+ React.createElement(BottomAmenitiesMobile, { isSoldOut: isSoldOut, amenitiesNodes: amenities(), hoursIcon: renderIcon("hours", "14px"), duration: (_j = serviceItem.duration) === null || _j === void 0 ? void 0 : _j.toString(), isDirectTrip: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip, directoColor: colors.directoColor, directoAnim: (_k = serviceItem.icons) === null || _k === void 0 ? void 0 : _k.directoAnim, isChangeTicket: serviceItem.is_change_ticket, isPetSeat: isPetSeat, petSeatInfo: serviceItem.pet_seat_info, petFriendlyAnim: (_l = serviceItem.icons) === null || _l === void 0 ? void 0 : _l.petFriendlyAnim, flexibleAnim: (_m = serviceItem.icons) === null || _m === void 0 ? void 0 : _m.flexibleAnim, isTrackingEnabled: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_tracking_enabled, locationAnim: (_o = serviceItem.icons) === null || _o === void 0 ? void 0 : _o.locationAnim, downArrowIcon: (_p = serviceItem.icons) === null || _p === void 0 ? void 0 : _p.downArrow, showDropdown: isItemExpanded, setShowDropdown: () => setIsExpanded &&
147
159
  setIsExpanded(isItemExpanded ? null : serviceItem.id), onDropdownToggle: () => {
148
160
  setIsExpanded &&
149
161
  setIsExpanded(isItemExpanded ? null : serviceItem.id);
150
- }, isPeru: isPeru, femaleAnim: (_p = serviceItem.icons) === null || _p === void 0 ? void 0 : _p.femaleAnim, ladiesBookedSeats: serviceItem.ladies_booked_seats, isDpEnabled: serviceItem.is_dp_enabled, isTrain: isTrain, seatCategoryText: serviceItem.api_type === 78 && serviceItem.number
162
+ }, isPeru: isPeru, femaleAnim: (_q = serviceItem.icons) === null || _q === void 0 ? void 0 : _q.femaleAnim, ladiesBookedSeats: serviceItem.ladies_booked_seats, isDpEnabled: serviceItem.is_dp_enabled, isTrain: isTrain, seatCategoryText: serviceItem.api_type === 78 && serviceItem.number
151
163
  ? serviceItem.number
152
164
  : undefined })),
153
165
  React.createElement(ServiceBadgesMobile, { showTopLabel: showTopLabel, isSoldOut: isSoldOut, colors: colors, renderIcon: renderIcon, serviceItem: serviceItem, isConexion: isConexion, isAllinBus: isAllinBus, boardingName: boardingName !== null && boardingName !== void 0 ? boardingName : undefined })),
154
- hasOfferText &&
155
- !isNewUiEnabled &&
156
- !isSoldOut &&
157
- !(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: {
166
+ isOfferTextOnly && !isSoldOut && !hasDpRibbon && (React.createElement("div", { className: "px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]", style: {
158
167
  background: colors === null || colors === void 0 ? void 0 : colors.bottomStripColor,
159
168
  borderRadius: "0 0 14px 14px",
160
169
  zIndex: -1,
@@ -163,15 +172,13 @@ function PeruServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStag
163
172
  React.createElement("div", { className: "flex justify-between items-center" },
164
173
  React.createElement("div", { className: `flex ${((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "").length > 10 ? "items-start" : "items-center"}` },
165
174
  React.createElement("div", { className: isLongOfferText ? "mt-[2px]" : "" },
166
- React.createElement(LottiePlayer, { animationData: (_q = serviceItem.icons) === null || _q === void 0 ? void 0 : _q.promoAnim, width: "14px", height: "14px" })),
175
+ React.createElement(LottiePlayer, { animationData: (_r = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.icons) === null || _r === void 0 ? void 0 : _r.promoAnim, width: "14px", height: "14px" })),
167
176
  React.createElement("div", { className: `ml-[4px] flex-1 outline-none ${isLongOfferText ? "mt-[2px]" : ""}`, style: {
168
177
  color: "#fff",
169
178
  lineHeight: 1.4,
170
179
  } },
171
180
  React.createElement("span", { className: "whitespace-nowrap min-[380px]:text-[12px]" }, serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text))))))),
172
- (isNewUiEnabled ||
173
- ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents))) &&
174
- !isSoldOut && (React.createElement("div", { className: "px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]", style: {
181
+ (isFullNewUi || hasDpRibbon) && !isSoldOut && (React.createElement("div", { className: "px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]", style: {
175
182
  background: isSoldOut ? offerGradientWithOpacity : offerGradient,
176
183
  borderRadius: "0 0 14px 14px",
177
184
  zIndex: -1,
@@ -179,27 +186,23 @@ function PeruServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStag
179
186
  React.createElement("div", { className: "flex flex-col gap-[8px] text-[12px] min-[420px]:text-[12px] text-[#464647]", style: { lineHeight: 1.6 } },
180
187
  React.createElement("div", { className: "flex justify-between items-center" },
181
188
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) &&
182
- Object.keys((_r = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents) !== null && _r !== void 0 ? _r : {}).length ===
189
+ Object.keys((_s = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents) !== null && _s !== void 0 ? _s : {}).length ===
183
190
  0 &&
184
- ((_s = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discounted_seats) !== null && _s !== void 0 ? _s : []).length === 0 ? (React.createElement("div", { className: "flex items-center gap-[6px]" },
185
- React.createElement(LottiePlayer, { animationData: (_t = serviceItem.icons) === null || _t === void 0 ? void 0 : _t.starAnimation, width: "14px", height: "14px" }),
191
+ ((_t = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discounted_seats) !== null && _t !== void 0 ? _t : []).length === 0 ? (React.createElement("div", { className: "flex items-center gap-[6px]" },
192
+ React.createElement(LottiePlayer, { animationData: (_u = serviceItem.icons) === null || _u === void 0 ? void 0 : _u.starAnimation, width: "14px", height: "14px" }),
186
193
  React.createElement("span", { className: "text-[#fff]" }, "M\u00E1s elegido"))) : (React.createElement("div", { className: `flex ${((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "").length > 10 ? "items-start" : "items-center"}` },
187
- React.createElement("div", { className: isLongOfferText ? "mt-[2px]" : "" }, ((_u = serviceItem.icons) === null || _u === void 0 ? void 0 : _u.bombAnim) && (React.createElement(LottiePlayer, { animationData: serviceItem.icons.bombAnim, width: "14px", height: "14px" }))),
194
+ React.createElement("div", { className: isLongOfferText ? "mt-[2px]" : "" }, ((_v = serviceItem.icons) === null || _v === void 0 ? void 0 : _v.bombAnim) && (React.createElement(LottiePlayer, { animationData: serviceItem.icons.bombAnim, width: "14px", height: "14px" }))),
188
195
  React.createElement("div", { className: `ml-[4px] flex-1 outline-none ${isLongOfferText ? "mt-[2px]" : ""}`, style: {
189
196
  color: "#fff",
190
197
  lineHeight: 1.4,
191
- } }, !isNewUiEnabled && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) ? (React.createElement("span", { className: "whitespace-nowrap min-[380px]:text-[12px]" }, serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text)) : (React.createElement("span", { className: "whitespace-nowrap min-[380px]:text-[12px]" },
192
- "Termina en\u00A0",
193
- React.createElement("span", { className: "bold-text", ref: (node) => commonService.startCountdown(node, 599), style: {
194
- fontVariantNumeric: "tabular-nums",
195
- display: "inline-block",
196
- } })))))),
198
+ } },
199
+ React.createElement("span", { className: "whitespace-nowrap min-[380px]:text-[12px]" }, displayOfferText)))),
197
200
  React.createElement("div", { className: "flex flex-col items-end", style: {
198
201
  color: "#fff",
199
202
  } },
200
203
  React.createElement("div", { className: "flex items-center" },
201
204
  React.createElement("div", { className: "mr-[4px]" },
202
- React.createElement(LottiePlayer, { animationData: (_v = serviceItem.icons) === null || _v === void 0 ? void 0 : _v.dotAnimation, width: "12px", height: "12px" })),
205
+ React.createElement(LottiePlayer, { animationData: (_w = serviceItem.icons) === null || _w === void 0 ? void 0 : _w.dotAnimation, width: "12px", height: "12px" })),
203
206
  React.createElement("span", { className: "flex-1", style: { lineHeight: 1.4 } },
204
207
  React.createElement("span", { className: "bold-text", ref: (node) => commonService.startViewerCount(node, viewersConfig), style: { fontVariantNumeric: "tabular-nums" } }),
205
208
  " ",
@@ -216,25 +219,17 @@ function PeruServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStag
216
219
  opacity: isItemExpanded ? 1 : 0,
217
220
  transition: "grid-template-rows 0.3s ease-in-out, opacity 0.25s ease-in-out",
218
221
  position: "relative",
219
- zIndex: hasOfferText ||
220
- ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents)) ||
221
- isNewUiEnabled
222
- ? -2
223
- : -1,
222
+ zIndex: isOfferTextOnly || isFullNewUi || hasDpRibbon ? -2 : -1,
224
223
  } },
225
224
  React.createElement("div", { style: {
226
225
  overflow: "hidden",
227
226
  minHeight: 0,
228
- position: hasOfferText || isNewUiEnabled || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled)
227
+ position: isOfferTextOnly || isFullNewUi || hasDpEnabled
229
228
  ? "relative"
230
229
  : undefined,
231
- zIndex: (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) ||
232
- isNewUiEnabled ||
233
- ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents))
234
- ? -3
235
- : undefined,
230
+ zIndex: isOfferTextOnly || isFullNewUi || hasDpRibbon ? -3 : undefined,
236
231
  marginTop: hasOfferText ? "-15px" : "-10px",
237
232
  } },
238
- React.createElement(ExpandedDropdownMobile, { serviceItem: serviceItem, isPeru: isPeru, petSeatInfo: serviceItem.pet_seat_info, petFriendlyAnim: (_w = serviceItem.icons) === null || _w === void 0 ? void 0 : _w.petFriendlyAnim, isSoldOut: isSoldOut, isChangeTicket: serviceItem.is_change_ticket === true, ladiesBookedSeats: serviceItem.ladies_booked_seats, isDpEnabled: serviceItem.is_dp_enabled, femaleAnim: (_x = serviceItem.icons) === null || _x === void 0 ? void 0 : _x.femaleAnim, flexibleAnim: (_y = serviceItem.icons) === null || _y === void 0 ? void 0 : _y.flexibleAnim, renderIcon: renderIcon, operatorLabel: operatorLabel })))));
233
+ React.createElement(ExpandedDropdownMobile, { serviceItem: serviceItem, isPeru: isPeru, petSeatInfo: serviceItem.pet_seat_info, petFriendlyAnim: (_x = serviceItem.icons) === null || _x === void 0 ? void 0 : _x.petFriendlyAnim, isSoldOut: isSoldOut, isChangeTicket: serviceItem.is_change_ticket === true, ladiesBookedSeats: serviceItem.ladies_booked_seats, isDpEnabled: serviceItem.is_dp_enabled, femaleAnim: (_y = serviceItem.icons) === null || _y === void 0 ? void 0 : _y.femaleAnim, flexibleAnim: (_z = serviceItem.icons) === null || _z === void 0 ? void 0 : _z.flexibleAnim, renderIcon: renderIcon, operatorLabel: operatorLabel })))));
239
234
  }
240
235
  export default PeruServiceItemMobile;
@@ -317,7 +317,7 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
317
317
  ((isNewUiEnabled && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.ui_type) === 1 && hasOfferText) ||
318
318
  (hasDpEnabled && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents)) ||
319
319
  (isNewUiEnabled && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.ui_type) === 2)) &&
320
- !isSoldOut && (React.createElement(OfferBanner, { offerGradient: offerGradient, isSoldOut: isSoldOut, serviceItem: serviceItem, renderIcon: renderIcon, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, viewersConfig: viewersConfig, getAnimationIcon: getAnimationIcon, showLoginOption: showLoginOption, isNewUiEnabled: isNewUiEnabled, colors: colors, isLinatal: isLinatal, coachKey: coachKey, isExpand: isItemExpanded })),
320
+ !isSoldOut && (React.createElement(OfferBanner, { offerGradient: offerGradient, isSoldOut: isSoldOut, serviceItem: serviceItem, renderIcon: renderIcon, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, viewersConfig: viewersConfig, getAnimationIcon: getAnimationIcon, showLoginOption: showLoginOption, isNewUiEnabled: isNewUiEnabled, colors: colors, isLinatal: isLinatal, coachKey: coachKey, isExpand: isItemExpanded, isPeru: isPeru })),
321
321
  React.createElement("div", { id: `service-card-${serviceItem.id}`, className: `bg-white mx-auto relative ${((isNewUiEnabled && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.ui_type) === 2) ||
322
322
  (hasDpEnabled && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents))) &&
323
323
  !isSoldOut
@@ -21,6 +21,7 @@ const exceptions = [
21
21
  ];
22
22
  function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig, operatorLabel, isTrain, isFeatureDropDownExpand, setIsFeatureDropDownExpand, ticketQuantity, onIncreaseTicketQuantity, onDecreaseTicketQuantity, cityOrigin, cityDestination, isNewUi, onRemateUiButtonClick, selectedTimeSlot, onTimeSlotChange, isTimeDropdownOpen, onTimeDropdownToggle, wowDealData, isFlores, isAllinBus, isPeruSite, priority_stage_ids, }) {
23
23
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
24
+ console.log("🚀 ~ ServiceItemMobile ~ serviceItem:", serviceItem);
24
25
  const isItemExpanded = serviceItem.id === isExpanded;
25
26
  const isPetSeat = (Object.keys(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.pet_seat_info) || []).length > 0;
26
27
  const isNewUiEnabled = ((_b = (_a = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discounts) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.new_ui_enabled) === true;
@@ -210,11 +211,14 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
210
211
  lineHeight: 1.4,
211
212
  } },
212
213
  React.createElement("span", { className: "whitespace-nowrap min-[380px]:text-[12px]" },
213
- "Termina en\u00A0",
214
- React.createElement("span", { className: "bold-text", ref: (node) => commonService.startCountdown(node, 599), style: {
214
+ (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.ui_type) === 2 && isPeru
215
+ ? serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text
216
+ : "Termina en",
217
+ "\u00A0",
218
+ isPeru ? null : (React.createElement("span", { className: "bold-text", ref: (node) => commonService.startCountdown(node, 599), style: {
215
219
  fontVariantNumeric: "tabular-nums",
216
220
  display: "inline-block",
217
- } }))))),
221
+ } })))))),
218
222
  React.createElement("div", { className: "flex flex-col items-end", style: {
219
223
  color: "#fff",
220
224
  } },
@@ -20,6 +20,7 @@ interface OfferBannerProps {
20
20
  coachKey?: number;
21
21
  isExpand?: any;
22
22
  ui_type?: number;
23
+ isPeru?: boolean;
23
24
  }
24
25
  declare const OfferBanner: React.FC<OfferBannerProps>;
25
26
  export default OfferBanner;
@@ -18,7 +18,7 @@ const AnimationIcon = ({ getAnimationIcon, name, width = "18px", height = "18px"
18
18
  const PopularServiceBanner = ({ getAnimationIcon }) => (React.createElement("div", { className: "flex items-center gap-[5px]" },
19
19
  React.createElement(AnimationIcon, { getAnimationIcon: getAnimationIcon, name: "starAnimation" }),
20
20
  React.createElement("span", null, "Servicio popular entre los usuarios")));
21
- const NewUiOfferBanner = ({ offerText, isLoggedIn, showLoginModal, showLoginOption, getAnimationIcon, hideRegister, isNewUiEnabled, showLoginButton, ui_type, }) => (React.createElement("div", { className: "flex items-center" },
21
+ const NewUiOfferBanner = ({ offerText, isLoggedIn, showLoginModal, showLoginOption, getAnimationIcon, hideRegister, isNewUiEnabled, showLoginButton, ui_type, isPeru, }) => (React.createElement("div", { className: "flex items-center" },
22
22
  React.createElement(AnimationIcon, { getAnimationIcon: getAnimationIcon, name: "bombAnimation" }),
23
23
  React.createElement("div", { className: "flex items-center mt-[2px]" },
24
24
  React.createElement("span", { className: "bold-text", style: { marginLeft: offerText ? "6px" : "3px" } },
@@ -32,8 +32,12 @@ const NewUiOfferBanner = ({ offerText, isLoggedIn, showLoginModal, showLoginOpti
32
32
  "\u00A0"),
33
33
  " ",
34
34
  offerText && ui_type !== 2 ? "| " : ui_type === 2 ? "" : "",
35
- "Termina en\u00A0",
36
- React.createElement("span", { className: "bold-text text-end", ref: (node) => CommonService.startCountdown(node, 599), style: { fontVariantNumeric: "tabular-nums", display: "inline-block" } }))));
35
+ ui_type === 2 && isPeru ? offerText : "Termina en",
36
+ "\u00A0",
37
+ isPeru ? null : (React.createElement("span", { className: "bold-text text-end", ref: (node) => CommonService.startCountdown(node, 599), style: {
38
+ fontVariantNumeric: "tabular-nums",
39
+ display: "inline-block",
40
+ } })))));
37
41
  const LegacyOfferBanner = ({ offerText, getAnimationIcon, }) => (React.createElement("div", { className: "flex items-center" },
38
42
  React.createElement(AnimationIcon, { getAnimationIcon: getAnimationIcon, name: "promoAnim" }),
39
43
  React.createElement("div", { className: "flex items-center mt-[2px]" },
@@ -56,7 +60,7 @@ const ViewersCount = ({ serviceItem, viewersConfig, getAnimationIcon, }) => {
56
60
  "comprando")))));
57
61
  };
58
62
  // ─── Main Component ───────────────────────────────────────────────────────────
59
- const OfferBanner = ({ offerGradient, isSoldOut, serviceItem, isLoggedIn, showLoginModal, viewersConfig, getAnimationIcon, showLoginOption, isNewUiEnabled, colors, isLinatal, coachKey, isExpand, }) => {
63
+ const OfferBanner = ({ offerGradient, isSoldOut, serviceItem, isLoggedIn, showLoginModal, viewersConfig, getAnimationIcon, showLoginOption, isNewUiEnabled, colors, isLinatal, coachKey, isExpand, isPeru, }) => {
60
64
  const isDiscountBelow20 = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value) > 0 &&
61
65
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value) < 20;
62
66
  const offerText = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "";
@@ -76,11 +80,11 @@ const OfferBanner = ({ offerGradient, isSoldOut, serviceItem, isLoggedIn, showLo
76
80
  return (React.createElement(LegacyOfferBanner, { offerText: offerText, getAnimationIcon: getAnimationIcon }));
77
81
  }
78
82
  if (hasDp || (isNewUiEnabled && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.ui_type) === 2)) {
79
- return (React.createElement(NewUiOfferBanner, { offerText: offerText, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, showLoginOption: showLoginOption, getAnimationIcon: getAnimationIcon, hideRegister: hasDp, isNewUiEnabled: isNewUiEnabled, showLoginButton: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.show_register_button, ui_type: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.ui_type }));
83
+ return (React.createElement(NewUiOfferBanner, { offerText: offerText, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, showLoginOption: showLoginOption, getAnimationIcon: getAnimationIcon, hideRegister: hasDp, isNewUiEnabled: isNewUiEnabled, showLoginButton: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.show_register_button, ui_type: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.ui_type, isPeru: isPeru }));
80
84
  }
81
85
  return null;
82
86
  };
83
- return (React.createElement("div", { className: `text-white w-full absolute ${coachKey ? "-bottom-[32px]" : isExpand ? "-bottom-[32px]" : "-bottom-[40px]"} rounded-b-[14px] text-[14px] h-[58px] flex items-end pb-[7px]`, style: {
87
+ return (React.createElement("div", { className: `text-white w-full absolute ${coachKey ? "-bottom-[32px]" : isExpand ? "-bottom-[32px]" : "-bottom-[32px]"} rounded-b-[14px] text-[14px] h-[58px] flex items-end pb-[7px]`, style: {
84
88
  background: (isNewUiEnabled && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.ui_type) === 2) ||
85
89
  ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents))
86
90
  ? offerGradient
@@ -19,6 +19,7 @@ interface PeruOfferBannerProps {
19
19
  coachKey?: number;
20
20
  isExpand?: any;
21
21
  isNewUiEnabled?: boolean;
22
+ uiType?: number;
22
23
  }
23
24
  declare const PeruOfferBanner: React.FC<PeruOfferBannerProps>;
24
25
  export default PeruOfferBanner;
@@ -29,11 +29,7 @@ const OfferBannerContent = ({ offerText, isLoggedIn, showLoginModal, showLoginOp
29
29
  : showLoginOption &&
30
30
  showLoginButton && (React.createElement("span", { onClick: showLoginModal, className: "cursor-pointer" }, "- registro")),
31
31
  " ",
32
- "\u00A0"),
33
- " ",
34
- offerText ? "| " : "",
35
- "Termina en\u00A0",
36
- React.createElement("span", { className: "bold-text text-end", ref: (node) => CommonService.startCountdown(node, 599), style: { fontVariantNumeric: "tabular-nums", display: "inline-block" } }))));
32
+ "\u00A0"))));
37
33
  const LegacyOfferBanner = ({ offerText, getAnimationIcon, }) => (React.createElement("div", { className: "flex items-center" },
38
34
  React.createElement(AnimationIcon, { getAnimationIcon: getAnimationIcon, name: "promoAnim" }),
39
35
  React.createElement("div", { className: "flex items-center mb-[2px]" },
@@ -56,35 +52,31 @@ const ViewersCount = ({ serviceItem, viewersConfig, getAnimationIcon, }) => {
56
52
  "comprando")))));
57
53
  };
58
54
  // ─── Main Component ───────────────────────────────────────────────────────────
59
- const PeruOfferBanner = ({ offerGradient, isSoldOut, serviceItem, isLoggedIn, showLoginModal, viewersConfig, getAnimationIcon, showLoginOption, colors, isLinatal, coachKey, isExpand, isNewUiEnabled, }) => {
60
- const isDiscountBelow20 = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value) > 0 &&
61
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value) < 20;
55
+ const PeruOfferBanner = ({ offerGradient, isSoldOut, serviceItem, renderIcon, isLoggedIn, showLoginModal, viewersConfig, getAnimationIcon, showLoginOption, colors, isLinatal, coachKey, isExpand, isNewUiEnabled, uiType, }) => {
62
56
  const offerText = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "";
63
- const isLegacyOffer = !!offerText && !isNewUiEnabled;
64
- // const showViewers = serviceItem?.is_dp_enabled;
65
- const showViewers = isNewUiEnabled;
66
- const background = isLegacyOffer ? colors === null || colors === void 0 ? void 0 : colors.bottomStripColor : offerGradient;
57
+ const hasDp = hasDpDiscounts(serviceItem);
58
+ // Tier B: new UI enabled, ui_type 1 — offer text only, no timer, no viewers.
59
+ const isOfferTextOnly = isNewUiEnabled && uiType === 1 && !!offerText;
60
+ // Tier C: new UI enabled, ui_type 2 — full ribbon (timer, bomb, viewers).
61
+ const isFullNewUi = isNewUiEnabled && uiType === 2;
62
+ const showViewers = isFullNewUi || hasDp;
63
+ const background = isOfferTextOnly
64
+ ? (colors === null || colors === void 0 ? void 0 : colors.bottomStripColor) || offerGradient
65
+ : offerGradient;
67
66
  const renderLeftContent = () => {
68
- const hasDp = hasDpDiscounts(serviceItem);
69
67
  if ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) && !hasDp) {
70
68
  return React.createElement(PopularServiceBanner, { getAnimationIcon: getAnimationIcon });
71
69
  }
72
- // If new UI is enabled, show offer with registro and countdown
73
- if (isNewUiEnabled || offerText || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value)) {
74
- return (React.createElement(OfferBannerContent, { offerText: offerText, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, showLoginOption: showLoginOption, getAnimationIcon: getAnimationIcon, hideRegister: hasDp, showLoginButton: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.show_register_button }));
70
+ if (isOfferTextOnly) {
71
+ return React.createElement(LegacyOfferBanner, { offerText: offerText, getAnimationIcon: getAnimationIcon });
75
72
  }
76
- // If new UI is disabled, show offer text only
77
- if (offerText) {
78
- return (React.createElement(LegacyOfferBanner, { offerText: offerText, getAnimationIcon: getAnimationIcon }));
73
+ if (isFullNewUi || hasDp) {
74
+ return (React.createElement(OfferBannerContent, { offerText: offerText, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, showLoginOption: showLoginOption, getAnimationIcon: getAnimationIcon, hideRegister: hasDp, showLoginButton: serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.show_register_button }));
79
75
  }
80
76
  return null;
81
77
  };
82
78
  return (React.createElement("div", { className: `text-white w-full absolute ${coachKey ? "-bottom-[32px]" : isExpand ? "-bottom-[32px]" : "-bottom-[40px]"} rounded-b-[14px] text-[14px] h-[58px] flex items-end pb-[7px]`, style: {
83
- background: (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) ||
84
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents) ||
85
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value)
86
- ? offerGradient
87
- : background,
79
+ background,
88
80
  opacity: isSoldOut ? 0.5 : 1,
89
81
  zIndex: isLinatal ? "-1" : "0",
90
82
  } },
@@ -71,6 +71,7 @@ function getSeatTypeIcon(label, serviceItem) {
71
71
  return (_d = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.icons) === null || _d === void 0 ? void 0 : _d.seatFallBackIcon;
72
72
  }
73
73
  function PeruSeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, serviceItem, renderIcon, discountSeatPriceColor, isSeatIcon, }) {
74
+ var _a;
74
75
  const uniqueSeats = getUniqueSeats(seatTypes);
75
76
  const sortedSeatTypes = getSortedSeatTypes(seatTypes);
76
77
  const numberOfSeats = getNumberOfSeats(seatTypes);
@@ -125,12 +126,18 @@ function PeruSeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, cur
125
126
  const discountSeat = discountedSeats
126
127
  .filter((seat) => !SEAT_EXCEPTIONS.includes(seat.label))
127
128
  .sort((a, b) => a.discountedPrice - b.discountedPrice)[0];
129
+ // discount_type/discount_value/max_discount live on the service item
130
+ // itself; only ui_type and the ready-made badge text come from discounts[0].
131
+ const peruDiscount = (_a = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discounts) === null || _a === void 0 ? void 0 : _a[0];
132
+ const uiType = peruDiscount === null || peruDiscount === void 0 ? void 0 : peruDiscount.ui_type;
133
+ const discountType = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_type;
134
+ const discountValueRaw = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value;
135
+ const maxDiscount = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.max_discount;
128
136
  const discountValue = (() => {
129
- if ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_type) === "percentage" &&
130
- typeof (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_value) === "number") {
131
- return Math.round(serviceItem.discount_value);
137
+ if (discountType === "percentage" && typeof discountValueRaw === "number") {
138
+ return Math.round(discountValueRaw);
132
139
  }
133
- if ((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.discount_type) === "fixed" && discountSeat) {
140
+ if (discountType === "fixed" && discountSeat) {
134
141
  const { originalPrice, discountedPrice } = discountSeat;
135
142
  if (originalPrice > 0 && originalPrice !== discountedPrice) {
136
143
  return Math.round(((originalPrice - discountedPrice) / originalPrice) * 100);
@@ -139,17 +146,24 @@ function PeruSeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, cur
139
146
  return null;
140
147
  })();
141
148
  const isMaxDiscountApplied = (() => {
142
- const { discount_type, discount_value, max_discount } = serviceItem !== null && serviceItem !== void 0 ? serviceItem : {};
143
- if (discount_type === "percentage" &&
144
- typeof discount_value === "number" &&
145
- max_discount != null &&
146
- max_discount > 0 &&
149
+ if (discountType === "percentage" &&
150
+ typeof discountValueRaw === "number" &&
151
+ maxDiscount != null &&
152
+ maxDiscount > 0 &&
147
153
  discountSeat) {
148
- const rawPercentageDiscount = (discountSeat.originalPrice * discount_value) / 100;
149
- return rawPercentageDiscount > max_discount;
154
+ const rawPercentageDiscount = (discountSeat.originalPrice * discountValueRaw) / 100;
155
+ return rawPercentageDiscount > maxDiscount;
150
156
  }
151
157
  return false;
152
158
  })();
159
+ // Backend-provided ready-made badge text (e.g. "30% OFF" / "$2.000 OFF")
160
+ // takes precedence over the value computed client-side.
161
+ const discountBadgeText = (peruDiscount === null || peruDiscount === void 0 ? void 0 : peruDiscount.discount_display_badge) ||
162
+ (isMaxDiscountApplied
163
+ ? `${CommonService.currency(maxDiscount)} OFF`
164
+ : discountValue != null
165
+ ? `${discountValue}% OFF`
166
+ : null);
153
167
  const renderLabels = () => {
154
168
  const isMovilBus = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.operator_service_name) === "MovilBus" ||
155
169
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.operator_service_name) === "Movil Bus";
@@ -189,18 +203,31 @@ function PeruSeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, cur
189
203
  CommonService.capitalize(seatLabel))) : (React.createElement("span", { className: "text-[13.33px]" }, "Desde")))));
190
204
  };
191
205
  if (hasDiscount && discountSeat) {
206
+ // Tier B (ui_type 1): offer text is announced elsewhere, but the fare
207
+ // itself must render exactly as it would with no discount — no
208
+ // strike-off, no badge, no fire icon.
209
+ if (uiType === 1) {
210
+ return (React.createElement("div", { className: "grid grid-cols-2 items-center text-[13.33px] relative", style: { opacity: isSoldOut ? 0.5 : 1 } },
211
+ React.createElement("div", { className: "col-start-1 row-start-3 flex h-[20px] items-end" },
212
+ React.createElement("span", { className: "text-[13.33px] font-normal leading-[20px] text-[#464647]" }, discountSeat.label)),
213
+ React.createElement("div", { className: "col-start-2 row-start-3 flex h-[30px] items-end justify-center relative" },
214
+ React.createElement("span", { className: "flex items-center gap-[6px] bold-text leading-[30px]", style: {
215
+ color: isSoldOut ? "#c0c0c0" : "#464647",
216
+ fontSize: "13.33px",
217
+ } }, availableSeats <= 0
218
+ ? CommonService.currency(0, currencySign)
219
+ : CommonService.discountedCurrency(discountSeat.originalPrice, currencySign)))));
220
+ }
192
221
  return (React.createElement("div", { className: "grid grid-cols-2 items-center text-[13.33px] relative", style: { opacity: isSoldOut ? 0.5 : 1 } },
193
222
  React.createElement("div", { className: "col-start-1 row-start-2 flex items-center" },
194
223
  React.createElement("span", { className: "text-[13.33px] font-normal leading-[22px] text-[#ccc]" }, "Antes")),
195
224
  React.createElement("div", { className: "col-start-1 row-start-3 flex h-[20px] items-end" },
196
225
  React.createElement("span", { className: "text-[13.33px] font-normal leading-[20px] text-[#464647]" }, "Desde")),
197
- 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 || isMaxDiscountApplied ? (React.createElement("span", { className: "rounded-[100px] bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white", style: {
226
+ React.createElement("div", { className: "col-start-2 row-start-1 flex items-center justify-center absolute", style: { top: "-22px", left: "50%", transform: "translateX(-50%)" } }, discountBadgeText ? (React.createElement("span", { className: "rounded-[100px] bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white", style: {
198
227
  animation: "pulse-zoom 2s ease-in-out infinite",
199
228
  whiteSpace: "nowrap",
200
229
  backgroundColor: discountSeatPriceColor,
201
- } }, isMaxDiscountApplied
202
- ? `${CommonService.currency(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.max_discount)} OFF`
203
- : `${discountValue}% OFF`)) : null),
230
+ } }, discountBadgeText)) : null),
204
231
  React.createElement("div", { className: "col-start-2 row-start-2 flex items-center justify-center ", style: { textAlign: "center" } },
205
232
  React.createElement("span", { className: "text-[13.33px] font-normal leading-[20px] relative whitespace-nowrap", style: {
206
233
  position: "relative",