kupos-ui-components-lib 10.4.37 → 10.4.39

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.
@@ -1,4 +1,4 @@
1
1
  import React from "react";
2
2
  import { FilterBarProps } from "./tyoes";
3
- declare const FilterBarDesktop: ({ t, serviceList, setServiceList, allSchedules, showReturnTripModal, filterArrData, isBlankTicket, operatorId, filtersArray, setFiltersArray, metaData, busTerminals, setTypes, colors, icons, translation, isTrain, isPeru, hideOperator, setCoachLoading, setCoachKey, isAllinBus, }: FilterBarProps) => React.JSX.Element;
3
+ declare const FilterBarDesktop: ({ t, serviceList, setServiceList, allSchedules, showReturnTripModal, filterArrData, isBlankTicket, operatorId, filtersArray, setFiltersArray, metaData, busTerminals, setTypes, colors, icons, translation, isTrain, isPeru, hideOperator, setCoachLoading, setCoachKey, isAllinBus, priority_stage_ids, }: FilterBarProps) => React.JSX.Element;
4
4
  export default FilterBarDesktop;
@@ -2,21 +2,45 @@ import React from "react";
2
2
  import commonService from "../../utils/CommonService";
3
3
  import ServiceFilter from "./ServiceFilter";
4
4
  let cachedStageOptions = null;
