kupos-ui-components-lib 10.4.72 → 10.4.74
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/DiscountBanners/DiscountBannerDesktop.js +0 -1
- package/dist/ui/DiscountBanners/discountUtils.js +18 -4
- package/dist/ui/FeaturServiceUiMobile/FeatureServiceUiMobile.js +6 -24
- package/dist/ui/FeatureServiceUI/FeatureServiceUi.js +4 -4
- package/package.json +1 -1
- package/src/components/DiscountBanners/DiscountBannerDesktop.tsx +0 -1
- package/src/ui/DiscountBanners/discountUtils.ts +18 -4
- package/src/ui/FeaturServiceUiMobile/FeatureServiceUiMobile.tsx +9 -28
- package/src/ui/FeatureServiceUI/FeatureServiceUi.tsx +6 -4
|
@@ -147,7 +147,6 @@ class DiscountBannersDesktop extends React.Component {
|
|
|
147
147
|
}
|
|
148
148
|
render() {
|
|
149
149
|
const { services = [], wowDealData, backgroundImages = [], artIncludesChipPill, accentColors = [], label = DEFAULT_LABEL, currencySign = "$", size = "default", selectedKey, className = "", style, } = this.props;
|
|
150
|
-
console.log("🚀 ~ DiscountBannersDesktop ~ render ~ services:", services);
|
|
151
150
|
// Compute cards directly — no useMemo
|
|
152
151
|
const cards = deriveDiscountCards(services, wowDealData, currencySign);
|
|
153
152
|
if (!cards.length)
|
|
@@ -107,6 +107,18 @@ function addOperatorLogo(card, service) {
|
|
|
107
107
|
{ url, name: service.operator_name || ((_f = service.operator_details) === null || _f === void 0 ? void 0 : _f[2]) },
|
|
108
108
|
];
|
|
109
109
|
}
|
|
110
|
+
// savings_percent may be missing or sent as a string; fall back to the deal's prices so
|
|
111
|
+
// Remate still sorts by its real discount instead of dropping to 0%
|
|
112
|
+
function getWowDealPercent(wowDealData) {
|
|
113
|
+
const savings = Number(wowDealData.savings_percent);
|
|
114
|
+
if (savings > 0)
|
|
115
|
+
return savings;
|
|
116
|
+
const original = Number(wowDealData.original_price);
|
|
117
|
+
const final = Number(wowDealData.final_price);
|
|
118
|
+
return original > 0 && final >= 0 && final < original
|
|
119
|
+
? ((original - final) / original) * 100
|
|
120
|
+
: 0;
|
|
121
|
+
}
|
|
110
122
|
function toDiscountLabel(discount, currencySign) {
|
|
111
123
|
if (discount.type === "fixed") {
|
|
112
124
|
return `${CommonService.currencyRounded(discount.amount, currencySign)} de dcto`;
|
|
@@ -118,13 +130,14 @@ export function deriveDiscountCards(services = [], wowDealData, currencySign = "
|
|
|
118
130
|
var _a, _b, _c, _d, _e;
|
|
119
131
|
const cards = new Map();
|
|
120
132
|
const wowServices = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.services;
|
|
133
|
+
const wowDealPercent = wowDealData ? getWowDealPercent(wowDealData) : 0;
|
|
121
134
|
const hasWowDeal = !!wowDealData &&
|
|
122
135
|
((Array.isArray(wowServices) && wowServices.length > 0) ||
|
|
123
|
-
|
|
136
|
+
wowDealPercent > 0);
|
|
124
137
|
if (hasWowDeal) {
|
|
125
138
|
const remateDiscount = {
|
|
126
139
|
type: "percentage",
|
|
127
|
-
amount: Math.round(
|
|
140
|
+
amount: Math.round(wowDealPercent),
|
|
128
141
|
};
|
|
129
142
|
cards.set(REMATE_KEY, {
|
|
130
143
|
key: REMATE_KEY,
|
|
@@ -217,8 +230,9 @@ export function deriveDiscountCards(services = [], wowDealData, currencySign = "
|
|
|
217
230
|
return a.name.localeCompare(b.name, "es", { sensitivity: "base" });
|
|
218
231
|
});
|
|
219
232
|
}
|
|
220
|
-
// Highest discount first
|
|
221
|
-
//
|
|
233
|
+
// Highest discount first, Remate included — it takes its place by its percent rather than
|
|
234
|
+
// always leading. Percentages and fixed amounts can't be compared, so percentages lead.
|
|
235
|
+
// The sort is stable, so on a tie Remate stays ahead and the rest keep service order.
|
|
222
236
|
return Array.from(cards.values()).sort((a, b) => {
|
|
223
237
|
if (a.discountType !== b.discountType) {
|
|
224
238
|
return a.discountType === "percentage" ? -1 : 1;
|
|
@@ -91,31 +91,13 @@ const FeatureServiceUiMobile = ({ serviceItem, showTopLabel, colors, isSoldOut,
|
|
|
91
91
|
selectedSlotService.original_price) *
|
|
92
92
|
100)
|
|
93
93
|
: savingsPercent;
|
|
94
|
-
//
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return time;
|
|
99
|
-
let h = parseInt(match[1], 10);
|
|
100
|
-
const m = match[2];
|
|
101
|
-
const period = h >= 12 ? "PM" : "AM";
|
|
102
|
-
h = h % 12 || 12;
|
|
103
|
-
return `${h}:${m} ${period}`;
|
|
104
|
-
};
|
|
105
|
-
// Convert all HH:MM occurrences in a label string to AM/PM
|
|
106
|
-
const formatLabelAmPm = (label) => label.replace(/(\d{1,2}):(\d{2})/g, (_, hh, mm) => {
|
|
107
|
-
let h = parseInt(hh, 10);
|
|
108
|
-
const period = h >= 12 ? "PM" : "AM";
|
|
109
|
-
h = h % 12 || 12;
|
|
110
|
-
return `${h}:${mm} ${period}`;
|
|
111
|
-
});
|
|
112
|
-
// The label shown on the dropdown button
|
|
113
|
-
const departureRange = formatLabelAmPm((activeSlot === null || activeSlot === void 0 ? void 0 : activeSlot.label) || `Entre ${dealWindowFrom} y ${dealWindowTo}`);
|
|
114
|
-
const currentWindowFrom = (activeSlot === null || activeSlot === void 0 ? void 0 : activeSlot.label)
|
|
115
|
-
? activeSlot.label.split(" - ")[0]
|
|
94
|
+
// The label shown on the dropdown button (24h format, e.g. "Entre 16:00 y 20:00")
|
|
95
|
+
const departureRange = (activeSlot === null || activeSlot === void 0 ? void 0 : activeSlot.label) || `Entre ${dealWindowFrom} y ${dealWindowTo}`;
|
|
96
|
+
const currentWindowFrom = activeSlot
|
|
97
|
+
? commonService.minutesToTime(activeSlot.start)
|
|
116
98
|
: dealWindowFrom;
|
|
117
|
-
const currentWindowTo =
|
|
118
|
-
? activeSlot.
|
|
99
|
+
const currentWindowTo = activeSlot
|
|
100
|
+
? commonService.minutesToTime(activeSlot.end === 1440 ? 1439 : activeSlot.end)
|
|
119
101
|
: dealWindowTo;
|
|
120
102
|
const isItemExpanded = serviceItem.id === isFeatureDropDownExpand ||
|
|
121
103
|
isFeatureDropDownExpand === true;
|
|
@@ -105,11 +105,11 @@ const FeatureServiceUi = ({ serviceItem, showTopLabel, getAnimationIcon, cityOri
|
|
|
105
105
|
// The label shown on the dropdown button
|
|
106
106
|
const departureRange = (activeSlot === null || activeSlot === void 0 ? void 0 : activeSlot.label) || `${dealWindowFrom} y ${dealWindowTo}`;
|
|
107
107
|
// activeSlot?.label || `Entre ${dealWindowFrom} y ${dealWindowTo}`;
|
|
108
|
-
const currentWindowFrom =
|
|
109
|
-
? activeSlot.
|
|
108
|
+
const currentWindowFrom = activeSlot
|
|
109
|
+
? commonService.minutesToTime(activeSlot.start)
|
|
110
110
|
: dealWindowFrom;
|
|
111
|
-
const currentWindowTo =
|
|
112
|
-
? activeSlot.
|
|
111
|
+
const currentWindowTo = activeSlot
|
|
112
|
+
? commonService.minutesToTime(activeSlot.end === 1440 ? 1439 : activeSlot.end)
|
|
113
113
|
: dealWindowTo;
|
|
114
114
|
if (expandedStateMap[serviceItem.id] === undefined) {
|
|
115
115
|
expandedStateMap[serviceItem.id] = true;
|
package/package.json
CHANGED
|
@@ -197,7 +197,6 @@ class DiscountBannersDesktop extends React.Component<
|
|
|
197
197
|
className = "",
|
|
198
198
|
style,
|
|
199
199
|
} = this.props;
|
|
200
|
-
console.log("🚀 ~ DiscountBannersDesktop ~ render ~ services:", services)
|
|
201
200
|
|
|
202
201
|
// Compute cards directly — no useMemo
|
|
203
202
|
const cards = deriveDiscountCards(services, wowDealData, currencySign);
|
|
@@ -148,6 +148,18 @@ function addOperatorLogo(
|
|
|
148
148
|
];
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
// savings_percent may be missing or sent as a string; fall back to the deal's prices so
|
|
152
|
+
// Remate still sorts by its real discount instead of dropping to 0%
|
|
153
|
+
function getWowDealPercent(wowDealData: WowDealData): number {
|
|
154
|
+
const savings = Number(wowDealData.savings_percent);
|
|
155
|
+
if (savings > 0) return savings;
|
|
156
|
+
const original = Number(wowDealData.original_price);
|
|
157
|
+
const final = Number(wowDealData.final_price);
|
|
158
|
+
return original > 0 && final >= 0 && final < original
|
|
159
|
+
? ((original - final) / original) * 100
|
|
160
|
+
: 0;
|
|
161
|
+
}
|
|
162
|
+
|
|
151
163
|
function toDiscountLabel(
|
|
152
164
|
discount: ServiceDiscount,
|
|
153
165
|
currencySign: string,
|
|
@@ -167,15 +179,16 @@ export function deriveDiscountCards(
|
|
|
167
179
|
const cards = new Map<string, DiscountBannerCard>();
|
|
168
180
|
|
|
169
181
|
const wowServices = wowDealData?.services;
|
|
182
|
+
const wowDealPercent = wowDealData ? getWowDealPercent(wowDealData) : 0;
|
|
170
183
|
const hasWowDeal =
|
|
171
184
|
!!wowDealData &&
|
|
172
185
|
((Array.isArray(wowServices) && wowServices.length > 0) ||
|
|
173
|
-
|
|
186
|
+
wowDealPercent > 0);
|
|
174
187
|
|
|
175
188
|
if (hasWowDeal) {
|
|
176
189
|
const remateDiscount: ServiceDiscount = {
|
|
177
190
|
type: "percentage",
|
|
178
|
-
amount: Math.round(
|
|
191
|
+
amount: Math.round(wowDealPercent),
|
|
179
192
|
};
|
|
180
193
|
cards.set(REMATE_KEY, {
|
|
181
194
|
key: REMATE_KEY,
|
|
@@ -276,8 +289,9 @@ export function deriveDiscountCards(
|
|
|
276
289
|
});
|
|
277
290
|
}
|
|
278
291
|
|
|
279
|
-
// Highest discount first
|
|
280
|
-
//
|
|
292
|
+
// Highest discount first, Remate included — it takes its place by its percent rather than
|
|
293
|
+
// always leading. Percentages and fixed amounts can't be compared, so percentages lead.
|
|
294
|
+
// The sort is stable, so on a tie Remate stays ahead and the rest keep service order.
|
|
281
295
|
return Array.from(cards.values()).sort((a, b) => {
|
|
282
296
|
if (a.discountType !== b.discountType) {
|
|
283
297
|
return a.discountType === "percentage" ? -1 : 1;
|
|
@@ -131,36 +131,17 @@ const FeatureServiceUiMobile = ({
|
|
|
131
131
|
)
|
|
132
132
|
: savingsPercent;
|
|
133
133
|
|
|
134
|
-
//
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
if (!match) return time;
|
|
138
|
-
let h = parseInt(match[1], 10);
|
|
139
|
-
const m = match[2];
|
|
140
|
-
const period = h >= 12 ? "PM" : "AM";
|
|
141
|
-
h = h % 12 || 12;
|
|
142
|
-
return `${h}:${m} ${period}`;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
// Convert all HH:MM occurrences in a label string to AM/PM
|
|
146
|
-
const formatLabelAmPm = (label: string): string =>
|
|
147
|
-
label.replace(/(\d{1,2}):(\d{2})/g, (_, hh, mm) => {
|
|
148
|
-
let h = parseInt(hh, 10);
|
|
149
|
-
const period = h >= 12 ? "PM" : "AM";
|
|
150
|
-
h = h % 12 || 12;
|
|
151
|
-
return `${h}:${mm} ${period}`;
|
|
152
|
-
});
|
|
134
|
+
// The label shown on the dropdown button (24h format, e.g. "Entre 16:00 y 20:00")
|
|
135
|
+
const departureRange =
|
|
136
|
+
activeSlot?.label || `Entre ${dealWindowFrom} y ${dealWindowTo}`;
|
|
153
137
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
activeSlot?.label || `Entre ${dealWindowFrom} y ${dealWindowTo}`,
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
const currentWindowFrom = activeSlot?.label
|
|
160
|
-
? activeSlot.label.split(" - ")[0]
|
|
138
|
+
const currentWindowFrom = activeSlot
|
|
139
|
+
? commonService.minutesToTime(activeSlot.start)
|
|
161
140
|
: dealWindowFrom;
|
|
162
|
-
const currentWindowTo = activeSlot
|
|
163
|
-
?
|
|
141
|
+
const currentWindowTo = activeSlot
|
|
142
|
+
? commonService.minutesToTime(
|
|
143
|
+
activeSlot.end === 1440 ? 1439 : activeSlot.end,
|
|
144
|
+
)
|
|
164
145
|
: dealWindowTo;
|
|
165
146
|
|
|
166
147
|
const isItemExpanded =
|
|
@@ -147,11 +147,13 @@ const FeatureServiceUi = ({
|
|
|
147
147
|
activeSlot?.label || `${dealWindowFrom} y ${dealWindowTo}`;
|
|
148
148
|
// activeSlot?.label || `Entre ${dealWindowFrom} y ${dealWindowTo}`;
|
|
149
149
|
|
|
150
|
-
const currentWindowFrom = activeSlot
|
|
151
|
-
? activeSlot.
|
|
150
|
+
const currentWindowFrom = activeSlot
|
|
151
|
+
? commonService.minutesToTime(activeSlot.start)
|
|
152
152
|
: dealWindowFrom;
|
|
153
|
-
const currentWindowTo = activeSlot
|
|
154
|
-
?
|
|
153
|
+
const currentWindowTo = activeSlot
|
|
154
|
+
? commonService.minutesToTime(
|
|
155
|
+
activeSlot.end === 1440 ? 1439 : activeSlot.end,
|
|
156
|
+
)
|
|
155
157
|
: dealWindowTo;
|
|
156
158
|
|
|
157
159
|
if (expandedStateMap[serviceItem.id] === undefined) {
|