kupos-ui-components-lib 10.1.5 → 10.1.7

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,10 +174,10 @@ 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
- 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, }) => {
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, isOpsite, }) => {
181
181
  var _a, _b, _c, _d, _e;
182
182
  // REMOVED AM/PM DUPLICATION AND ADDED 24 HOUR TIME FORMAT IN BOARDING STAGE
183
183
  const depTime = droppingTimeOnward || "";
@@ -408,6 +408,7 @@ const PaymentSideBarDesktop = ({ serviceNameOnward, serviceNameReturn, metaData,
408
408
  ? returnConexionFare * conexionPassengers
409
409
  : conexionFare, currencySign), className: "subtotal-row font10", customStyle: { color: colors === null || colors === void 0 ? void 0 : colors.seatPriceColor } })) : null,
410
410
  metaData &&
411
+ !isOpsite &&
411
412
  metaData.whatsapp_delivery_charges &&
412
413
  !loginData &&
413
414
  !checkWhatsappEligibility ? (React.createElement(PaymentItem, { label: React.createElement("div", { style: { display: "flex", alignItems: "center" } },
@@ -420,6 +421,20 @@ const PaymentSideBarDesktop = ({ serviceNameOnward, serviceNameReturn, metaData,
420
421
  } }),
421
422
  React.createElement("div", { className: "duration-mouseover font9", style: { lineHeight: "1.3" } },
422
423
  React.createElement("span", null, translation === null || translation === void 0 ? void 0 : translation.whatsappInfoIcon)))), amount: metaData.whatsapp_delivery_charges, className: "font10", customStyle: { color: colors === null || colors === void 0 ? void 0 : colors.whatsappDeliveryChargesColor } })) : null,
424
+ metaData &&
425
+ isOpsite &&
426
+ metaData.opsite_whatsapp_delivery_charges &&
427
+ !loginData &&
428
+ !checkWhatsappEligibility ? (React.createElement(PaymentItem, { label: React.createElement("div", { style: { display: "flex", alignItems: "center" } },
429
+ React.createElement("div", { className: "font10" }, translation === null || translation === void 0 ? void 0 : translation.whatsappDeliveryCharges),
430
+ React.createElement("div", { className: "img-hover" },
431
+ React.createElement("img", { src: icons === null || icons === void 0 ? void 0 : icons.whatsappInfoIcon, alt: "", style: {
432
+ marginLeft: "5px",
433
+ marginBottom: "3px",
434
+ width: "15px",
435
+ } }),
436
+ React.createElement("div", { className: "duration-mouseover font9", style: { lineHeight: "1.3" } },
437
+ React.createElement("span", null, translation === null || translation === void 0 ? void 0 : translation.whatsappInfoIcon)))), amount: metaData.opsite_whatsapp_delivery_charges, className: "font10", customStyle: { color: colors === null || colors === void 0 ? void 0 : colors.whatsappDeliveryChargesColor } })) : null,
423
438
  removeDiscountAtomValue && (React.createElement(PaymentItem, { label: "Cup\u00F3n", amount: CommonService.currency(netFare, currencySign), isNegative: true, currency: "" })),
424
439
  React.createElement("div", { style: { margin: "6px 0" } }, renderDiscount(discountAmount)),
425
440
  (promoCode === null || promoCode === void 0 ? void 0 : promoCode.promoCodeApplied) && (React.createElement(React.Fragment, null,
@@ -71,9 +71,9 @@ 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
- 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, }) => {
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, isOpsite }) => {
77
77
  var _a, _b, _c, _d, _e;
78
78
  return (React.createElement("div", { className: "pb-[15px]" },
79
79
  React.createElement("div", { className: "border border-[#ccc] m-[20px] rounded-[20px] relative" },
@@ -192,6 +192,7 @@ const PaymentSideBarMobile = ({ serviceNameOnward, serviceNameReturn, metaData,
192
192
  React.createElement("div", { className: "bold-text", style: { color: colors === null || colors === void 0 ? void 0 : colors.seatPriceColor } }, CommonService.currency((_e = insuranceData === null || insuranceData === void 0 ? void 0 : insuranceData.insurance_total) !== null && _e !== void 0 ? _e : 0, currencySign)))) : null),
193
193
  React.createElement("div", { style: { margin: "6px 0" } }, renderDiscount(discountAmount)),
194
194
  metaData &&
195
+ !isOpsite &&
195
196
  metaData.whatsapp_delivery_charges &&
196
197
  !loginData &&
197
198
  !checkWhatsappEligibility ? (React.createElement(PaymentItem, { label: React.createElement("div", { style: { display: "flex" } },
@@ -206,6 +207,22 @@ const PaymentSideBarMobile = ({ serviceNameOnward, serviceNameReturn, metaData,
206
207
  backgroundColor: colors === null || colors === void 0 ? void 0 : colors.whatsappDeliveryChargesBgColor,
207
208
  color: colors === null || colors === void 0 ? void 0 : colors.whatsappDeliveryChargesTextColor,
208
209
  } }, translation === null || translation === void 0 ? void 0 : translation.whatsappInfoIcon)))), amount: metaData.whatsapp_delivery_charges, className: "text-[14px]", customStyle: { color: colors === null || colors === void 0 ? void 0 : colors.whatsappDeliveryChargesColor } })) : null,
