kupos-ui-components-lib 10.1.5 β†’ 10.1.6

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.
@@ -147,7 +147,7 @@ class ServiceFilter extends React.Component {
147
147
  ((option === null || option === void 0 ? void 0 : option.type) === "tipo" && this.props.isTrain) ||
148
148
  !this.props.isTrain;
149
149
  return (React.createElement("div", { key: key },
150
- shouldShowHeader && (React.createElement("div", { onClick: () => this.toggleFilter(option.type), className: "bold-text flex items-center justify-between mt-[13px] mb-[5px]" },
150
+ shouldShowHeader && (React.createElement("div", { onClick: () => this.toggleFilter(option.type), className: "bold-text flex items-center justify-between mt-[20px] mb-[5px]" },
151
151
  this.props.t("RESULTS_PAGE." + option.title),
152
152
  React.createElement("img", { src: this.props.icons.downArrow, alt: "downArrow", className: `${isOpen ? "rotate-180" : ""} w-[auto] h-[9px] transition-all duration-300 cursor-pointer` }))),
153
153
  React.createElement("div", { className: ` transition-all duration-300 ease-in-out
@@ -174,7 +174,7 @@ const renderSummaryDetailsCard = ({ serviceName, date, source, dest, boardingSta
174
174
  React.createElement("img", { src: icons === null || icons === void 0 ? void 0 : icons.hours, className: "w-[16px] h-[16px] mr-[5px]" })),
175
175
  React.createElement("span", null,
176
176
  "Duraci\u00F3n : ",
177
- duration,
177
+ DateService.formatDuration(duration),
178
178
  " horas")))))));
179
179
  };
180
180
  const PaymentSideBarDesktop = ({ serviceNameOnward, serviceNameReturn, metaData, currencySign, dateOnward, dateReturn, sourceOnward, sourceReturn, destinationOnward, destinationReturn, boardingStageOnward, boardingStageReturn, droppingStageOnward, droppingStageReturn, boardingTimeOnward, boardingTimeReturn, droppingTimeOnward, droppingTimeReturn, durationOnward, durationReturn, selectSeatOnward, selectSeatReturn, journeyTypeActive, setJourneyTypeActive, translation, trainTypeOnward, trainTypeReturn, colors, trainType, icons, selectedOnward, selectedReturn, conexionChecked, conexionPassengers, returnConexionFare, conexionFare, loginData, checkWhatsappEligibility, removeDiscountAtomValue, netFare, promoCode, onPromoRemove, isAgency, agencyFee, walletMoney, virtualMoney, virtualLimit, showUsd, netFareInUsd, renderDiscount, discountAmount, walletLabel, creditosLabel, currency, customSideBarwidth, isLinatal, insuranceData, isPeru, serviceFeeDataStateValue, }) => {
@@ -71,7 +71,7 @@ const renderSummaryDetailsCard = ({ serviceName, date, source, dest, boardingSta
71
71
  " ",
72
72
  isTacna
73
73
  ? `${getRoundedHour(duration)}hrs aprox`
74
- : `${duration} horas`)))))));
74
+ : `${DateService.formatDuration(duration)} horas`)))))));
75
75
  };
76
76
  const PaymentSideBarMobile = ({ serviceNameOnward, serviceNameReturn, metaData, currencySign, dateOnward, dateReturn, sourceOnward, sourceReturn, destinationOnward, destinationReturn, boardingStageOnward, boardingStageReturn, droppingStageOnward, droppingStageReturn, boardingTimeOnward, boardingTimeReturn, droppingTimeOnward, droppingTimeReturn, durationOnward, durationReturn, selectSeatOnward, selectSeatReturn, journeyTypeActive, setJourneyTypeActive, translation, trainTypeOnward, trainTypeReturn, colors, trainType, icons, selectedOnward, selectedReturn, conexionChecked, conexionPassengers, returnConexionFare, conexionFare, loginData, checkWhatsappEligibility, removeDiscountAtomValue, netFare, promoCode, onPromoRemove, isAgency, agencyFee, walletMoney, virtualMoney, virtualLimit, showUsd, netFareInUsd, renderDiscount, discountAmount, currency, showWhatsappChargesInfo, setShowWhatsappChargesInfo, t, countdown, walletLabel, creditosLabel, isTacna, isLinatal, insuranceData, isPeru, setShowServicefeeModal, serviceFeeDataStateValue, }) => {
77
77
  var _a, _b, _c, _d, _e;
@@ -7,33 +7,51 @@ const getAmenityBaseName = (amenityStr) => {
7
7
  };
8
8
  const isWater = (amenityStr) => { var _a; return ((_a = getAmenityBaseName(amenityStr)) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === "WATER"; };
9
9
  const TooltipArrow = ({ color }) => (React.createElement("div", { className: "tooltip-arrow absolute -top-[7px] left-1/2 -translate-x-1/2 w-0 h-0 border-l-8 border-r-8 border-b-8 border-l-transparent border-r-transparent", style: { borderBottomColor: color } }));
10
+ /*
10
11
  const getAmenitySplit = ({ isPeru, amenities, priorityIds }) => {
11
- const priority = amenities.filter((id) => priorityIds.includes(id));
12
- const nonPriority = amenities.filter((id) => !priorityIds.includes(id));
13
- const hasPriority = priority.length > 0;
14
- /* ============================
15
- πŸ‡΅πŸ‡ͺ PERU LOGIC
16
- ============================ */
17
- // if (isPeru) {
18
- // return hasPriority
19
- // ? { visible: priority, plus: nonPriority }
20
- // : { visible: [], plus: amenities };
21
- // }
22
- if (isPeru) {
23
- return hasPriority
24
- ? {
25
- visible: priority.slice(0, 2),
26
- plus: [...priority.slice(2), ...nonPriority],
27
- }
28
- : { visible: amenities.slice(0, 2), plus: amenities.slice(2) };
12
+ const priority = amenities.filter((id) => priorityIds.includes(id));
13
+ const nonPriority = amenities.filter((id) => !priorityIds.includes(id));
14
+ const hasPriority = priority.length > 0;
15
+
16
+ // if (isPeru) {
17
+ // return hasPriority
18
+ // ? { visible: priority, plus: nonPriority }
19
+ // : { visible: [], plus: amenities };
20
+ // }
21
+
22
+ if (isPeru) {
23
+ return hasPriority
24
+ ? {
25
+ visible: priority.slice(0, 2),
26
+ plus: [...priority.slice(2), ...nonPriority],
27
+ }
28
+ : { visible: amenities.slice(0, 2), plus: amenities.slice(2) };
29
+ }
30
+
31
+ const sorted = [...amenities].sort(
32
+ (a, b) => Number(priorityIds.includes(b)) - Number(priorityIds.includes(a)),
33
+ );
34
+
35
+ return {
36
+ visible: sorted.slice(0, 2),
37
+ plus: sorted.slice(2),
38
+ };
39
+ };
40
+ */
41
+ const getAmenitySplit = ({ isPeru, amenities, priorityIds }) => {
42
+ // The three important amenities: Mobile ticket ("3"), USB charger ("2"), WiFi ("13")
43
+ const IMPORTANT_AMENITY_IDS = ["2", "3", "13"];
44
+ const important = amenities.filter((id) => IMPORTANT_AMENITY_IDS.includes(id));
45
+ const nonImportant = amenities.filter((id) => !IMPORTANT_AMENITY_IDS.includes(id));
46
+ if (important.length > 0) {
47
+ return {
48
+ visible: important,
49
+ plus: nonImportant,
50
+ };
29
51
  }
30
- /* ============================
31
- 🌍 NON-PERU LOGIC
32
- ============================ */
33
- const sorted = [...amenities].sort((a, b) => Number(priorityIds.includes(b)) - Number(priorityIds.includes(a)));
34
52
  return {
35
- visible: sorted.slice(0, 2),
36
- plus: sorted.slice(2),
53
+ visible: [],
54
+ plus: amenities,
37
55
  };
38
56
  };
39
57
  const AmenitiesBlock = ({ serviceItem, metaData, isSoldOut, colors, isPeru, getAnimationIcon, getAmenityName, SvgAmenities, }) => {
@@ -53,6 +71,7 @@ const AmenitiesBlock = ({ serviceItem, metaData, isSoldOut, colors, isPeru, getA
53
71
  amenities,
54
72
  priorityIds,
55
73
  });
74
+ console.log("πŸš€ ~ AmenitiesBlock ~ visibleAmenities:", visibleAmenities, amenities);
56
75
  const shouldShowPlus = plusAmenities.length > 0;
57
76
  const grayscaleClass = isSoldOut ? "grayscale" : "";
58
77
  return (React.createElement("div", { className: "relative flex items-center gap-[6px]" },
@@ -1,9 +1,10 @@
1
1
  import React from "react";
2
+ import DateService from "../utils/DateService";
2
3
  const DurationBlock = ({ serviceItem, translation, renderIcon, isSoldOut, colors, }) => (React.createElement("div", { className: "flex items-baseline relative whitespace-nowrap " },
3
4
  React.createElement("div", { className: `w-[18px] mr-[4px] ${isSoldOut ? "grayscale" : ""}`, style: { opacity: isSoldOut ? 0.5 : 1 } }, renderIcon("hours", "14px")),
4
5
  React.createElement("div", { className: "group text-[13.33px] cursor-pointer" },
5
6
  React.createElement("span", { style: { opacity: isSoldOut ? 0.5 : 1 } },
6
- serviceItem.duration,
7
+ DateService.formatDuration(serviceItem.duration),
7
8
  " ",
8
9
  translation.hours),
9
10
  React.createElement("div", { className: "hidden group-hover:block absolute top-[24px] left-1/2 -translate-x-1/2 text-white p-3 rounded-[14px] whitespace-normal z-10 mt-2.5 w-[188px] text-center break-normal shadow-service text-[12px]", style: { backgroundColor: colors.bottomStripColor } },
@@ -217,7 +217,9 @@ function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currenc
217
217
  hasDiscount && (React.createElement("span", { className: "text-[13.33px]", style: {
218
218
  color: "#999",
219
219
  } }, "Antes")),
220
- React.createElement("span", { className: "text-[13.33px] flex flex-col" }, !hasDiscount ? (React.createElement("span", { className: "text-[13.33px] whitespace-nowrap flex items-center" },
220
+ React.createElement("span", { className: "text-[13.33px] flex flex-col" }, !hasDiscount ? (React.createElement("span", { className: "text-[13.33px] whitespace-nowrap flex items-center", style: {
221
+ opacity: isSoldOut ? 0.5 : 1,
222
+ } },
221
223
  isSeatIcon && !hasDiscount && (React.createElement("img", { src: getSeatTypeIcon(seatLabel, serviceItem), alt: "seattype", style: {
222
224
  width: "20px",
223
225
  height: "20px",
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import LottiePlayer from "../../assets/LottiePlayer";
3
+ import DateService from "../../utils/DateService";
3
4
  function BottomAmenitiesMobile({ isSoldOut, amenitiesNodes, hoursIcon, duration, isDirectTrip, directoColor, directoAnim, isChangeTicket, isPetSeat, petSeatInfo, petFriendlyAnim, flexibleAnim, isTrackingEnabled, locationAnim, downArrowIcon, showDropdown, setShowDropdown, onDropdownToggle, isItemExpanded, isPeru, femaleAnim, ladiesBookedSeats, isDpEnabled, }) {
4
5
  return (React.createElement("div", { className: `${"flex justify-between items-center items-center "}` },
5
6
  React.createElement("div", { className: "w-[55%] flex justify-between items-center" },
@@ -8,7 +9,7 @@ function BottomAmenitiesMobile({ isSoldOut, amenitiesNodes, hoursIcon, duration,
8
9
  React.createElement("div", { className: `w-[12px] h-auto mr-[2px] ${isSoldOut ? "grayscale" : ""}` }, hoursIcon),
9
10
  "\u00A0",
10
11
  React.createElement("div", { className: `cursor-default group min-[420]:text-[13px] text-[12px] ${isSoldOut ? "text-[#c0c0c0]" : ""}`, style: { lineHeight: "normal" } },
11
- duration,
12
+ DateService.formatDuration(duration),
12
13
  "hrs"))),
13
14
  React.createElement("div", { className: "flex items-center" },
14
15
  React.createElement("div", null, (isChangeTicket || isPetSeat) && (React.createElement("div", { className: "flex items-center" },
@@ -14,5 +14,9 @@ declare const DateService: {
14
14
  * Format time string (HH:MM) to AM/PM format
15
15
  */
16
16
  formatTime: (time: string) => string;
17
+ /**
18
+ * Format duration string (HH:MM:SS) to HH:MM format
19
+ */
20
+ formatDuration: (duration: string | number | undefined | null) => string;
17
21
  };
18
22
  export default DateService;
@@ -168,5 +168,23 @@ const DateService = {
168
168
  return time;
169
169
  }
170
170
  },
171
+ /**
172
+ * Format duration string (HH:MM:SS) to HH:MM format
173
+ */
174
+ formatDuration: (duration) => {
175
+ if (duration === null || duration === undefined) {
176
+ return "";
177
+ }
178
+ const durationStr = duration.toString().trim();
179
+ if (durationStr.includes(":")) {
180
+ const parts = durationStr.split(":");
181
+ if (parts.length >= 2) {
182
+ const hours = parts[0].trim().padStart(2, "0");
183
+ const minutes = parts[1].trim();
184
+ return `${hours}:${minutes}`;
185
+ }
186
+ }
187
+ return durationStr;
188
+ },
171
189
  };
172
190
  export default DateService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kupos-ui-components-lib",
3
- "version": "10.1.5",
3
+ "version": "10.1.6",
4
4
  "description": "A reusable UI components package",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -223,7 +223,7 @@ class ServiceFilter extends React.Component<
223
223
  {shouldShowHeader && (
224
224
  <div
225
225
  onClick={() => this.toggleFilter(option.type)}
226
- className="bold-text flex items-center justify-between mt-[13px] mb-[5px]"
226
+ className="bold-text flex items-center justify-between mt-[20px] mb-[5px]"
227
227
  >
228
228
  {this.props.t("RESULTS_PAGE." + option.title)}
229
229
  <img
@@ -266,7 +266,7 @@ const renderSummaryDetailsCard = ({
266
266
  className="w-[16px] h-[16px] mr-[5px]"
267
267
  />
268
268
  </div>
269
- <span>DuraciΓ³n : {duration} horas</span>
269
+ <span>DuraciΓ³n : {DateService.formatDuration(duration)} horas</span>
270
270
  </div>
271
271
  )}
272
272
  </div>
@@ -167,7 +167,7 @@ const renderSummaryDetailsCard = ({
167
167
  <span className="bold-text">DuraciΓ³n:</span>{" "}
168
168
  {isTacna
169
169
  ? `${getRoundedHour(duration)}hrs aprox`
170
- : `${duration} horas`}
170
+ : `${DateService.formatDuration(duration)} horas`}
171
171
  </span>
172
172
  </div>
173
173
  )}
@@ -20,14 +20,12 @@ const TooltipArrow = ({ color }) => (
20
20
  />
21
21
  );
22
22
 
23
+ /*
23
24
  const getAmenitySplit = ({ isPeru, amenities, priorityIds }) => {
24
25
  const priority = amenities.filter((id) => priorityIds.includes(id));
25
26
  const nonPriority = amenities.filter((id) => !priorityIds.includes(id));
26
27
  const hasPriority = priority.length > 0;
27
28
 
28
- /* ============================
29
- πŸ‡΅πŸ‡ͺ PERU LOGIC
30
- ============================ */
31
29
  // if (isPeru) {
32
30
  // return hasPriority
33
31
  // ? { visible: priority, plus: nonPriority }
@@ -43,9 +41,6 @@ const getAmenitySplit = ({ isPeru, amenities, priorityIds }) => {
43
41
  : { visible: amenities.slice(0, 2), plus: amenities.slice(2) };
44
42
  }
45
43
 
46
- /* ============================
47
- 🌍 NON-PERU LOGIC
48
- ============================ */
49
44
  const sorted = [...amenities].sort(
50
45
  (a, b) => Number(priorityIds.includes(b)) - Number(priorityIds.includes(a)),
51
46
  );
@@ -55,6 +50,32 @@ const getAmenitySplit = ({ isPeru, amenities, priorityIds }) => {
55
50
  plus: sorted.slice(2),
56
51
  };
57
52
  };
53
+ */
54
+
55
+ const getAmenitySplit = ({ isPeru, amenities, priorityIds }) => {
56
+ // The three important amenities: Mobile ticket ("3"), USB charger ("2"), WiFi ("13")
57
+ const IMPORTANT_AMENITY_IDS = ["2", "3", "13"];
58
+
59
+ const important = amenities.filter((id) =>
60
+ IMPORTANT_AMENITY_IDS.includes(id),
61
+ );
62
+
63
+ const nonImportant = amenities.filter(
64
+ (id) => !IMPORTANT_AMENITY_IDS.includes(id),
65
+ );
66
+
67
+ if (important.length > 0) {
68
+ return {
69
+ visible: important,
70
+ plus: nonImportant,
71
+ };
72
+ }
73
+
74
+ return {
75
+ visible: [],
76
+ plus: amenities,
77
+ };
78
+ };
58
79
 
59
80
  const AmenitiesBlock = ({
60
81
  serviceItem,
@@ -87,6 +108,11 @@ const AmenitiesBlock = ({
87
108
  amenities,
88
109
  priorityIds,
89
110
  });
111
+ console.log(
112
+ "πŸš€ ~ AmenitiesBlock ~ visibleAmenities:",
113
+ visibleAmenities,
114
+ amenities,
115
+ );
90
116
 
91
117
  const shouldShowPlus = plusAmenities.length > 0;
92
118
  const grayscaleClass = isSoldOut ? "grayscale" : "";
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import DateService from "../utils/DateService";
2
3
 
3
4
  const DurationBlock = ({
4
5
  serviceItem,
@@ -17,7 +18,7 @@ const DurationBlock = ({
17
18
 
18
19
  <div className="group text-[13.33px] cursor-pointer">
19
20
  <span style={{ opacity: isSoldOut ? 0.5 : 1 }}>
20
- {serviceItem.duration} {translation.hours}
21
+ {DateService.formatDuration(serviceItem.duration)} {translation.hours}
21
22
  </span>
22
23
  <div
23
24
  className="hidden group-hover:block absolute top-[24px] left-1/2 -translate-x-1/2 text-white p-3 rounded-[14px] whitespace-normal z-10 mt-2.5 w-[188px] text-center break-normal shadow-service text-[12px]"
@@ -411,7 +411,12 @@ function SeatSection({
411
411
 
412
412
  <span className="text-[13.33px] flex flex-col">
413
413
  {!hasDiscount ? (
414
- <span className="text-[13.33px] whitespace-nowrap flex items-center">
414
+ <span
415
+ className="text-[13.33px] whitespace-nowrap flex items-center"
416
+ style={{
417
+ opacity: isSoldOut ? 0.5 : 1,
418
+ }}
419
+ >
415
420
  {isSeatIcon && !hasDiscount && (
416
421
  <img
417
422
  src={
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import LottiePlayer from "../../assets/LottiePlayer";
3
+ import DateService from "../../utils/DateService";
3
4
 
4
5
  interface BottomAmenitiesMobileProps {
5
6
  isSoldOut: boolean;
@@ -75,7 +76,7 @@ function BottomAmenitiesMobile({
75
76
  }`}
76
77
  style={{ lineHeight: "normal" }}
77
78
  >
78
- {duration}hrs
79
+ {DateService.formatDuration(duration)}hrs
79
80
  </div>
80
81
  </div>
81
82
 
@@ -206,6 +206,25 @@ const DateService = {
206
206
  return time;
207
207
  }
208
208
  },
209
+
210
+ /**
211
+ * Format duration string (HH:MM:SS) to HH:MM format
212
+ */
213
+ formatDuration: (duration: string | number | undefined | null): string => {
214
+ if (duration === null || duration === undefined) {
215
+ return "";
216
+ }
217
+ const durationStr = duration.toString().trim();
218
+ if (durationStr.includes(":")) {
219
+ const parts = durationStr.split(":");
220
+ if (parts.length >= 2) {
221
+ const hours = parts[0].trim().padStart(2, "0");
222
+ const minutes = parts[1].trim();
223
+ return `${hours}:${minutes}`;
224
+ }
225
+ }
226
+ return durationStr;
227
+ },
209
228
  };
210
229
 
211
230
  export default DateService;