kupos-ui-components-lib 9.11.1 → 9.11.2

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.
@@ -130,6 +130,24 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
130
130
  : serviceItem.seat_types || [];
131
131
  const discountedSeats = seats.map((seat) => (Object.assign(Object.assign({}, seat), CommonService.calculateDiscountedPrice(seat.fare, serviceItem))));
132
132
  const hasDiscount = discountedSeats.some((seat) => seat.originalPrice !== seat.discountedPrice);
133
+ // Mirror the same check as SeatSection: hide badge (and its top margin) when
134
+ // both percentage and max_discount exist and the cap is being applied.
135
+ const isMaxDiscountApplied = (() => {
136
+ const { discount_type, discount_value, max_discount } = serviceItem;
137
+ if (discount_type === "percentage" &&
138
+ typeof discount_value === "number" &&
139
+ max_discount != null &&
140
+ max_discount > 0) {
141
+ const lowestFare = discountedSeats
142
+ .map((s) => s.originalPrice)
143
+ .filter((p) => p > 0)
144
+ .sort((a, b) => a - b)[0];
145
+ if (lowestFare != null) {
146
+ return (lowestFare * discount_value) / 100 > max_discount;
147
+ }
148
+ }
149
+ return false;
150
+ })();
133
151
  const dpDiscountEntry = Object.entries((serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.dp_discount_percents) || {})[0];
134
152
  const dpDiscountPercent = dpDiscountEntry === null || dpDiscountEntry === void 0 ? void 0 : dpDiscountEntry[1];
135
153
  const hasDpEnabled = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_dp_enabled) === true;
@@ -277,7 +295,8 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
277
295
  : coachKey
278
296
  ? "20px 15px 20px 15px"
279
297
  : "20px 15px 10px 15px",
280
- marginTop: hasDiscount || hasOfferText || dpDiscountPercent
298
+ marginTop: (hasDiscount || hasOfferText || dpDiscountPercent) &&
299
+ !isMaxDiscountApplied
281
300
  ? "14px"
282
301
  : "",
283
302
  } },
@@ -126,6 +126,20 @@ function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currenc
126
126
  }
127
127
  return null;
128
128
  })();