5
- const FilterBarDesktop = ({ t, serviceList, setServiceList, allSchedules, showReturnTripModal, filterArrData, isBlankTicket, operatorId, filtersArray, setFiltersArray, metaData, busTerminals, setTypes, colors, icons, translation, isTrain, isPeru, hideOperator, setCoachLoading, setCoachKey, isAllinBus, }) => {
5
+ const FilterBarDesktop = ({ t, serviceList, setServiceList, allSchedules, showReturnTripModal, filterArrData, isBlankTicket, operatorId, filtersArray, setFiltersArray, metaData, busTerminals, setTypes, colors, icons, translation, isTrain, isPeru, hideOperator, setCoachLoading, setCoachKey, isAllinBus, priority_stage_ids, }) => {
6
+ // Same rule as showTopLabel in ServiceItemDesktop: a visible bus terminal
7
+ // label, restricted to priority_stage_ids when that list is non-empty.
8
+ const getTopLabel = (labelId) => {
9
+ const stageValue = busTerminals === null || busTerminals === void 0 ? void 0 : busTerminals[labelId];
10
+ if (!stageValue)
11
+ return false;
12
+ const [label, visible] = stageValue.split("|");
13
+ if (visible !== "true" || !label)
14
+ return false;
15
+ if (priority_stage_ids && priority_stage_ids.length > 0) {
16
+ return priority_stage_ids.includes(labelId) ? label : false;
17
+ }
18
+ return label;
19
+ };
6
20
  const getEnrichedFilters = () => {
7
- const hasSpecialDeparture = filtersArray.some((f) => { var _a; return f.type === "special_departure" && ((_a = f.options) === null || _a === void 0 ? void 0 : _a.length) > 0; });
8
- if (hasSpecialDeparture)
21
+ if (!isAllinBus)
9
22
  return filtersArray;
10
- if (isAllinBus && (allSchedules === null || allSchedules === void 0 ? void 0 : allSchedules.length)) {
23
+ if (allSchedules === null || allSchedules === void 0 ? void 0 : allSchedules.length) {
24
+ // Mirror what each service card shows: the top label if there is one,
25
+ // otherwise the boarding name.
11
26
  const stageMap = new Map();
12
27
  allSchedules.forEach((schedule) => {
13
28
  var _a, _b, _c;
29
+ const labelId = typeof schedule.boarding_stages === "string"
30
+ ? schedule.boarding_stages.split("|")[0]
31
+ : "";
32
+ const topLabel = labelId && getTopLabel(labelId);
33
+ if (topLabel) {
34
+ stageMap.set(labelId, topLabel);
35
+ return;
36
+ }
14
37
  if ((_a = schedule.stage_details_arr) === null || _a === void 0 ? void 0 : _a.length) {
15
38
  const stageObj = schedule.stage_details_arr[0];
16
39
  const stageId = Object.keys(stageObj)[0];
17
40
  const stageName = (_c = (_b = stageObj[stageId]) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.split(", ")[0];
18
- if (stageId && stageName) {
19
- stageMap.set(stageId, stageName);
41
+ const id = labelId || stageId;
42
+ if (id && stageName) {
43
+ stageMap.set(id, stageName);
20
44
  }
21
45
  }
22
46
  });
@@ -28,11 +52,31 @@ const FilterBarDesktop = ({ t, serviceList, setServiceList, allSchedules, showRe
28
52
  }));
29
53
  }
30
54
  }
31
- if (cachedStageOptions === null || cachedStageOptions === void 0 ? void 0 : cachedStageOptions.length) {
32
- return filtersArray.map((f) => f.type === "special_departure"
33
- ? Object.assign(Object.assign({}, f), { options: cachedStageOptions }) : f);
34
- }
35
- return filtersArray;
55
+ if (!(cachedStageOptions === null || cachedStageOptions === void 0 ? void 0 : cachedStageOptions.length))
56
+ return filtersArray;
57
+ // Replace the special departure options with the computed ones, keeping
58
+ // the active state of options already selected. Stays a no-op once the
59
+ // options match, so the setFiltersArray call below doesn't loop.
60
+ let changed = false;
61
+ const enriched = filtersArray.map((f) => {
62
+ if (f.type !== "special_departure")
63
+ return f;
64
+ const existing = f.options || [];
65
+ const isSame = existing.length === cachedStageOptions.length &&
66
+ cachedStageOptions.every((opt, i) => {
67
+ var _a, _b;
68
+ return String((_a = existing[i]) === null || _a === void 0 ? void 0 : _a.value) === opt.value &&
69
+ ((_b = existing[i]) === null || _b === void 0 ? void 0 : _b.label) === opt.label;
70
+ });
71
+ if (isSame)
72
+ return f;
73
+ changed = true;
74
+ return Object.assign(Object.assign({}, f), { options: cachedStageOptions.map((opt) => {
75
+ var _a;
76
+ return (Object.assign(Object.assign({}, opt), { active: !!((_a = existing.find((o) => String(o.value) === opt.value)) === null || _a === void 0 ? void 0 : _a.active) }));
77
+ }) });
78
+ });
79
+ return changed ? enriched : filtersArray;
36
80
  };
37
81
  const enrichedFilters = getEnrichedFilters();
38
82
  if (enrichedFilters !== filtersArray) {
@@ -36,4 +36,5 @@ export interface FilterBarProps {
36
36
  setCoachLoading?: any;
37
37
  setCoachKey?: any;
38
38
  isAllinBus?: boolean;
39
+ priority_stage_ids?: string[];
39
40
  }
@@ -305,7 +305,7 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
305
305
  },
306
306
  ];
307
307
  const otherItems = items.filter((i) => i.key !== "pet" && i.key !== "flexible" && !!i.condition);
308
- return (React.createElement(React.Fragment, null, isPeruSites ? (React.createElement(PeruServiceItemDesktop, { serviceItem: serviceItem, onBookButtonPress: onBookButtonPress, colors: colors, metaData: metaData, children: children, busStage: busStage, serviceDetailsLoading: serviceDetailsLoading, cityOrigin: cityOrigin, cityDestination: cityDestination, translation: translation, orignLabel: orignLabel, destinationLabel: destinationLabel, currencySign: currencySign, isCiva: isCiva, showRating: showRating, showLastSeats: showLastSeats, removeArrivalTime: removeArrivalTime, removeDuplicateSeats: removeDuplicateSeats, isPeruSites: isPeruSites, t: (key) => t(key), showAvailableSeats: showAvailableSeats, isSeatIcon: isSeatIcon, isPeru: isPeru, siteType: siteType, isAllinBus: isAllinBus, viewersConfig: viewersConfig, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, isExpand: isExpand, setIsExpand: setIsExpand, coachKey: coachKey, isFlores: isFlores, isNewUiEnabled: isNewUiEnabledPeru, showLoginOption: showLoginOption })) : isNewUi && !isTrain ? (React.createElement(FeatureServiceUi, { serviceItem: serviceItem, showTopLabel: showTopLabel, getAnimationIcon: getAnimationIcon, cityOrigin: cityOrigin, cityDestination: cityDestination, renderIcon: renderIcon, viewersConfig: viewersConfig, isFeatureDropDownExpand: isFeatureDropDownExpand, ticketQuantity: ticketQuantity, onIncreaseTicketQuantity: onIncreaseTicketQuantity, onDecreaseTicketQuantity: onDecreaseTicketQuantity, onBookButtonPress: onRemateUiButtonClick, onToggleExpand: () => setIsFeatureDropDownExpand &&
308
+ return (React.createElement(React.Fragment, null, isPeruSites ? (React.createElement(PeruServiceItemDesktop, { serviceItem: serviceItem, onBookButtonPress: onBookButtonPress, colors: colors, metaData: metaData, children: children, busStage: busStage, serviceDetailsLoading: serviceDetailsLoading, cityOrigin: cityOrigin, cityDestination: cityDestination, translation: translation, orignLabel: orignLabel, destinationLabel: destinationLabel, currencySign: currencySign, isCiva: isCiva, showRating: showRating, showLastSeats: showLastSeats, removeArrivalTime: removeArrivalTime, removeDuplicateSeats: removeDuplicateSeats, isPeruSites: isPeruSites, t: (key) => t(key), showAvailableSeats: showAvailableSeats, isSeatIcon: isSeatIcon, isPeru: isPeru, siteType: siteType, isAllinBus: isAllinBus, viewersConfig: viewersConfig, isLoggedIn: isLoggedIn, showLoginModal: showLoginModal, isExpand: isExpand, setIsExpand: setIsExpand, coachKey: coachKey, isFlores: isFlores, isNewUiEnabled: isNewUiEnabledPeru, showLoginOption: showLoginOption, priority_stage_ids: priority_stage_ids })) : isNewUi && !isTrain ? (React.createElement(FeatureServiceUi, { serviceItem: serviceItem, showTopLabel: showTopLabel, getAnimationIcon: getAnimationIcon, cityOrigin: cityOrigin, cityDestination: cityDestination, renderIcon: renderIcon, viewersConfig: viewersConfig, isFeatureDropDownExpand: isFeatureDropDownExpand, ticketQuantity: ticketQuantity, onIncreaseTicketQuantity: onIncreaseTicketQuantity, onDecreaseTicketQuantity: onDecreaseTicketQuantity, onBookButtonPress: onRemateUiButtonClick, onToggleExpand: () => setIsFeatureDropDownExpand &&
309
309
  setIsFeatureDropDownExpand(isFeatureDropDownExpand === serviceItem.id ||
310
310
  isFeatureDropDownExpand === true
311
311
  ? null
@@ -419,7 +419,7 @@ export const PaymentCardMobile = (props) => {
419
419
  React.createElement("span", { style: S.sectionRowValue, className: "bold-text" }, CommonService.currency((_g = insuranceData === null || insuranceData === void 0 ? void 0 : insuranceData.insurance_total) !== null && _g !== void 0 ? _g : 0, currencySign)))) : null,
420
420
  ((_h = props.serviceFeeDataStateValue) === null || _h === void 0 ? void 0 : _h.total_convenience_fee_amount) && (React.createElement("div", { style: S.sectionRow },
421
421
  React.createElement("span", { style: { flex: 1 } }, "Cargo por servicio"),
422
- React.createElement("span", { style: S.sectionRowValue, className: "bold-text" }, CommonService.currency(props.serviceFeeDataStateValue
422
+ React.createElement("span", { style: S.sectionRowValue }, CommonService.currency(props.serviceFeeDataStateValue
423
423
  .total_convenience_fee_amount, currencySign)))),
424
424
  (promoCode === null || promoCode === void 0 ? void 0 : promoCode.promoCodeApplied) && (React.createElement(React.Fragment, null,
425
425
  React.createElement("div", { style: S.sectionRow },
@@ -476,8 +476,7 @@ export const PaymentCardMobile = (props) => {
476
476
  virtualMoney ? (React.createElement("div", { style: S.sectionRow },
477
477
  React.createElement("span", { style: { flex: 1 } },
478
478
  React.createElement("span", { style: { color: "var(--secondary-color)" } }, `${creditosLabel}(${virtualLimit}%)`)),
479
- React.createElement("span", { style: Object.assign(Object.assign({}, S.sectionRowValue), { color: "var(--secondary-color)" }), className: "bold-text" }, CommonService.currency(((virtualLimit !== null && virtualLimit !== void 0 ? virtualLimit : 0) / 100) *
480
- Number(virtualMoney !== null && virtualMoney !== void 0 ? virtualMoney : 0), currencySign)))) : null,
479
+ React.createElement("span", { style: Object.assign(Object.assign({}, S.sectionRowValue), { color: "var(--secondary-color)" }), className: "bold-text" }, CommonService.currency(virtualMoney, currencySign)))) : null,
481
480
  React.createElement("div", { style: {
482
481
  borderTop: "1.5px dashed #464647",
483
482
  margin: "14px 0",
@@ -495,10 +494,17 @@ export const PaymentCardMobile = (props) => {
495
494
  currency ? currency : "",
496
495
  " ",
497
496
  CommonService.currency(isPeru
498
- ? Math.round((removeDiscountAtomValue ? 0 : netFare) * 100) / 100
497
+ ? Math.round(Math.max(0, ((removeDiscountAtomValue
498
+ ? 0
499
+ : (netFare !== null && netFare !== void 0 ? netFare : 0)) -
500
+ (walletMoney !== null && walletMoney !== void 0 ? walletMoney : 0) -
501
+ (virtualMoney !== null && virtualMoney !== void 0 ? virtualMoney : 0)) *
502
+ 100)) / 100
499
503
  : removeDiscountAtomValue
500
504
  ? 0
501
- : netFare, currencySign))))));
505
+ : Math.max(0, (netFare !== null && netFare !== void 0 ? netFare : 0) -
506
+ (walletMoney !== null && walletMoney !== void 0 ? walletMoney : 0) -
507
+ (virtualMoney !== null && virtualMoney !== void 0 ? virtualMoney : 0)), currencySign))))));
502
508
  } }),
503
509
  React.createElement("div", { style: {
504
510
  display: "flex",
@@ -40,7 +40,7 @@ const ServiceBadges = ({ showTopLabel, isSoldOut, colors, renderIcon, translatio
40
40
  } },
41
41
  renderIcon("directo", "12px"),
42
42
  React.createElement("div", null, "Tren Express"))),
43
- boardingName && isAllinBus && (React.createElement("div", { className: `flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-20`, style: {
43
+ boardingName && isAllinBus && !showTopLabel && (React.createElement("div", { className: `flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-20`, style: {
44
44
  backgroundColor: colors.topLabelBgColor || "#fff",
45
45
  border: isSoldOut
46
46
  ? "1px solid #ccc"
@@ -40,7 +40,7 @@ const ServiceBadgesMobile = ({ showTopLabel, isSoldOut, colors, renderIcon, serv
40
40
  } },
41
41
  renderIcon("directo", "12px"),
42
42
  React.createElement("div", null, "Tren Express"))),
43
- boardingName && isAllinBus && (React.createElement("div", { className: `flex items-center gap-[2p x] py-[4px] px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] h-[24px] z-20`, style: {
43
+ boardingName && isAllinBus && !showTopLabel && (React.createElement("div", { className: `flex items-center gap-[2p x] py-[4px] px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] h-[24px] z-20`, style: {
44
44
  backgroundColor: colors.topLabelBgColor || "#fff",
45
45
  border: isSoldOut
46
46
  ? "1px solid #ccc"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kupos-ui-components-lib",
3
- "version": "10.4.37",
3
+ "version": "10.4.39",
4
4
  "description": "A reusable UI components package",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -28,22 +28,47 @@ const FilterBarDesktop = ({
28
28
  setCoachLoading,
29
29
  setCoachKey,
30
30
  isAllinBus,
31
+ priority_stage_ids,
31
32
  }: FilterBarProps) => {
33
+ // Same rule as showTopLabel in ServiceItemDesktop: a visible bus terminal
34
+ // label, restricted to priority_stage_ids when that list is non-empty.
35
+ const getTopLabel = (labelId: string) => {
36
+ const stageValue = busTerminals?.[labelId];
37
+ if (!stageValue) return false;
38
+ const [label, visible] = stageValue.split("|");
39
+ if (visible !== "true" || !label) return false;
40
+ if (priority_stage_ids && priority_stage_ids.length > 0) {
41
+ return priority_stage_ids.includes(labelId) ? label : false;
42
+ }
43
+ return label;
44
+ };
45
+
32
46
  const getEnrichedFilters = () => {
33
- const hasSpecialDeparture = filtersArray.some(
34
- (f: any) => f.type === "special_departure" && f.options?.length > 0,
35
- );
36
- if (hasSpecialDeparture) return filtersArray;
47
+ if (!isAllinBus) return filtersArray;
37
48
 
38
- if (isAllinBus && allSchedules?.length) {
49
+ if (allSchedules?.length) {
50
+ // Mirror what each service card shows: the top label if there is one,
51
+ // otherwise the boarding name.
39
52
  const stageMap = new Map<string, string>();
40
53
  allSchedules.forEach((schedule: any) => {
54
+ const labelId =
55
+ typeof schedule.boarding_stages === "string"
56
+ ? schedule.boarding_stages.split("|")[0]
57
+ : "";
58
+
59
+ const topLabel = labelId && getTopLabel(labelId);
60
+ if (topLabel) {
61
+ stageMap.set(labelId, topLabel);
62
+ return;
63
+ }
64
+
41
65
  if (schedule.stage_details_arr?.length) {
42
66
  const stageObj = schedule.stage_details_arr[0];
43
67
  const stageId = Object.keys(stageObj)[0];
44
68
  const stageName = stageObj[stageId]?.[0]?.split(", ")[0];
45
- if (stageId && stageName) {
46
- stageMap.set(stageId, stageName);
69
+ const id = labelId || stageId;
70
+ if (id && stageName) {
71
+ stageMap.set(id, stageName);
47
72
  }
48
73
  }
49
74
  });
@@ -59,15 +84,35 @@ const FilterBarDesktop = ({
59
84
  }
60
85
  }
61
86
 
62
- if (cachedStageOptions?.length) {
63
- return filtersArray.map((f: any) =>
64
- f.type === "special_departure"
65
- ? { ...f, options: cachedStageOptions! }
66
- : f,
67
- );
68
- }
87
+ if (!cachedStageOptions?.length) return filtersArray;
88
+
89
+ // Replace the special departure options with the computed ones, keeping
90
+ // the active state of options already selected. Stays a no-op once the
91
+ // options match, so the setFiltersArray call below doesn't loop.
92
+ let changed = false;
93
+ const enriched = filtersArray.map((f: any) => {
94
+ if (f.type !== "special_departure") return f;
95
+ const existing = f.options || [];
96
+ const isSame =
97
+ existing.length === cachedStageOptions!.length &&
98
+ cachedStageOptions!.every(
99
+ (opt, i) =>
100
+ String(existing[i]?.value) === opt.value &&
101
+ existing[i]?.label === opt.label,
102
+ );
103
+ if (isSame) return f;
104
+ changed = true;
105
+ return {
106
+ ...f,
107
+ options: cachedStageOptions!.map((opt) => ({
108
+ ...opt,
109
+ active: !!existing.find((o: any) => String(o.value) === opt.value)
110
+ ?.active,
111
+ })),
112
+ };
113
+ });
69
114
 
70
- return filtersArray;
115
+ return changed ? enriched : filtersArray;
71
116
  };
72
117
 
73
118
  const enrichedFilters = getEnrichedFilters();
@@ -35,5 +35,6 @@ export interface FilterBarProps {
35
35
  setCoachLoading?: any;
36
36
  setCoachKey?: any;
37
37
  isAllinBus?: boolean;
38
-
38
+ priority_stage_ids?: string[];
39
+
39
40
  }
@@ -712,7 +712,7 @@ const PaymentSideBarMobile: React.FC<PaymentSideBarProps> = (props) => {
712
712
  }
713
713
  amount={CommonService.currency(
714
714
  ((virtualLimit ?? 0) / 100) * Number(virtualMoney ?? 0),
715
- currencySign
715
+ currencySign,
716
716
  )}
717
717
  customStyle={{ color: "var(--secondary-color)" }}
718
718
  className="text-[14px]"
@@ -520,6 +520,7 @@ function ServiceItemPB({
520
520
  isFlores={isFlores}
521
521
  isNewUiEnabled={isNewUiEnabledPeru}
522
522
  showLoginOption={showLoginOption}
523
+ priority_stage_ids={priority_stage_ids}
523
524
  />
524
525
  ) : isNewUi && !isTrain ? (
525
526
  <FeatureServiceUi
@@ -777,7 +777,7 @@ export const PaymentCardMobile: React.FC<PaymentSideBarProps> = (props) => {
777
777
  ?.total_convenience_fee_amount && (
778
778
  <div style={S.sectionRow}>
779
779
  <span style={{ flex: 1 }}>Cargo por servicio</span>
780
- <span style={S.sectionRowValue} className="bold-text">
780
+ <span style={S.sectionRowValue}>
781
781
  {CommonService.currency(
782
782
  props.serviceFeeDataStateValue
783
783
  .total_convenience_fee_amount,
@@ -934,11 +934,7 @@ export const PaymentCardMobile: React.FC<PaymentSideBarProps> = (props) => {
934
934
  }}
935
935
  className="bold-text"
936
936
  >
937
- {CommonService.currency(
938
- ((virtualLimit ?? 0) / 100) *
939
- Number(virtualMoney ?? 0),
940
- currencySign,
941
- )}
937
+ {CommonService.currency(virtualMoney, currencySign)}
942
938
  </span>
943
939
  </div>
944
940
  ) : null}
@@ -968,11 +964,24 @@ export const PaymentCardMobile: React.FC<PaymentSideBarProps> = (props) => {
968
964
  {CommonService.currency(
969
965
  isPeru
970
966
  ? Math.round(
971
- (removeDiscountAtomValue ? 0 : netFare) * 100,
967
+ Math.max(
968
+ 0,
969
+ ((removeDiscountAtomValue
970
+ ? 0
971
+ : (netFare ?? 0)) -
972
+ (walletMoney ?? 0) -
973
+ (virtualMoney ?? 0)) *
974
+ 100,
975
+ ),
972
976
  ) / 100
973
977
  : removeDiscountAtomValue
974
978
  ? 0
975
- : netFare,
979
+ : Math.max(
980
+ 0,
981
+ (netFare ?? 0) -
982
+ (walletMoney ?? 0) -
983
+ (virtualMoney ?? 0),
984
+ ),
976
985
  currencySign,
977
986
  )}
978
987
  </span>
@@ -97,7 +97,7 @@ const ServiceBadges: React.FC<ServiceBadgesProps> = ({
97
97
  <div>{"Tren Express"}</div>
98
98
  </div>
99
99
  )}
100
- {boardingName && isAllinBus && (
100
+ {boardingName && isAllinBus && !showTopLabel && (
101
101
  <div
102
102
  className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-20`}
103
103
  style={{
@@ -104,7 +104,7 @@ const ServiceBadgesMobile: React.FC<ServiceBadgesMobileProps> = ({
104
104
  <div>{"Tren Express"}</div>
105
105
  </div>
106
106
  )}
107
- {boardingName && isAllinBus && (
107
+ {boardingName && isAllinBus && !showTopLabel && (
108
108
  <div
109
109
  className={`flex items-center gap-[2p x] py-[4px] px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] h-[24px] z-20`}
110
110
  style={{