kupos-ui-components-lib 10.4.63 → 10.4.65

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.
Files changed (62) hide show
  1. package/dist/components/ServiceItem/PeruServiceItemDesktop.js +3 -1
  2. package/dist/components/ServiceItem/PeruServiceItemMobile.js +5 -3
  3. package/dist/components/ServiceItem/ServiceItemDesktop.js +4 -2
  4. package/dist/components/ServiceItem/ServiceItemMobile.js +11 -13
  5. package/dist/components/ServiceItem/mobileTypes.d.ts +2 -0
  6. package/dist/components/ServiceItem/types.d.ts +2 -0
  7. package/dist/ui/ExpendedDropDown/ExpandedDropdown.d.ts +1 -0
  8. package/dist/ui/ExpendedDropDown/ExpandedDropdown.js +7 -1
  9. package/dist/ui/OfferBanner.d.ts +1 -1
  10. package/dist/ui/OfferBanner.js +9 -5
  11. package/dist/ui/PeruOfferBanner.d.ts +1 -1
  12. package/dist/ui/PeruOfferBanner.js +5 -1
  13. package/dist/ui/SeatSection/SeatSection.js +6 -4
  14. package/dist/ui/ServiceBadges/ServiceBadges.js +1 -1
  15. package/dist/ui/mobileweb/ExpandedDropdownMobile.d.ts +1 -0
  16. package/dist/ui/mobileweb/ExpandedDropdownMobile.js +6 -1
  17. package/dist/ui/mobileweb/SeatSectionMobile.js +7 -3
  18. package/dist/utils/CommonService.d.ts +7 -0
  19. package/dist/utils/CommonService.js +6 -0
  20. package/package.json +1 -1
  21. package/src/components/ServiceItem/PeruServiceItemDesktop.tsx +4 -1
  22. package/src/components/ServiceItem/PeruServiceItemMobile.tsx +6 -3
  23. package/src/components/ServiceItem/ServiceItemDesktop.tsx +4 -2
  24. package/src/components/ServiceItem/ServiceItemMobile.tsx +12 -13
  25. package/src/components/ServiceItem/mobileTypes.ts +2 -0
  26. package/src/components/ServiceItem/types.ts +2 -0
  27. package/src/ui/ExpendedDropDown/ExpandedDropdown.tsx +12 -2
  28. package/src/ui/OfferBanner.tsx +10 -5
  29. package/src/ui/PeruOfferBanner.tsx +7 -1
  30. package/src/ui/SeatSection/SeatSection.tsx +20 -16
  31. package/src/ui/ServiceBadges/ServiceBadges.tsx +1 -1
  32. package/src/ui/mobileweb/ExpandedDropdownMobile.tsx +13 -1
  33. package/src/ui/mobileweb/SeatSectionMobile.tsx +25 -18
  34. package/src/utils/CommonService.ts +13 -0
  35. package/dist/ServiceItemPb.d.ts +0 -4
  36. package/dist/ServiceItemPb.js +0 -486
  37. package/dist/assets/images/anims/service_list/60_percent_anim.json +0 -1
  38. package/dist/assets/images/directo-icon.png +0 -0
  39. package/dist/components/FilterSortBar/SingleFilterSheet.d.ts +0 -15
  40. package/dist/components/FilterSortBar/SingleFilterSheet.js +0 -21
  41. package/dist/components/PaymentOptions/PaymentOptionsDesktop.d.ts +0 -4
  42. package/dist/components/PaymentOptions/PaymentOptionsDesktop.js +0 -5
  43. package/dist/components/PaymentOptions/PaymentOptionsMobile.d.ts +0 -4
  44. package/dist/components/PaymentOptions/PaymentOptionsMobile.js +0 -5
  45. package/dist/components/PaymentOptions/ResponsivePaymentOptions.d.ts +0 -3
  46. package/dist/components/PaymentOptions/ResponsivePaymentOptions.js +0 -10
  47. package/dist/components/PaymentOptions/index.d.ts +0 -5
  48. package/dist/components/PaymentOptions/index.js +0 -4
  49. package/dist/components/PaymentOptions/mobileTypes.d.ts +0 -0
  50. package/dist/components/PaymentOptions/mobileTypes.js +0 -0
  51. package/dist/components/PaymentOptions/type.d.ts +0 -4
  52. package/dist/components/PaymentOptions/type.js +0 -1
  53. package/dist/components/ServiceItem/ExpandedDropdown.d.ts +0 -19
  54. package/dist/components/ServiceItem/ExpandedDropdown.js +0 -28
  55. package/dist/components/ServiceItem/ServiceItemDesktopPeru.d.ts +0 -6
  56. package/dist/components/ServiceItem/ServiceItemDesktopPeru.js +0 -612
  57. package/dist/example.d.ts +0 -5
  58. package/dist/example.js +0 -240
  59. package/dist/ui/ServiceType.d.ts +0 -9
  60. package/dist/ui/ServiceType.js +0 -9
  61. package/dist/ui/TopAmenities/PromoCountdown.d.ts +0 -18
  62. package/dist/ui/TopAmenities/PromoCountdown.js +0 -55
