kupos-ui-components-lib 9.10.3 → 9.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ServiceItem/PeruServiceItemDesktop.js +2 -2
- package/dist/components/ServiceItem/ServiceItemDesktop.js +2 -1
- package/dist/components/ServiceItem/ServiceItemMobile.js +4 -1
- package/dist/components/Survey/SurveyDesktop.js +2 -2
- package/dist/components/Survey/SurveyMobile.js +5 -5
- package/dist/styles.css +6 -0
- package/dist/ui/OfferBanner.d.ts +9 -5
- package/dist/ui/OfferBanner.js +73 -60
- package/package.json +1 -1
- package/src/components/ServiceItem/PeruServiceItemDesktop.tsx +2 -2
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +2 -1
- package/src/components/ServiceItem/ServiceItemMobile.tsx +35 -32
- package/src/components/Survey/SurveyDesktop.tsx +2 -2
- package/src/components/Survey/SurveyMobile.tsx +5 -5
- package/src/ui/OfferBanner.tsx +232 -135
|
@@ -391,10 +391,10 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
|
|
|
391
391
|
: serviceItem.seat_types || [];
|
|
392
392
|
const discountedSeats = seats.map((seat) => (Object.assign(Object.assign({}, seat), CommonService.calculateDiscountedPrice(seat.fare, serviceItem))));
|
|
393
393
|
const hasDiscount = discountedSeats.some((seat) => seat.originalPrice !== seat.discountedPrice);
|
|
394
|
-
return (React.createElement("div", { className: `relative hover:z-[150] ${hasOfferText ? "mb-[
|
|
394
|
+
return (React.createElement("div", { className: `relative hover:z-[150] ${hasOfferText || hasDpEnabled || isNewUiEnabled ? "mb-[65px]" : "mb-[20px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
|
|
395
395
|
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.train_type_label) === "Tren Express (Nuevo)" ||
|
|
396
396
|
showTopLabel
|
|
397
|
-
? "mt-[
|
|
397
|
+
? "mt-[30px]"
|
|
398
398
|
: "mt-[20px]"} ` },
|
|
399
399
|
((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || hasDpEnabled) && !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 })),
|
|
400
400
|
React.createElement("div", { id: `service-card-${serviceItem.id}`, className: `bg-white mx-auto relative ${(hasOfferText && isNewUiEnabled && !isSoldOut) || hasDpEnabled
|
|
@@ -89,6 +89,7 @@ const ANIMATION_MAP = {
|
|
|
89
89
|
};
|
|
90
90
|
function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isPeruSites, showAvailableSeats, isSeatIcon, isLinatal, isPeru, t = (key) => key, siteType, isAllinBus, isExpand, setIsExpand, coachKey, viewersConfig, isNewUi, showLoginModal, isLoggedIn, showLoginOption, isFeatureDropDownExpand, setIsFeatureDropDownExpand, ticketQuantity, onIncreaseTicketQuantity, onDecreaseTicketQuantity, onRemateUiButtonClick, selectedTimeSlot, onTimeSlotChange, isTimeDropdownOpen, onTimeDropdownToggle, wowDealData, isFlores, }) {
|
|
91
91
|
var _a, _b, _c;
|
|
92
|
+
console.log("🚀 ~ ServiceItemPB ~ serviceItem:", serviceItem);
|
|
92
93
|
const getAnimationIcon = (icon) => {
|
|
93
94
|
var _a;
|
|
94
95
|
const animation = ANIMATION_MAP[icon];
|
|
@@ -261,7 +262,7 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
|
|
|
261
262
|
setIsFeatureDropDownExpand(isFeatureDropDownExpand === serviceItem.id ||
|
|
262
263
|
isFeatureDropDownExpand === true
|
|
263
264
|
? null
|
|
264
|
-
: serviceItem.id), selectedTimeSlot: selectedTimeSlot, onTimeSlotChange: onTimeSlotChange, isTimeDropdownOpen: isTimeDropdownOpen, onTimeDropdownToggle: onTimeDropdownToggle, wowDealData: wowDealData })) : (React.createElement("div", { className: `relative hover:z-[150] ${hasOfferText || hasDpEnabled || isNewUiEnabled ? "mb-[
|
|
265
|
+
: serviceItem.id), selectedTimeSlot: selectedTimeSlot, onTimeSlotChange: onTimeSlotChange, isTimeDropdownOpen: isTimeDropdownOpen, onTimeDropdownToggle: onTimeDropdownToggle, wowDealData: wowDealData })) : (React.createElement("div", { className: `relative hover:z-[150] ${hasOfferText || hasDpEnabled || isNewUiEnabled ? "mb-[65px]" : "mb-[20px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
|
|
265
266
|
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.train_type_label) === "Tren Express (Nuevo)" ||
|
|
266
267
|
showTopLabel
|
|
267
268
|
? "mt-[30px]"
|
|
@@ -136,7 +136,10 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
|
|
|
136
136
|
setIsExpanded(isItemExpanded ? null : serviceItem.id);
|
|
137
137
|
}, isPeru: isPeru, femaleAnim: serviceItem.icons.femaleAnim, ladiesBookedSeats: serviceItem.ladies_booked_seats, isDpEnabled: serviceItem.is_dp_enabled })),
|
|
138
138
|
React.createElement(ServiceBadgesMobile, { showTopLabel: showTopLabel, isSoldOut: isSoldOut, colors: colors, renderIcon: renderIcon, serviceItem: serviceItem, isConexion: isConexion })),
|
|
139
|
-
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) &&
|
|
139
|
+
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) &&
|
|
140
|
+
!isNewUiEnabled &&
|
|
141
|
+
!isSoldOut &&
|
|
142
|
+
!(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: {
|
|
140
143
|
background: colors === null || colors === void 0 ? void 0 : colors.bottomStripColor,
|
|
141
144
|
borderRadius: "0 0 14px 14px",
|
|
142
145
|
zIndex: -1,
|
|
@@ -15,9 +15,9 @@ const SurveyDesktop = ({ isOpen, isSubmitted, selectedScore, onScoreChange, feed
|
|
|
15
15
|
React.createElement(React.Fragment, null,
|
|
16
16
|
React.createElement("button", { onClick: onClose, "aria-label": "Close survey", className: "absolute top-[15px] right-[25px] bg-transparent border-none cursor-pointer text-[22px] text-gray-400 flex items-center justify-center p-1 z-10 transition-colors duration-200 hover:text-gray-600" },
|
|
17
17
|
React.createElement("img", { src: icons.closeIcon, alt: "Close", className: "w-[16px] h-[16px] block" })),
|
|
18
|
-
(icons === null || icons === void 0 ? void 0 : icons.surveyIcon) && (React.createElement("div", { className: "flex justify-center mb-
|
|
18
|
+
(icons === null || icons === void 0 ? void 0 : icons.surveyIcon) && (React.createElement("div", { className: "flex justify-center mb-2 mt-2" },
|
|
19
19
|
React.createElement("img", { src: icons.surveyIcon, alt: "Survey Illustration", className: "w-[90px] h-[90px] block" }))),
|
|
20
|
-
React.createElement("h2", { className: "text-[18px] bold-text leading-[1.25] text-center
|
|
20
|
+
React.createElement("h2", { className: "text-[18px] bold-text leading-[1.25] text-center mb-2" }, "Ay\u00FAdanos a mejorar"),
|
|
21
21
|
React.createElement("p", { className: "text-[13.33px] text-center leading-[1.4] mb-6 max-w-[460px] mx-auto" },
|
|
22
22
|
"Bas\u00E1ndote en tu experiencia de compra.",
|
|
23
23
|
React.createElement("br", null),
|
|
@@ -15,17 +15,17 @@ const SurveyMobile = ({ isOpen, isSubmitted, selectedScore, onScoreChange, feedb
|
|
|
15
15
|
React.createElement(React.Fragment, null,
|
|
16
16
|
React.createElement("button", { onClick: onClose, "aria-label": "Close survey", className: "absolute top-[15px] right-[25px] bg-transparent border-none cursor-pointer text-[22px] text-gray-400 flex items-center justify-center p-1 z-10 transition-colors duration-200 hover:text-gray-600" },
|
|
17
17
|
React.createElement("img", { src: icons.closeIcon, alt: "Close", className: "w-[16px] h-[16px] block" })),
|
|
18
|
-
(icons === null || icons === void 0 ? void 0 : icons.surveyIcon) && (React.createElement("div", { className: "flex justify-center mb-
|
|
18
|
+
(icons === null || icons === void 0 ? void 0 : icons.surveyIcon) && (React.createElement("div", { className: "flex justify-center mb-2 mt-2" },
|
|
19
19
|
React.createElement("img", { src: icons.surveyIcon, alt: "Survey Illustration", className: "w-[90px] h-[90px] block" }))),
|
|
20
|
-
React.createElement("h2", { className: "text-[18px] bold-text leading-[1.25] text-center
|
|
21
|
-
React.createElement("p", { className: "text-[13.33px] text-center leading-[1.4] mb-
|
|
20
|
+
React.createElement("h2", { className: "text-[18px] bold-text leading-[1.25] text-center mb-2" }, "Ay\u00FAdanos a mejorar"),
|
|
21
|
+
React.createElement("p", { className: "text-[13.33px] text-center leading-[1.4] mb-8 max-w-[460px] mx-auto" },
|
|
22
22
|
"Bas\u00E1ndote en tu experiencia de compra.",
|
|
23
23
|
React.createElement("br", null),
|
|
24
24
|
"\u00BFNos recomendar\u00EDas a un amigo?"),
|
|
25
25
|
React.createElement(ScoreButtons, { selectedScore: selectedScore, onScoreChange: onScoreChange, buttonHeight: 44, fontSize: 13, gap: 6, colors: colors }),
|
|
26
26
|
React.createElement(FeedbackTextarea, { config: config, feedback: feedback, onFeedbackChange: onFeedbackChange }),
|
|
27
|
-
React.createElement("div", { className: "flex justify-center mt-[
|
|
28
|
-
React.createElement("div", { className: "w-[
|
|
27
|
+
React.createElement("div", { className: "flex justify-center mt-[50px] mb-[50px]" },
|
|
28
|
+
React.createElement("div", { className: "w-[100px]" },
|
|
29
29
|
React.createElement(KuposButton, { isSoldOut: selectedScore == null, isLoading: isLoading || false, buttonColor: "#FF8E43", buyLabel: "Enviar", soldOutLabel: "Enviar", onClick: handleSubmit }))))));
|
|
30
30
|
};
|
|
31
31
|
export default SurveyMobile;
|
package/dist/styles.css
CHANGED
|
@@ -246,6 +246,9 @@
|
|
|
246
246
|
.mt-\[30px\] {
|
|
247
247
|
margin-top: 30px;
|
|
248
248
|
}
|
|
249
|
+
.mt-\[50px\] {
|
|
250
|
+
margin-top: 50px;
|
|
251
|
+
}
|
|
249
252
|
.-mr-\[12px\] {
|
|
250
253
|
margin-right: calc(12px * -1);
|
|
251
254
|
}
|
|
@@ -306,6 +309,9 @@
|
|
|
306
309
|
.mb-\[55px\] {
|
|
307
310
|
margin-bottom: 55px;
|
|
308
311
|
}
|
|
312
|
+
.mb-\[65px\] {
|
|
313
|
+
margin-bottom: 65px;
|
|
314
|
+
}
|
|
309
315
|
.-ml-\[12px\] {
|
|
310
316
|
margin-left: calc(12px * -1);
|
|
311
317
|
}
|
package/dist/ui/OfferBanner.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ServiceItemProps } from "../components/ServiceItem/types";
|
|
3
|
+
type ServiceItemSlice = Pick<ServiceItemProps["serviceItem"], "is_dp_enabled" | "offer_text" | "dp_discount_percents" | "dp_discounted_seats">;
|
|
4
|
+
interface OfferBannerColors {
|
|
5
|
+
bottomStripColor?: string;
|
|
6
|
+
}
|
|
3
7
|
interface OfferBannerProps {
|
|
4
8
|
offerGradient: string;
|
|
5
9
|
isSoldOut: boolean;
|
|
6
|
-
serviceItem:
|
|
10
|
+
serviceItem: ServiceItemSlice;
|
|
7
11
|
renderIcon: (name: string, size: string) => React.ReactNode;
|
|
8
|
-
isLoggedIn:
|
|
9
|
-
showLoginModal:
|
|
12
|
+
isLoggedIn: boolean;
|
|
13
|
+
showLoginModal: () => void;
|
|
10
14
|
viewersConfig: ServiceItemProps["viewersConfig"];
|
|
11
|
-
getAnimationIcon: (name: string) =>
|
|
15
|
+
getAnimationIcon: (name: string) => unknown;
|
|
12
16
|
showLoginOption?: boolean;
|
|
13
17
|
isNewUiEnabled?: boolean;
|
|
14
|
-
colors:
|
|
18
|
+
colors: OfferBannerColors;
|
|
15
19
|
}
|
|
16
20
|
declare const OfferBanner: React.FC<OfferBannerProps>;
|
|
17
21
|
export default OfferBanner;
|
package/dist/ui/OfferBanner.js
CHANGED
|
@@ -1,66 +1,79 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import LottiePlayer from "../assets/LottiePlayer";
|
|
3
3
|
import CommonService from "../utils/CommonService";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
4
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
5
|
+
const OFFER_TEXT_MAX_LENGTH = 30;
|
|
6
|
+
function truncateOfferText(text) {
|
|
7
|
+
return text.length > OFFER_TEXT_MAX_LENGTH
|
|
8
|
+
? `${text.slice(0, OFFER_TEXT_MAX_LENGTH)}...`
|
|
9
|
+
: text;
|
|
10
|
+
}
|
|
11
|
+
function hasDpDiscounts(serviceItem) {
|
|
12
|
+
var _a, _b;
|
|
13
|
+
return (Object.keys((_a = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents) !== null && _a !== void 0 ? _a : {}).length > 0 ||
|
|
14
|
+
((_b = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discounted_seats) !== null && _b !== void 0 ? _b : []).length > 0);
|
|
15
|
+
}
|
|
16
|
+
const AnimationIcon = ({ getAnimationIcon, name, width = "18px", height = "18px", }) => (React.createElement(LottiePlayer, { animationData: getAnimationIcon(name), width: width, height: height }));
|
|
17
|
+
// Shown when DP is enabled but no discounts / discounted seats are present
|
|
18
|
+
const PopularServiceBanner = ({ getAnimationIcon }) => (React.createElement("div", { className: "flex items-center gap-[5px]" },
|
|
19
|
+
React.createElement(AnimationIcon, { getAnimationIcon: getAnimationIcon, name: "starAnimation" }),
|
|
20
|
+
React.createElement("span", null, "Servicio popular entre los usuarios")));
|
|
21
|
+
const NewUiOfferBanner = ({ offerText, isLoggedIn, showLoginModal, showLoginOption, getAnimationIcon, hideRegister, }) => (React.createElement("div", { className: "flex items-center" },
|
|
22
|
+
React.createElement(AnimationIcon, { getAnimationIcon: getAnimationIcon, name: "bombAnimation" }),
|
|
23
|
+
React.createElement("div", { className: "flex items-center mt-[2px]" },
|
|
24
|
+
React.createElement("span", { className: "bold-text", style: { marginLeft: offerText ? "6px" : "3px" } },
|
|
25
|
+
truncateOfferText(offerText),
|
|
26
|
+
" ",
|
|
27
|
+
!hideRegister && (isLoggedIn && showLoginOption ? null : (React.createElement("span", { onClick: showLoginModal, className: "cursor-pointer" }, "- registro"))),
|
|
28
|
+
" ",
|
|
29
|
+
"\u00A0"),
|
|
30
|
+
" ",
|
|
31
|
+
offerText ? "|" : "",
|
|
32
|
+
"Termina en\u00A0",
|
|
33
|
+
React.createElement("span", { className: "bold-text text-end", ref: (node) => CommonService.startCountdown(node, 599), style: { fontVariantNumeric: "tabular-nums", display: "inline-block" } }))));
|
|
34
|
+
const LegacyOfferBanner = ({ offerText, getAnimationIcon, }) => (React.createElement("div", { className: "flex items-center" },
|
|
35
|
+
React.createElement(AnimationIcon, { getAnimationIcon: getAnimationIcon, name: "promoAnim" }),
|
|
36
|
+
React.createElement("div", { className: "flex items-center mt-[2px]" },
|
|
37
|
+
React.createElement("span", { className: "bold-text", style: { marginLeft: offerText ? "6px" : "3px" } }, offerText))));
|
|
38
|
+
const ViewersCount = ({ serviceItem, viewersConfig, getAnimationIcon, }) => {
|
|
39
|
+
const showScarcity = hasDpDiscounts(serviceItem);
|
|
40
|
+
return (React.createElement("div", { className: "flex items-center" },
|
|
41
|
+
React.createElement(AnimationIcon, { getAnimationIcon: getAnimationIcon, name: "dotAnimation", width: "12px", height: "12px" }),
|
|
42
|
+
React.createElement("span", { className: "ml-[6px]" },
|
|
43
|
+
React.createElement("span", { className: "bold-text", ref: (node) => CommonService.startViewerCount(node, viewersConfig), style: { fontVariantNumeric: "tabular-nums" } }),
|
|
44
|
+
" ",
|
|
45
|
+
React.createElement("span", null,
|
|
46
|
+
(viewersConfig === null || viewersConfig === void 0 ? void 0 : viewersConfig.label) || " viendo",
|
|
47
|
+
" |",
|
|
48
|
+
" ",
|
|
49
|
+
React.createElement("span", null,
|
|
50
|
+
showScarcity && "Quedan pocos • ",
|
|
51
|
+
React.createElement("span", { className: "bold-text", ref: (node) => CommonService.startComprandoCount(node, 4, 16), style: { fontVariantNumeric: "tabular-nums" } }),
|
|
31
52
|
" ",
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Object.keys((_c = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents) !== null && _c !== void 0 ? _c : {})
|
|
58
|
-
.length === 0 &&
|
|
59
|
-
((_d = serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discounted_seats) !== null && _d !== void 0 ? _d : []).length === 0
|
|
60
|
-
? null
|
|
61
|
-
: "Quedan pocos • ",
|
|
62
|
-
React.createElement("span", { className: "bold-text", ref: (node) => CommonService.startComprandoCount(node, 4, 16), style: { fontVariantNumeric: "tabular-nums" } }),
|
|
63
|
-
" ",
|
|
64
|
-
"comprando"))))))));
|
|
53
|
+
"comprando")))));
|
|
54
|
+
};
|
|
55
|
+
// ─── Main Component ───────────────────────────────────────────────────────────
|
|
56
|
+
const OfferBanner = ({ offerGradient, isSoldOut, serviceItem, isLoggedIn, showLoginModal, viewersConfig, getAnimationIcon, showLoginOption, isNewUiEnabled, colors, }) => {
|
|
57
|
+
const isLegacyOffer = !!(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) && !isNewUiEnabled && !(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled);
|
|
58
|
+
const isDpEnabledWithoutDiscounts = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) && !hasDpDiscounts(serviceItem);
|
|
59
|
+
const showViewers = isNewUiEnabled || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled);
|
|
60
|
+
const background = isLegacyOffer ? colors === null || colors === void 0 ? void 0 : colors.bottomStripColor : offerGradient;
|
|
61
|
+
const renderLeftContent = () => {
|
|
62
|
+
if (isDpEnabledWithoutDiscounts) {
|
|
63
|
+
return React.createElement(PopularServiceBanner, { getAnimationIcon: getAnimationIcon });
|
|
64
|
+
}
|
|
65
|
+
const hasDp = hasDpDiscounts(serviceItem);
|
|
66
|
+
if (hasDp || (isNewUiEnabled && (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text))) {
|
|
67
|
+
return (React.createElement(NewUiOfferBanner, { offerText: serviceItem.offer_text || "", isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, showLoginOption: showLoginOption, getAnimationIcon: getAnimationIcon, hideRegister: hasDp }));
|
|
68
|
+
}
|
|
69
|
+
if (isLegacyOffer) {
|
|
70
|
+
return (React.createElement(LegacyOfferBanner, { offerText: serviceItem.offer_text, getAnimationIcon: getAnimationIcon }));
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
};
|
|
74
|
+
return (React.createElement("div", { className: "text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[44px] pt-[50px] rounded-b-[14px] text-[14px] mt-[10px]", style: { background, opacity: isSoldOut ? 0.5 : 1 } },
|
|
75
|
+
React.createElement("div", { className: "flex justify-between items-center w-full" },
|
|
76
|
+
React.createElement("div", { className: "flex items-center" }, renderLeftContent()),
|
|
77
|
+
showViewers && (React.createElement(ViewersCount, { serviceItem: serviceItem, viewersConfig: viewersConfig, getAnimationIcon: getAnimationIcon })))));
|
|
65
78
|
};
|
|
66
79
|
export default OfferBanner;
|
package/package.json
CHANGED
|
@@ -605,11 +605,11 @@ function PeruServiceItemDesktop({
|
|
|
605
605
|
|
|
606
606
|
return (
|
|
607
607
|
<div
|
|
608
|
-
className={`relative hover:z-[150] ${hasOfferText ? "mb-[
|
|
608
|
+
className={`relative hover:z-[150] ${hasOfferText || hasDpEnabled || isNewUiEnabled ? "mb-[65px]" : "mb-[20px]"} ${
|
|
609
609
|
serviceItem?.is_direct_trip ||
|
|
610
610
|
serviceItem?.train_type_label === "Tren Express (Nuevo)" ||
|
|
611
611
|
showTopLabel
|
|
612
|
-
? "mt-[
|
|
612
|
+
? "mt-[30px]"
|
|
613
613
|
: "mt-[20px]"
|
|
614
614
|
} `}
|
|
615
615
|
>
|
|
@@ -144,6 +144,7 @@ function ServiceItemPB({
|
|
|
144
144
|
wowDealData,
|
|
145
145
|
isFlores,
|
|
146
146
|
}: ServiceItemProps & { currencySign?: string }): React.ReactElement {
|
|
147
|
+
console.log("🚀 ~ ServiceItemPB ~ serviceItem:", serviceItem);
|
|
147
148
|
const getAnimationIcon = (icon: string) => {
|
|
148
149
|
const animation = ANIMATION_MAP[icon];
|
|
149
150
|
if (!animation) return null;
|
|
@@ -487,7 +488,7 @@ function ServiceItemPB({
|
|
|
487
488
|
/>
|
|
488
489
|
) : (
|
|
489
490
|
<div
|
|
490
|
-
className={`relative hover:z-[150] ${hasOfferText || hasDpEnabled || isNewUiEnabled ? "mb-[
|
|
491
|
+
className={`relative hover:z-[150] ${hasOfferText || hasDpEnabled || isNewUiEnabled ? "mb-[65px]" : "mb-[20px]"} ${
|
|
491
492
|
serviceItem?.is_direct_trip ||
|
|
492
493
|
serviceItem?.train_type_label === "Tren Express (Nuevo)" ||
|
|
493
494
|
showTopLabel
|
|
@@ -386,46 +386,49 @@ function ServiceItemMobile({
|
|
|
386
386
|
</div>
|
|
387
387
|
|
|
388
388
|
{/* 🔹 EXPANDABLE DROPDOWN (below the card) */}
|
|
389
|
-
{serviceItem?.offer_text &&
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
background: colors?.bottomStripColor,
|
|
394
|
-
borderRadius: "0 0 14px 14px",
|
|
395
|
-
zIndex: -1,
|
|
396
|
-
}}
|
|
397
|
-
>
|
|
389
|
+
{serviceItem?.offer_text &&
|
|
390
|
+
!isNewUiEnabled &&
|
|
391
|
+
!isSoldOut &&
|
|
392
|
+
!serviceItem?.is_dp_enabled && (
|
|
398
393
|
<div
|
|
399
|
-
className="
|
|
400
|
-
style={{
|
|
394
|
+
className="px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]"
|
|
395
|
+
style={{
|
|
396
|
+
background: colors?.bottomStripColor,
|
|
397
|
+
borderRadius: "0 0 14px 14px",
|
|
398
|
+
zIndex: -1,
|
|
399
|
+
}}
|
|
401
400
|
>
|
|
402
|
-
<div
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
<LottiePlayer
|
|
408
|
-
animationData={serviceItem.icons.promoAnim}
|
|
409
|
-
width="14px"
|
|
410
|
-
height="14px"
|
|
411
|
-
/>
|
|
412
|
-
</div>
|
|
401
|
+
<div
|
|
402
|
+
className="flex flex-col gap-[8px] text-[12px] min-[420px]:text-[12px] text-[#464647]"
|
|
403
|
+
style={{ lineHeight: 1.6 }}
|
|
404
|
+
>
|
|
405
|
+
<div className="flex justify-between items-center">
|
|
413
406
|
<div
|
|
414
|
-
className={`
|
|
415
|
-
style={{
|
|
416
|
-
color: "#fff",
|
|
417
|
-
lineHeight: 1.4,
|
|
418
|
-
}}
|
|
407
|
+
className={`flex ${(serviceItem?.offer_text || "").length > 10 ? "items-start" : "items-center"}`}
|
|
419
408
|
>
|
|
420
|
-
<
|
|
421
|
-
|
|
422
|
-
|
|
409
|
+
<div className={isLongOfferText ? "mt-[2px]" : ""}>
|
|
410
|
+
<LottiePlayer
|
|
411
|
+
animationData={serviceItem.icons.promoAnim}
|
|
412
|
+
width="14px"
|
|
413
|
+
height="14px"
|
|
414
|
+
/>
|
|
415
|
+
</div>
|
|
416
|
+
<div
|
|
417
|
+
className={`ml-[4px] flex-1 outline-none ${isLongOfferText ? "mt-[2px]" : ""}`}
|
|
418
|
+
style={{
|
|
419
|
+
color: "#fff",
|
|
420
|
+
lineHeight: 1.4,
|
|
421
|
+
}}
|
|
422
|
+
>
|
|
423
|
+
<span className="whitespace-nowrap min-[380px]:text-[12px]">
|
|
424
|
+
{serviceItem?.offer_text}
|
|
425
|
+
</span>
|
|
426
|
+
</div>
|
|
423
427
|
</div>
|
|
424
428
|
</div>
|
|
425
429
|
</div>
|
|
426
430
|
</div>
|
|
427
|
-
|
|
428
|
-
)}
|
|
431
|
+
)}
|
|
429
432
|
|
|
430
433
|
{/* 🔹 EXPANDABLE DROPDOWN (below the card) */}
|
|
431
434
|
{((serviceItem?.offer_text && isNewUiEnabled) ||
|
|
@@ -63,7 +63,7 @@ const SurveyDesktop = ({
|
|
|
63
63
|
|
|
64
64
|
{/* Centered Illustration */}
|
|
65
65
|
{icons?.surveyIcon && (
|
|
66
|
-
<div className="flex justify-center mb-
|
|
66
|
+
<div className="flex justify-center mb-2 mt-2">
|
|
67
67
|
<img
|
|
68
68
|
src={icons.surveyIcon}
|
|
69
69
|
alt="Survey Illustration"
|
|
@@ -73,7 +73,7 @@ const SurveyDesktop = ({
|
|
|
73
73
|
)}
|
|
74
74
|
|
|
75
75
|
{/* Centered Title */}
|
|
76
|
-
<h2 className="text-[18px] bold-text leading-[1.25] text-center
|
|
76
|
+
<h2 className="text-[18px] bold-text leading-[1.25] text-center mb-2">
|
|
77
77
|
Ayúdanos a mejorar
|
|
78
78
|
</h2>
|
|
79
79
|
|
|
@@ -66,7 +66,7 @@ const SurveyMobile = ({
|
|
|
66
66
|
|
|
67
67
|
{/* Centered Illustration */}
|
|
68
68
|
{icons?.surveyIcon && (
|
|
69
|
-
<div className="flex justify-center mb-
|
|
69
|
+
<div className="flex justify-center mb-2 mt-2">
|
|
70
70
|
<img
|
|
71
71
|
src={icons.surveyIcon}
|
|
72
72
|
alt="Survey Illustration"
|
|
@@ -76,12 +76,12 @@ const SurveyMobile = ({
|
|
|
76
76
|
)}
|
|
77
77
|
|
|
78
78
|
{/* Centered Title */}
|
|
79
|
-
<h2 className="text-[18px] bold-text leading-[1.25] text-center
|
|
79
|
+
<h2 className="text-[18px] bold-text leading-[1.25] text-center mb-2">
|
|
80
80
|
Ayúdanos a mejorar
|
|
81
81
|
</h2>
|
|
82
82
|
|
|
83
83
|
{/* Centered Subtitle */}
|
|
84
|
-
<p className="text-[13.33px] text-center leading-[1.4] mb-
|
|
84
|
+
<p className="text-[13.33px] text-center leading-[1.4] mb-8 max-w-[460px] mx-auto">
|
|
85
85
|
Basándote en tu experiencia de compra.
|
|
86
86
|
<br />
|
|
87
87
|
¿Nos recomendarías a un amigo?
|
|
@@ -104,8 +104,8 @@ const SurveyMobile = ({
|
|
|
104
104
|
onFeedbackChange={onFeedbackChange}
|
|
105
105
|
/>
|
|
106
106
|
|
|
107
|
-
<div className="flex justify-center mt-[
|
|
108
|
-
<div className="w-[
|
|
107
|
+
<div className="flex justify-center mt-[50px] mb-[50px]">
|
|
108
|
+
<div className="w-[100px]">
|
|
109
109
|
<KuposButton
|
|
110
110
|
isSoldOut={selectedScore == null}
|
|
111
111
|
isLoading={isLoading || false}
|
package/src/ui/OfferBanner.tsx
CHANGED
|
@@ -3,31 +3,201 @@ import LottiePlayer from "../assets/LottiePlayer";
|
|
|
3
3
|
import CommonService from "../utils/CommonService";
|
|
4
4
|
import { ServiceItemProps } from "../components/ServiceItem/types";
|
|
5
5
|
|
|
6
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
type ServiceItemSlice = Pick<
|
|
9
|
+
ServiceItemProps["serviceItem"],
|
|
10
|
+
| "is_dp_enabled"
|
|
11
|
+
| "offer_text"
|
|
12
|
+
| "dp_discount_percents"
|
|
13
|
+
| "dp_discounted_seats"
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
interface OfferBannerColors {
|
|
17
|
+
bottomStripColor?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
6
20
|
interface OfferBannerProps {
|
|
7
21
|
offerGradient: string;
|
|
8
22
|
isSoldOut: boolean;
|
|
9
|
-
serviceItem:
|
|
10
|
-
ServiceItemProps["serviceItem"],
|
|
11
|
-
| "is_dp_enabled"
|
|
12
|
-
| "offer_text"
|
|
13
|
-
| "dp_discount_percents"
|
|
14
|
-
| "dp_discounted_seats"
|
|
15
|
-
>;
|
|
23
|
+
serviceItem: ServiceItemSlice;
|
|
16
24
|
renderIcon: (name: string, size: string) => React.ReactNode;
|
|
17
|
-
isLoggedIn:
|
|
18
|
-
showLoginModal:
|
|
25
|
+
isLoggedIn: boolean;
|
|
26
|
+
showLoginModal: () => void;
|
|
19
27
|
viewersConfig: ServiceItemProps["viewersConfig"];
|
|
20
|
-
getAnimationIcon: (name: string) =>
|
|
28
|
+
getAnimationIcon: (name: string) => unknown;
|
|
21
29
|
showLoginOption?: boolean;
|
|
22
30
|
isNewUiEnabled?: boolean;
|
|
23
|
-
colors:
|
|
31
|
+
colors: OfferBannerColors;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
35
|
+
|
|
36
|
+
const OFFER_TEXT_MAX_LENGTH = 30;
|
|
37
|
+
|
|
38
|
+
function truncateOfferText(text: string): string {
|
|
39
|
+
return text.length > OFFER_TEXT_MAX_LENGTH
|
|
40
|
+
? `${text.slice(0, OFFER_TEXT_MAX_LENGTH)}...`
|
|
41
|
+
: text;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function hasDpDiscounts(serviceItem: ServiceItemSlice): boolean {
|
|
45
|
+
return (
|
|
46
|
+
Object.keys(serviceItem?.dp_discount_percents ?? {}).length > 0 ||
|
|
47
|
+
(serviceItem?.dp_discounted_seats ?? []).length > 0
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ─── Sub-components ───────────────────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
interface AnimationIconProps {
|
|
54
|
+
getAnimationIcon: OfferBannerProps["getAnimationIcon"];
|
|
55
|
+
name: string;
|
|
56
|
+
width?: string;
|
|
57
|
+
height?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const AnimationIcon: React.FC<AnimationIconProps> = ({
|
|
61
|
+
getAnimationIcon,
|
|
62
|
+
name,
|
|
63
|
+
width = "18px",
|
|
64
|
+
height = "18px",
|
|
65
|
+
}) => (
|
|
66
|
+
<LottiePlayer
|
|
67
|
+
animationData={getAnimationIcon(name)}
|
|
68
|
+
width={width}
|
|
69
|
+
height={height}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
// Shown when DP is enabled but no discounts / discounted seats are present
|
|
74
|
+
const PopularServiceBanner: React.FC<{
|
|
75
|
+
getAnimationIcon: OfferBannerProps["getAnimationIcon"];
|
|
76
|
+
}> = ({ getAnimationIcon }) => (
|
|
77
|
+
<div className="flex items-center gap-[5px]">
|
|
78
|
+
<AnimationIcon getAnimationIcon={getAnimationIcon} name="starAnimation" />
|
|
79
|
+
<span>Servicio popular entre los usuarios</span>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// Shown when the new UI is enabled and an offer text exists
|
|
84
|
+
interface NewUiOfferBannerProps {
|
|
85
|
+
offerText: string;
|
|
86
|
+
isLoggedIn: boolean;
|
|
87
|
+
showLoginModal: () => void;
|
|
88
|
+
showLoginOption?: boolean;
|
|
89
|
+
getAnimationIcon: OfferBannerProps["getAnimationIcon"];
|
|
90
|
+
hideRegister?: boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const NewUiOfferBanner: React.FC<NewUiOfferBannerProps> = ({
|
|
94
|
+
offerText,
|
|
95
|
+
isLoggedIn,
|
|
96
|
+
showLoginModal,
|
|
97
|
+
showLoginOption,
|
|
98
|
+
getAnimationIcon,
|
|
99
|
+
hideRegister,
|
|
100
|
+
}) => (
|
|
101
|
+
<div className="flex items-center">
|
|
102
|
+
<AnimationIcon getAnimationIcon={getAnimationIcon} name="bombAnimation" />
|
|
103
|
+
<div className="flex items-center mt-[2px]">
|
|
104
|
+
<span
|
|
105
|
+
className="bold-text"
|
|
106
|
+
style={{ marginLeft: offerText ? "6px" : "3px" }}
|
|
107
|
+
>
|
|
108
|
+
{truncateOfferText(offerText)}{" "}
|
|
109
|
+
{!hideRegister && (isLoggedIn && showLoginOption ? null : (
|
|
110
|
+
<span onClick={showLoginModal} className="cursor-pointer">
|
|
111
|
+
- registro
|
|
112
|
+
</span>
|
|
113
|
+
))}{" "}
|
|
114
|
+
|
|
115
|
+
</span>{" "}
|
|
116
|
+
{offerText ? "|" : ""}
|
|
117
|
+
Termina en
|
|
118
|
+
<span
|
|
119
|
+
className="bold-text text-end"
|
|
120
|
+
ref={(node) => CommonService.startCountdown(node, 599)}
|
|
121
|
+
style={{ fontVariantNumeric: "tabular-nums", display: "inline-block" }}
|
|
122
|
+
/>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// Shown for legacy (non-new-UI) promo offers
|
|
128
|
+
interface LegacyOfferBannerProps {
|
|
129
|
+
offerText: string;
|
|
130
|
+
getAnimationIcon: OfferBannerProps["getAnimationIcon"];
|
|
24
131
|
}
|
|
25
132
|
|
|
133
|
+
const LegacyOfferBanner: React.FC<LegacyOfferBannerProps> = ({
|
|
134
|
+
offerText,
|
|
135
|
+
getAnimationIcon,
|
|
136
|
+
}) => (
|
|
137
|
+
<div className="flex items-center">
|
|
138
|
+
<AnimationIcon getAnimationIcon={getAnimationIcon} name="promoAnim" />
|
|
139
|
+
<div className="flex items-center mt-[2px]">
|
|
140
|
+
<span
|
|
141
|
+
className="bold-text"
|
|
142
|
+
style={{ marginLeft: offerText ? "6px" : "3px" }}
|
|
143
|
+
>
|
|
144
|
+
{offerText}
|
|
145
|
+
</span>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Right-side viewers / buying count
|
|
151
|
+
interface ViewersCountProps {
|
|
152
|
+
serviceItem: ServiceItemSlice;
|
|
153
|
+
viewersConfig: ServiceItemProps["viewersConfig"];
|
|
154
|
+
getAnimationIcon: OfferBannerProps["getAnimationIcon"];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const ViewersCount: React.FC<ViewersCountProps> = ({
|
|
158
|
+
serviceItem,
|
|
159
|
+
viewersConfig,
|
|
160
|
+
getAnimationIcon,
|
|
161
|
+
}) => {
|
|
162
|
+
const showScarcity = hasDpDiscounts(serviceItem);
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<div className="flex items-center">
|
|
166
|
+
<AnimationIcon
|
|
167
|
+
getAnimationIcon={getAnimationIcon}
|
|
168
|
+
name="dotAnimation"
|
|
169
|
+
width="12px"
|
|
170
|
+
height="12px"
|
|
171
|
+
/>
|
|
172
|
+
<span className="ml-[6px]">
|
|
173
|
+
<span
|
|
174
|
+
className="bold-text"
|
|
175
|
+
ref={(node) => CommonService.startViewerCount(node, viewersConfig)}
|
|
176
|
+
style={{ fontVariantNumeric: "tabular-nums" }}
|
|
177
|
+
/>{" "}
|
|
178
|
+
<span>
|
|
179
|
+
{viewersConfig?.label || " viendo"} |{" "}
|
|
180
|
+
<span>
|
|
181
|
+
{showScarcity && "Quedan pocos • "}
|
|
182
|
+
<span
|
|
183
|
+
className="bold-text"
|
|
184
|
+
ref={(node) => CommonService.startComprandoCount(node, 4, 16)}
|
|
185
|
+
style={{ fontVariantNumeric: "tabular-nums" }}
|
|
186
|
+
/>{" "}
|
|
187
|
+
comprando
|
|
188
|
+
</span>
|
|
189
|
+
</span>
|
|
190
|
+
</span>
|
|
191
|
+
</div>
|
|
192
|
+
);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
// ─── Main Component ───────────────────────────────────────────────────────────
|
|
196
|
+
|
|
26
197
|
const OfferBanner: React.FC<OfferBannerProps> = ({
|
|
27
198
|
offerGradient,
|
|
28
199
|
isSoldOut,
|
|
29
200
|
serviceItem,
|
|
30
|
-
renderIcon,
|
|
31
201
|
isLoggedIn,
|
|
32
202
|
showLoginModal,
|
|
33
203
|
viewersConfig,
|
|
@@ -36,132 +206,59 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
|
|
|
36
206
|
isNewUiEnabled,
|
|
37
207
|
colors,
|
|
38
208
|
}) => {
|
|
209
|
+
const isLegacyOffer =
|
|
210
|
+
!!serviceItem?.offer_text && !isNewUiEnabled && !serviceItem?.is_dp_enabled;
|
|
211
|
+
|
|
212
|
+
const isDpEnabledWithoutDiscounts =
|
|
213
|
+
serviceItem?.is_dp_enabled && !hasDpDiscounts(serviceItem);
|
|
214
|
+
|
|
215
|
+
const showViewers = isNewUiEnabled || serviceItem?.is_dp_enabled;
|
|
216
|
+
|
|
217
|
+
const background = isLegacyOffer ? colors?.bottomStripColor : offerGradient;
|
|
218
|
+
|
|
219
|
+
const renderLeftContent = () => {
|
|
220
|
+
if (isDpEnabledWithoutDiscounts) {
|
|
221
|
+
return <PopularServiceBanner getAnimationIcon={getAnimationIcon} />;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const hasDp = hasDpDiscounts(serviceItem);
|
|
225
|
+
|
|
226
|
+
if (hasDp || (isNewUiEnabled && serviceItem?.offer_text)) {
|
|
227
|
+
return (
|
|
228
|
+
<NewUiOfferBanner
|
|
229
|
+
offerText={serviceItem.offer_text || ""}
|
|
230
|
+
isLoggedIn={isLoggedIn}
|
|
231
|
+
showLoginModal={showLoginModal}
|
|
232
|
+
showLoginOption={showLoginOption}
|
|
233
|
+
getAnimationIcon={getAnimationIcon}
|
|
234
|
+
hideRegister={hasDp}
|
|
235
|
+
/>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
if (isLegacyOffer) {
|
|
239
|
+
return (
|
|
240
|
+
<LegacyOfferBanner
|
|
241
|
+
offerText={serviceItem.offer_text!}
|
|
242
|
+
getAnimationIcon={getAnimationIcon}
|
|
243
|
+
/>
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
};
|
|
248
|
+
|
|
39
249
|
return (
|
|
40
250
|
<div
|
|
41
|
-
className="text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[44px] pt-[50px]
|
|
42
|
-
style={{
|
|
43
|
-
background:
|
|
44
|
-
serviceItem?.offer_text && !isNewUiEnabled
|
|
45
|
-
? colors?.bottomStripColor
|
|
46
|
-
: offerGradient,
|
|
47
|
-
opacity: isSoldOut ? 0.5 : 1,
|
|
48
|
-
// zIndex: 0,
|
|
49
|
-
}}
|
|
251
|
+
className="text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[44px] pt-[50px] rounded-b-[14px] text-[14px] mt-[10px]"
|
|
252
|
+
style={{ background, opacity: isSoldOut ? 0.5 : 1 }}
|
|
50
253
|
>
|
|
51
|
-
<div className="flex
|
|
52
|
-
<div className="flex items-center
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
animationData={getAnimationIcon("starAnimation")}
|
|
60
|
-
width="18px"
|
|
61
|
-
height="18px"
|
|
62
|
-
/>
|
|
63
|
-
{/* starAnimation */}
|
|
64
|
-
<span>Servicio popular entre los usuarios</span>
|
|
65
|
-
</div>
|
|
66
|
-
) : isNewUiEnabled && serviceItem?.offer_text ? (
|
|
67
|
-
<div className="flex items-center">
|
|
68
|
-
<LottiePlayer
|
|
69
|
-
animationData={getAnimationIcon("bombAnimation")}
|
|
70
|
-
width="18px"
|
|
71
|
-
height="18px"
|
|
72
|
-
/>
|
|
73
|
-
<div className="flex items-center mt-[2px]">
|
|
74
|
-
<span
|
|
75
|
-
className="bold-text"
|
|
76
|
-
style={{
|
|
77
|
-
marginLeft: serviceItem?.offer_text ? "6px" : "3px",
|
|
78
|
-
}}
|
|
79
|
-
>
|
|
80
|
-
{(serviceItem?.offer_text || "").length > 30
|
|
81
|
-
? (serviceItem?.offer_text || "").slice(0, 30) + "..."
|
|
82
|
-
: serviceItem?.offer_text || ""}{" "}
|
|
83
|
-
{isLoggedIn && showLoginOption ? null : (
|
|
84
|
-
<span onClick={showLoginModal} className="cursor-pointer">
|
|
85
|
-
- registro
|
|
86
|
-
</span>
|
|
87
|
-
)}{" "}
|
|
88
|
-
|
|
89
|
-
</span>{" "}
|
|
90
|
-
{serviceItem?.offer_text ? "|" : ""}
|
|
91
|
-
Termina en
|
|
92
|
-
<span
|
|
93
|
-
className="bold-text text-end"
|
|
94
|
-
ref={(node) => CommonService.startCountdown(node, 599)}
|
|
95
|
-
style={{
|
|
96
|
-
fontVariantNumeric: "tabular-nums",
|
|
97
|
-
display: "inline-block",
|
|
98
|
-
}}
|
|
99
|
-
/>
|
|
100
|
-
</div>
|
|
101
|
-
</div>
|
|
102
|
-
) : (
|
|
103
|
-
serviceItem?.offer_text &&
|
|
104
|
-
!isNewUiEnabled && (
|
|
105
|
-
<div className="flex items-center">
|
|
106
|
-
<LottiePlayer
|
|
107
|
-
animationData={getAnimationIcon("promoAnim")}
|
|
108
|
-
width="18px"
|
|
109
|
-
height="18px"
|
|
110
|
-
/>
|
|
111
|
-
<div className="flex items-center mt-[2px]">
|
|
112
|
-
<span
|
|
113
|
-
className="bold-text"
|
|
114
|
-
style={{
|
|
115
|
-
marginLeft: serviceItem?.offer_text ? "6px" : "3px",
|
|
116
|
-
}}
|
|
117
|
-
>
|
|
118
|
-
{serviceItem?.offer_text || ""}
|
|
119
|
-
</span>{" "}
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
)
|
|
123
|
-
)}
|
|
124
|
-
</div>
|
|
125
|
-
{(isNewUiEnabled || serviceItem?.is_dp_enabled) && (
|
|
126
|
-
<div className="flex items-center">
|
|
127
|
-
{/* {renderIcon("personIcon", "16px")} */}
|
|
128
|
-
<LottiePlayer
|
|
129
|
-
animationData={getAnimationIcon("dotAnimation")}
|
|
130
|
-
width="12px"
|
|
131
|
-
height="12px"
|
|
132
|
-
/>
|
|
133
|
-
|
|
134
|
-
<span className="ml-[6px]">
|
|
135
|
-
<span
|
|
136
|
-
className="bold-text"
|
|
137
|
-
ref={(node) =>
|
|
138
|
-
CommonService.startViewerCount(node, viewersConfig)
|
|
139
|
-
}
|
|
140
|
-
style={{ fontVariantNumeric: "tabular-nums" }}
|
|
141
|
-
/>{" "}
|
|
142
|
-
{/* <span className="bold-text">personas</span>{" "} */}
|
|
143
|
-
<span>
|
|
144
|
-
{" "}
|
|
145
|
-
{viewersConfig?.label || " viendo"} |{" "}
|
|
146
|
-
<span className="">
|
|
147
|
-
{serviceItem?.is_dp_enabled &&
|
|
148
|
-
Object.keys(serviceItem?.dp_discount_percents ?? {})
|
|
149
|
-
.length === 0 &&
|
|
150
|
-
(serviceItem?.dp_discounted_seats ?? []).length === 0
|
|
151
|
-
? null
|
|
152
|
-
: "Quedan pocos • "}
|
|
153
|
-
<span
|
|
154
|
-
className="bold-text"
|
|
155
|
-
ref={(node) =>
|
|
156
|
-
CommonService.startComprandoCount(node, 4, 16)
|
|
157
|
-
}
|
|
158
|
-
style={{ fontVariantNumeric: "tabular-nums" }}
|
|
159
|
-
/>{" "}
|
|
160
|
-
comprando
|
|
161
|
-
</span>
|
|
162
|
-
</span>
|
|
163
|
-
</span>
|
|
164
|
-
</div>
|
|
254
|
+
<div className="flex justify-between items-center w-full">
|
|
255
|
+
<div className="flex items-center">{renderLeftContent()}</div>
|
|
256
|
+
{showViewers && (
|
|
257
|
+
<ViewersCount
|
|
258
|
+
serviceItem={serviceItem}
|
|
259
|
+
viewersConfig={viewersConfig}
|
|
260
|
+
getAnimationIcon={getAnimationIcon}
|
|
261
|
+
/>
|
|
165
262
|
)}
|
|
166
263
|
</div>
|
|
167
264
|
</div>
|