129
+ // Hide the % OFF badge when max_discount is capping the percentage discount
130
+ // (i.e. both percentage and max_discount exist, and the raw % amount exceeds the cap)
131
+ const isMaxDiscountApplied = (() => {
132
+ const { discount_type, discount_value, max_discount } = serviceItem !== null && serviceItem !== void 0 ? serviceItem : {};
133
+ if (discount_type === "percentage" &&
134
+ typeof discount_value === "number" &&
135
+ max_discount != null &&
136
+ max_discount > 0 &&
137
+ discountSeat) {
138
+ const rawPercentageDiscount = (discountSeat.originalPrice * discount_value) / 100;
139
+ return rawPercentageDiscount > max_discount;
140
+ }
141
+ return false;
142
+ })();
129
143
  const renderLabels = () => {
130
144
  if (isPeru) {
131
145
  const isMovilBus = (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.operator_service_name) === "MovilBus";
@@ -242,7 +256,7 @@ function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currenc
242
256
  React.createElement("span", { className: "text-[13.33px] font-normal leading-[22px] text-[#ccc]" }, "Antes")),
243
257
  React.createElement("div", { className: "col-start-1 row-start-3 flex h-[20px] items-end" },
244
258
  React.createElement("span", { className: "text-[13.33px] font-normal leading-[20px] text-[#464647]" }, "Desde")),
245
- React.createElement("div", { className: "col-start-2 row-start-1 flex items-center justify-center absolute", style: { top: "-22px", left: "50%", transform: "translateX(-50%)" } }, discountValue != null && (React.createElement("span", { className: "rounded-[100px] bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white", style: {
259
+ 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: {
246
260
  animation: "pulse-zoom 2s ease-in-out infinite",
247
261
  whiteSpace: "nowrap",
248
262
  backgroundColor: discountSeatPriceColor,
@@ -154,6 +154,19 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
154
154
  }
155
155
  return null;
156
156
  })();
157
+ // Hide the % OFF badge when max_discount is capping the percentage discount
158
+ const isMaxDiscountApplied = (() => {
159
+ const { discount_type, discount_value, max_discount } = serviceItem !== null && serviceItem !== void 0 ? serviceItem : {};
160
+ if (discount_type === "percentage" &&
161
+ typeof discount_value === "number" &&
162
+ max_discount != null &&
163
+ max_discount > 0 &&
164
+ discountSeat) {
165
+ const rawPercentageDiscount = (discountSeat.originalPrice * discount_value) / 100;
166
+ return rawPercentageDiscount > max_discount;
167
+ }
168
+ return false;
169
+ })();
157
170
  const getMinValue = (data) => {
158
171
  const vals = (Array.isArray(data) ? data : Object.values(data || {})).map(Number);
159
172
  if (!vals.length)
@@ -206,7 +219,7 @@ function SeatSectionMobile({ seatTypes: seatTypesData, isSoldOut, isPeru, seatPr
206
219
  commonService.discountedCurrency(Number(firstSeatFare), currencySign)),
207
220
  isSoldOut ? (React.createElement("span", { className: "col-span-2 min-[420]:text-[13px] text-right text-[12px] text-[#ccc]" }, "Agotado")) : null)) : hasDiscount && discountSeat ? (React.createElement("div", null,
208
221
  React.createElement("div", { className: "relative grid grid-cols-[auto_auto] justify-between gap-x-[8px] " },
209
- discountValue != null && (React.createElement("div", { className: "absolute -top-[18px] right-[0px]", style: {
222
+ discountValue != null && !isMaxDiscountApplied && (React.createElement("div", { className: "absolute -top-[18px] right-[0px]", style: {
210
223
  animation: "pulse-zoom 2s ease-in-out infinite",
211
224
  opacity: isSoldOut ? 0.5 : 1,
212
225
  } },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kupos-ui-components-lib",
3
- "version": "9.11.1",
3
+ "version": "9.11.2",
4
4
  "description": "A reusable UI components package",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -225,6 +225,27 @@ function ServiceItemPB({
225
225
  (seat) => seat.originalPrice !== seat.discountedPrice,
226
226
  );
227
227
 
228
+ // Mirror the same check as SeatSection: hide badge (and its top margin) when
229
+ // both percentage and max_discount exist and the cap is being applied.
230
+ const isMaxDiscountApplied = (() => {
231
+ const { discount_type, discount_value, max_discount } = serviceItem as any;
232
+ if (
233
+ discount_type === "percentage" &&
234
+ typeof discount_value === "number" &&
235
+ max_discount != null &&
236
+ max_discount > 0
237
+ ) {
238
+ const lowestFare = discountedSeats
239
+ .map((s) => s.originalPrice)
240
+ .filter((p) => p > 0)
241
+ .sort((a, b) => a - b)[0];
242
+ if (lowestFare != null) {
243
+ return (lowestFare * discount_value) / 100 > max_discount;
244
+ }
245
+ }
246
+ return false;
247
+ })();
248
+
228
249
  const dpDiscountEntry = Object.entries(
229
250
  serviceItem?.dp_discount_percents || {},
230
251
  )[0];
@@ -532,7 +553,8 @@ function ServiceItemPB({
532
553
  : "20px 15px 10px 15px",
533
554
 
534
555
  marginTop:
535
- hasDiscount || hasOfferText || dpDiscountPercent
556
+ (hasDiscount || hasOfferText || dpDiscountPercent) &&
557
+ !isMaxDiscountApplied
536
558
  ? "14px"
537
559
  : "",
538
560
  }}
@@ -236,6 +236,24 @@ function SeatSection({
236
236
  return null;
237
237
  })();
238
238
 
239
+ // Hide the % OFF badge when max_discount is capping the percentage discount
240
+ // (i.e. both percentage and max_discount exist, and the raw % amount exceeds the cap)
241
+ const isMaxDiscountApplied = (() => {
242
+ const { discount_type, discount_value, max_discount } = serviceItem ?? {};
243
+ if (
244
+ discount_type === "percentage" &&
245
+ typeof discount_value === "number" &&
246
+ max_discount != null &&
247
+ max_discount > 0 &&
248
+ discountSeat
249
+ ) {
250
+ const rawPercentageDiscount =
251
+ (discountSeat.originalPrice * discount_value) / 100;
252
+ return rawPercentageDiscount > max_discount;
253
+ }
254
+ return false;
255
+ })();
256
+
239
257
  const renderLabels = () => {
240
258
  if (isPeru) {
241
259
  const isMovilBus = serviceItem?.operator_service_name === "MovilBus";
@@ -490,7 +508,7 @@ function SeatSection({
490
508
  className="col-start-2 row-start-1 flex items-center justify-center absolute"
491
509
  style={{ top: "-22px", left: "50%", transform: "translateX(-50%)" }}
492
510
  >
493
- {discountValue != null && (
511
+ {discountValue != null && !isMaxDiscountApplied && (
494
512
  <span
495
513
  className="rounded-[100px] bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white"
496
514
  style={{
@@ -393,6 +393,23 @@ function SeatSectionMobile({
393
393
  return null;
394
394
  })();
395
395
 
396
+ // Hide the % OFF badge when max_discount is capping the percentage discount
397
+ const isMaxDiscountApplied = (() => {
398
+ const { discount_type, discount_value, max_discount } = serviceItem ?? {};
399
+ if (
400
+ discount_type === "percentage" &&
401
+ typeof discount_value === "number" &&
402
+ max_discount != null &&
403
+ max_discount > 0 &&
404
+ discountSeat
405
+ ) {
406
+ const rawPercentageDiscount =
407
+ (discountSeat.originalPrice * discount_value) / 100;
408
+ return rawPercentageDiscount > max_discount;
409
+ }
410
+ return false;
411
+ })();
412
+
396
413
  const getMinValue = (data: any): number | undefined => {
397
414
  const vals = (Array.isArray(data) ? data : Object.values(data || {})).map(
398
415
  Number,
@@ -510,7 +527,7 @@ function SeatSectionMobile({
510
527
  ) : hasDiscount && discountSeat ? (
511
528
  <div>
512
529
  <div className="relative grid grid-cols-[auto_auto] justify-between gap-x-[8px] ">
513
- {discountValue != null && (
530
+ {discountValue != null && !isMaxDiscountApplied && (
514
531
  <div
515
532
  className="absolute -top-[18px] right-[0px]"
516
533
  style={{