@@ -43,6 +43,8 @@ export interface ServiceItemProps {
43
43
  offer_text?: string;
44
44
  is_direct_trip?: boolean;
45
45
  is_dp_enabled?: boolean;
46
+ show_dp_ui?: boolean;
47
+ show_best_price?: boolean;
46
48
  dp_discount_percents?: any;
47
49
  dp_discounted_seats?: any;
48
50
  original_dp_price?: any;
@@ -7,6 +7,7 @@ interface ExpandedDropdownProps {
7
7
  pet_seat_info?: Record<string, any>;
8
8
  is_change_ticket?: boolean;
9
9
  is_tracking_enabled?: boolean;
10
+ operator_service_name?: string;
10
11
  };
11
12
  isPeru?: boolean;
12
13
  translation?: Record<string, string>;
@@ -34,7 +35,7 @@ function ExpandedDropdown({
34
35
  const hasPetInfo =
35
36
  serviceItem.pet_seat_info &&
36
37
  Object.keys(serviceItem.pet_seat_info).length > 0;
37
-
38
+ console.log("ExpandedDropdown serviceItem:", serviceItem);
38
39
  return (
39
40
  <div
40
41
  className="px-[15px] pt-[26px] pb-[14px] -mt-[16px] pt-[35px] relative -z-9"
@@ -47,7 +48,16 @@ function ExpandedDropdown({
47
48
  className="flex flex-col gap-[6px] text-[13px] text-[#464647]"
48
49
  style={{ lineHeight: 1.5, opacity: isSoldOut ? 0.5 : 1 }}
49
50
  >
50
- {isPeru || isDpEnabled ? null : isChangeTicket ? (
51
+ {isPeru || isDpEnabled ? null : serviceItem?.operator_service_name ===
52
+ "Cóndor Bus" ? (
53
+ <div className="flex gap-[8px] text-[13.33px]">
54
+ <span>{renderIcon("changeTicketIcon", "16px")}</span>
55
+ <span>
56
+ <span className="bold-text">Pasaje flexible:</span> Esta empresa
57
+ permite cambios hasta la hora del viaje.
58
+ </span>
59
+ </div>
60
+ ) : isChangeTicket ? (
51
61
  <div className="flex gap-[8px]" style={{ lineHeight: 1.5 }}>
52
62
  <span>{renderIcon("changeTicketIcon", "16px")}</span>
53
63
  {/* <span style={{ marginTop: "2px" }}>
@@ -8,6 +8,7 @@ import { ServiceItemProps } from "../components/ServiceItem/types";
8
8
  type ServiceItemSlice = Pick<
9
9
  ServiceItemProps["serviceItem"],
10
10
  | "is_dp_enabled"
11
+ | "show_dp_ui"
11
12
  | "offer_text"
12
13
  | "dp_discount_percents"
13
14
  | "dp_discounted_seats"
@@ -49,6 +50,7 @@ function truncateOfferText(text: string): string {
49
50
  }
50
51
 
51
52
  function hasDpDiscounts(serviceItem: ServiceItemSlice): boolean {
53
+ if (CommonService.isDpUiHidden(serviceItem)) return false;
52
54
  return (
53
55
  Object.keys(serviceItem?.dp_discount_percents ?? {}).length > 0 ||
54
56
  (serviceItem?.dp_discounted_seats ?? []).length > 0
@@ -238,23 +240,26 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
238
240
  (serviceItem as any)?.discount_value > 0 &&
239
241
  (serviceItem as any)?.discount_value < 20;
240
242
  const offerText = serviceItem?.offer_text || "";
243
+ // With show_dp_ui: false the banner renders as for a non-DP service
244
+ const showDpUi =
245
+ serviceItem?.is_dp_enabled && !CommonService.isDpUiHidden(serviceItem);
241
246
 
242
247
  const isLegacyOffer =
243
248
  !!offerText &&
244
249
  isNewUiEnabled &&
245
250
  serviceItem?.ui_type === 1 &&
246
- !serviceItem?.is_dp_enabled;
251
+ !showDpUi;
247
252
 
248
253
  const showViewers =
249
254
  (isNewUiEnabled && serviceItem?.ui_type !== 1) ||
250
- serviceItem?.is_dp_enabled;
255
+ showDpUi;
251
256
 
252
257
  const background = isLegacyOffer ? colors?.bottomStripColor : offerGradient;
253
258
 
254
259
  const renderLeftContent = () => {
255
260
  const hasDp = hasDpDiscounts(serviceItem);
256
261
 
257
- if (serviceItem?.is_dp_enabled && !hasDp) {
262
+ if (showDpUi && !hasDp) {
258
263
  return <PopularServiceBanner getAnimationIcon={getAnimationIcon} />;
259
264
  }
260
265
 
@@ -292,14 +297,14 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
292
297
  style={{
293
298
  background:
294
299
  (isNewUiEnabled && serviceItem?.ui_type === 2) ||
295
- (serviceItem?.is_dp_enabled && serviceItem?.dp_discount_percents)
300
+ (showDpUi && serviceItem?.dp_discount_percents)
296
301
  ? offerGradient
297
302
  : background,
298
303
  opacity: isSoldOut ? 0.5 : 1,
299
304
  zIndex: isLinatal ? "-1" : "0",
300
305
  paddingBottom:
301
306
  serviceItem?.offer_text && serviceItem?.ui_type !== 2
302
- ? "12px"
307
+ ? "7px"
303
308
  : "9px",
304
309
  }}
305
310
  >
@@ -8,6 +8,7 @@ import { ServiceItemProps } from "../components/ServiceItem/types";
8
8
  type ServiceItemSlice = Pick<
9
9
  ServiceItemProps["serviceItem"],
10
10
  | "is_dp_enabled"
11
+ | "show_dp_ui"
11
12
  | "offer_text"
12
13
  | "dp_discount_percents"
13
14
  | "dp_discounted_seats"
@@ -49,6 +50,7 @@ function truncateOfferText(text: string): string {
49
50
  }
50
51
 
51
52
  function hasDpDiscounts(serviceItem: ServiceItemSlice): boolean {
53
+ if (CommonService.isDpUiHidden(serviceItem)) return false;
52
54
  return (
53
55
  Object.keys(serviceItem?.dp_discount_percents ?? {}).length > 0 ||
54
56
  (serviceItem?.dp_discounted_seats ?? []).length > 0
@@ -232,7 +234,11 @@ const PeruOfferBanner: React.FC<PeruOfferBannerProps> = ({
232
234
  : offerGradient;
233
235
 
234
236
  const renderLeftContent = () => {
235
- if (serviceItem?.is_dp_enabled && !hasDp) {
237
+ if (
238
+ serviceItem?.is_dp_enabled &&
239
+ !CommonService.isDpUiHidden(serviceItem) &&
240
+ !hasDp
241
+ ) {
236
242
  return <PopularServiceBanner getAnimationIcon={getAnimationIcon} />;
237
243
  }
238
244
 
@@ -516,6 +516,8 @@ function SeatSection({
516
516
  serviceItem?.dp_discount_percents || {},
517
517
  ).sort(([, a], [, b]) => Number(a) - Number(b))[0];
518
518
  const dpDiscountPercent = dpDiscountEntry?.[1];
519
+ // show_dp_ui: false falls through to the regular fare layout
520
+ const isDpUiHidden = CommonService.isDpUiHidden(serviceItem);
519
521
  const getLowestDpValue = (source: any): number | undefined => {
520
522
  if (!source) return undefined;
521
523
  const values: any[] = Array.isArray(source)
@@ -611,7 +613,7 @@ function SeatSection({
611
613
  );
612
614
  };
613
615
 
614
- if (serviceItem?.is_dp_enabled && !dpDiscountEntry) {
616
+ if (serviceItem?.is_dp_enabled && !isDpUiHidden && !dpDiscountEntry) {
615
617
  const dpSeats = (
616
618
  removeDuplicateSeats ? uniqueSeats : sortedSeatTypes
617
619
  ).filter((s) => !SEAT_EXCEPTIONS.includes(s.label));
@@ -636,25 +638,27 @@ function SeatSection({
636
638
  <div className="absolute -left-[20px] transform -translate-y-1/2 top-[16px]">
637
639
  {renderIcon("fireIcon", "16px")}
638
640
  </div>
639
- <div
640
- className="absolute bottom-[35px] left-1/2 -translate-x-1/2 "
641
- style={{
642
- animation: "pulse-zoom 2s ease-in-out infinite",
643
- whiteSpace: "nowrap",
644
- }}
645
- >
646
- <span
647
- className="rounded-[100px] px-[6px] px-[2px] w-fit text-[12px] bold-text leading-[20px] text-white"
641
+ {CommonService.showDpBestPrice(serviceItem) && (
642
+ <div
643
+ className="absolute bottom-[35px] left-1/2 -translate-x-1/2 "
648
644
  style={{
649
645
  animation: "pulse-zoom 2s ease-in-out infinite",
650
646
  whiteSpace: "nowrap",
651
- color: dpSeatColor,
652
- backgroundColor: tooltipColor,
653
647
  }}
654
648
  >
655
- Mejor precio
656
- </span>
657
- </div>
649
+ <span
650
+ className="rounded-[100px] px-[6px] px-[2px] w-fit text-[12px] bold-text leading-[20px] text-white"
651
+ style={{
652
+ animation: "pulse-zoom 2s ease-in-out infinite",
653
+ whiteSpace: "nowrap",
654
+ color: dpSeatColor,
655
+ backgroundColor: tooltipColor,
656
+ }}
657
+ >
658
+ Mejor precio
659
+ </span>
660
+ </div>
661
+ )}
658
662
  <div
659
663
  className="text-[22px] bold-text leading-[30px] text-center"
660
664
  style={{ color: isSoldOut ? "#c0c0c0" : dpSeatColor }}
@@ -669,7 +673,7 @@ function SeatSection({
669
673
  );
670
674
  }
671
675
 
672
- if (dpDiscountEntry) {
676
+ if (dpDiscountEntry && !isDpUiHidden) {
673
677
  const originalDpPrice = getLowestDpValue(serviceItem.original_dp_price);
674
678
  const allFares = (serviceItem.seat_types ?? [])
675
679
  .map((st: any) => st.fare)
@@ -32,7 +32,7 @@ const ServiceBadges: React.FC<ServiceBadgesProps> = ({
32
32
  getAnimationIcon,
33
33
  }) => {
34
34
  return (
35
- <div className="absolute -top-[13px] left-0 w-full flex items-center justify-end gap-[12px] pr-[22px] z-10">
35
+ <div className="absolute -top-[11px] left-0 w-full flex items-center justify-end gap-[12px] pr-[22px] z-10">
36
36
  {showTopLabel && (
37
37
  <div
38
38
  className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-10`}
@@ -7,6 +7,7 @@ interface ExpandedDropdownMobileProps {
7
7
  pet_seat_info?: Record<string, any>;
8
8
  is_change_ticket?: boolean;
9
9
  is_tracking_enabled?: boolean;
10
+ operator_service_name?: string;
10
11
  };
11
12
  isPeru?: boolean;
12
13
  petSeatInfo?: Record<string, any>;
@@ -48,7 +49,18 @@ function ExpandedDropdownMobile({
48
49
  className="flex flex-col gap-[8px] text-[11px] min-[420px]:text-[12px] text-[#464647]"
49
50
  style={{ lineHeight: 1.6 }}
50
51
  >
51
- {isPeru || isDpEnabled ? null : isChangeTicket ? (
52
+ {isPeru || isDpEnabled ? null : serviceItem?.operator_service_name ===
53
+ "Cóndor Bus" ? (
54
+ <div className="flex gap-[6px]">
55
+ <span className="mt-[3px]">
56
+ {renderIcon("changeTicketIcon", "14px")}
57
+ </span>
58
+ <span>
59
+ <span className="bold-text">Pasaje flexible:</span> Esta empresa
60
+ permite cambios hasta la hora del viaje.
61
+ </span>
62
+ </div>
63
+ ) : isChangeTicket ? (
52
64
  <div className="flex gap-[6px]">
53
65
  <span className="mt-[3px]">
54
66
  {renderIcon("changeTicketIcon", "14px")}
@@ -360,27 +360,29 @@ function SeatSectionMobile({
360
360
  className="relative flex flex-col justify-center h-full"
361
361
  style={{ opacity: isSoldOut ? 0.5 : 1 }}
362
362
  >
363
- <div
364
- className="absolute right-[0px]"
365
- style={{
366
- animation: "pulse-zoom 2s ease-in-out infinite",
367
- top:
368
- (serviceItem?.available_seats < 10 &&
369
- serviceItem?.available_seats > 0) ||
370
- isSoldOut
371
- ? "-20px"
372
- : "-15px",
373
- }}
374
- >
375
- <span
376
- className="rounded-[100px] px-[8px] text-[11px] bold-text leading-[20px] text-[#fff]"
363
+ {commonService.showDpBestPrice(serviceItem) && (
364
+ <div
365
+ className="absolute right-[0px]"
377
366
  style={{
378
- backgroundColor: tooltipBgColor,
367
+ animation: "pulse-zoom 2s ease-in-out infinite",
368
+ top:
369
+ (serviceItem?.available_seats < 10 &&
370
+ serviceItem?.available_seats > 0) ||
371
+ isSoldOut
372
+ ? "-20px"
373
+ : "-15px",
379
374
  }}
380
375
  >
381
- Mejor precio
382
- </span>
383
- </div>
376
+ <span
377
+ className="rounded-[100px] px-[8px] text-[11px] bold-text leading-[20px] text-[#fff]"
378
+ style={{
379
+ backgroundColor: tooltipBgColor,
380
+ }}
381
+ >
382
+ Mejor precio
383
+ </span>
384
+ </div>
385
+ )}
384
386
  <div className="w-[100%] flex flex-row justify-between items-center">
385
387
  <span
386
388
  className="min-[420]:text-[13px] text-[12px]"
@@ -568,7 +570,11 @@ function SeatSectionMobile({
568
570
  )
569
571
  ?.sort((a, b) => a.fare - b.fare)[0]?.fare;
570
572
 
573
+ // show_dp_ui: false falls through to the regular fare layout
574
+ const isDpUiHidden = commonService.isDpUiHidden(serviceItem);
575
+
571
576
  const hasDpDiscount =
577
+ !isDpUiHidden &&
572
578
  serviceItem?.dp_discounted_seats &&
573
579
  serviceItem?.dp_discount_percents &&
574
580
  originalDpPrice != null &&
@@ -581,6 +587,7 @@ function SeatSectionMobile({
581
587
  style={{ width: "40%", flexShrink: 0 }}
582
588
  >
583
589
  {serviceItem?.is_dp_enabled &&
590
+ !isDpUiHidden &&
584
591
  !serviceItem?.dp_discounted_seats?.length &&
585
592
  !dpDiscountPercent ? (
586
593
  <div
@@ -349,6 +349,19 @@ const commonService = {
349
349
  return match ? icons?.[`seat${match[1]}`] || null : null;
350
350
  },
351
351
 
352
+ // The backend can switch off the DP look (gradient card, ribbon, DP fare
353
+ // block) per DP service with show_dp_ui: false. DP fare rules (no changes /
354
+ // cancellations) still apply. A missing flag keeps the current UI.
355
+ isDpUiHidden: (serviceItem?: {
356
+ is_dp_enabled?: boolean;
357
+ show_dp_ui?: boolean;
358
+ }): boolean =>
359
+ Boolean(serviceItem?.is_dp_enabled) && serviceItem?.show_dp_ui === false,
360
+
361
+ // "Mejor precio" pill on DP fares; a missing flag keeps the current UI.
362
+ showDpBestPrice: (serviceItem?: { show_best_price?: boolean }): boolean =>
363
+ serviceItem?.show_best_price !== false,
364
+
352
365
  calculateDiscountedPrice: (
353
366
  originalPrice: number | string,
354
367
  serviceItem?: {
@@ -1,4 +0,0 @@
1
- import React from "react";
2
- import { ServiceItemProps } from "./types";
3
- declare function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, t, }: ServiceItemProps): React.ReactElement;
4
- export default ServiceItemPB;