210
+ metaData &&
211
+ isOpsite &&
212
+ metaData.opsite_whatsapp_delivery_charges &&
213
+ !loginData &&
214
+ !checkWhatsappEligibility ? (React.createElement(PaymentItem, { label: React.createElement("div", { style: { display: "flex" } },
215
+ React.createElement("div", { className: "font-[14px]" }, translation === null || translation === void 0 ? void 0 : translation.whatsappDeliveryCharges),
216
+ React.createElement("div", { className: "img-hover" },
217
+ React.createElement("img", { src: icons === null || icons === void 0 ? void 0 : icons.whatsappInfoIcon, alt: "", style: {
218
+ marginLeft: "5px",
219
+ width: "15px",
220
+ }, onClick: () => setShowWhatsappChargesInfo(!showWhatsappChargesInfo) }),
221
+ showWhatsappChargesInfo && (React.createElement("div", { className: " absolute shadow-xl z-[1] w-[250px] p-[6px_20px] text-[11px] top-[88%] left-[11%] rounded-[10px]", style: {
222
+ lineHeight: "1.3",
223
+ backgroundColor: colors === null || colors === void 0 ? void 0 : colors.whatsappDeliveryChargesBgColor,
224
+ color: colors === null || colors === void 0 ? void 0 : colors.whatsappDeliveryChargesTextColor,
225
+ } }, translation === null || translation === void 0 ? void 0 : translation.whatsappInfoIcon)))), amount: metaData.opsite_whatsapp_delivery_charges, className: "text-[14px]", customStyle: { color: colors === null || colors === void 0 ? void 0 : colors.whatsappDeliveryChargesColor } })) : null,
209
226
  (promoCode === null || promoCode === void 0 ? void 0 : promoCode.promoCodeApplied) && (React.createElement(React.Fragment, null,
210
227
  React.createElement(PaymentItem, { label: `${translation === null || translation === void 0 ? void 0 : translation.promotionalCode}:`, amount: CommonService.currency((promoCode === null || promoCode === void 0 ? void 0 : promoCode.promoCouponAmount)
211
228
  ? promoCode === null || promoCode === void 0 ? void 0 : promoCode.promoCouponAmount
@@ -105,4 +105,5 @@ export interface PaymentSideBarProps {
105
105
  insuranceData?: any;
106
106
  isPeru?: boolean;
107
107
  serviceFeeDataStateValue?: any;
108
+ isOpsite?: boolean;
108
109
  }
@@ -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.7",
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>
@@ -335,6 +335,7 @@ const PaymentSideBarDesktop: React.FC<PaymentSideBarProps> = ({
335
335
  insuranceData,
336
336
  isPeru,
337
337
  serviceFeeDataStateValue,
338
+ isOpsite,
338
339
  }) => {
339
340
  // REMOVED AM/PM DUPLICATION AND ADDED 24 HOUR TIME FORMAT IN BOARDING STAGE
340
341
  const depTime = droppingTimeOnward || "";
@@ -689,6 +690,7 @@ const PaymentSideBarDesktop: React.FC<PaymentSideBarProps> = ({
689
690
  ) : null}
690
691
 
691
692
  {metaData &&
693
+ !isOpsite &&
692
694
  metaData.whatsapp_delivery_charges &&
693
695
  !loginData &&
694
696
  !checkWhatsappEligibility ? (
@@ -723,6 +725,42 @@ const PaymentSideBarDesktop: React.FC<PaymentSideBarProps> = ({
723
725
  />
724
726
  ) : null}
725
727
 
728
+ {metaData &&
729
+ isOpsite &&
730
+ metaData.opsite_whatsapp_delivery_charges &&
731
+ !loginData &&
732
+ !checkWhatsappEligibility ? (
733
+ <PaymentItem
734
+ label={
735
+ <div style={{ display: "flex", alignItems: "center" }}>
736
+ <div className="font10">
737
+ {translation?.whatsappDeliveryCharges}
738
+ </div>
739
+ <div className="img-hover">
740
+ <img
741
+ src={icons?.whatsappInfoIcon}
742
+ alt=""
743
+ style={{
744
+ marginLeft: "5px",
745
+ marginBottom: "3px",
746
+ width: "15px",
747
+ }}
748
+ />
749
+ <div
750
+ className="duration-mouseover font9"
751
+ style={{ lineHeight: "1.3" }}
752
+ >
753
+ <span>{translation?.whatsappInfoIcon}</span>
754
+ </div>
755
+ </div>
756
+ </div>
757
+ }
758
+ amount={metaData.opsite_whatsapp_delivery_charges}
759
+ className="font10"
760
+ customStyle={{ color: colors?.whatsappDeliveryChargesColor }}
761
+ />
762
+ ) : null}
763
+
726
764
  {removeDiscountAtomValue && (
727
765
  <PaymentItem
728
766
  label="Cupón"
@@ -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
  )}
@@ -242,6 +242,7 @@ const PaymentSideBarMobile: React.FC<PaymentSideBarProps> = ({
242
242
  isPeru,
243
243
  setShowServicefeeModal,
244
244
  serviceFeeDataStateValue,
245
+ isOpsite
245
246
  }) => {
246
247
  return (
247
248
  <div className="pb-[15px]">
@@ -461,6 +462,7 @@ const PaymentSideBarMobile: React.FC<PaymentSideBarProps> = ({
461
462
  </div>
462
463
 
463
464
  {metaData &&
465
+ !isOpsite &&
464
466
  metaData.whatsapp_delivery_charges &&
465
467
  !loginData &&
466
468
  !checkWhatsappEligibility ? (
@@ -504,6 +506,51 @@ const PaymentSideBarMobile: React.FC<PaymentSideBarProps> = ({
504
506
  />
505
507
  ) : null}
506
508
 
509
+ {metaData &&
510
+ isOpsite &&
511
+ metaData.opsite_whatsapp_delivery_charges &&
512
+ !loginData &&
513
+ !checkWhatsappEligibility ? (
514
+ <PaymentItem
515
+ label={
516
+ <div style={{ display: "flex" }}>
517
+ <div className="font-[14px]">
518
+ {translation?.whatsappDeliveryCharges}
519
+ </div>
520
+ <div className="img-hover">
521
+ <img
522
+ src={icons?.whatsappInfoIcon}
523
+ alt=""
524
+ style={{
525
+ marginLeft: "5px",
526
+ width: "15px",
527
+ }}
528
+ onClick={() =>
529
+ setShowWhatsappChargesInfo(!showWhatsappChargesInfo)
530
+ }
531
+ />
532
+ {showWhatsappChargesInfo && (
533
+ <div
534
+ className=" absolute shadow-xl z-[1] w-[250px] p-[6px_20px] text-[11px] top-[88%] left-[11%] rounded-[10px]"
535
+ style={{
536
+ lineHeight: "1.3",
537
+ backgroundColor:
538
+ colors?.whatsappDeliveryChargesBgColor,
539
+ color: colors?.whatsappDeliveryChargesTextColor,
540
+ }}
541
+ >
542
+ {translation?.whatsappInfoIcon}
543
+ </div>
544
+ )}
545
+ </div>
546
+ </div>
547
+ }
548
+ amount={metaData.opsite_whatsapp_delivery_charges}
549
+ className="text-[14px]"
550
+ customStyle={{ color: colors?.whatsappDeliveryChargesColor }}
551
+ />
552
+ ) : null}
553
+
507
554
  {promoCode?.promoCodeApplied && (
508
555
  <>
509
556
  <PaymentItem
@@ -104,4 +104,5 @@ export interface PaymentSideBarProps {
104
104
  insuranceData?: any;
105
105
  isPeru?: boolean;
106
106
  serviceFeeDataStateValue?: any;
107
+ isOpsite?: boolean;
107
108
  }
@@ -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;