kupos-ui-components-lib 9.3.1 → 9.3.3

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 (41) hide show
  1. package/dist/assets/images/anims/service_list/60_percent_anim.json +1 -0
  2. package/dist/assets/images/anims/service_list/dot_animation.json +1 -0
  3. package/dist/assets/images/anims/service_list/thunder_icon.json +1 -0
  4. package/dist/components/ServiceItem/ServiceItemDesktop.js +50 -121
  5. package/dist/components/ServiceItem/ServiceItemMobile.js +44 -105
  6. package/dist/components/ServiceItem/mobileTypes.d.ts +3 -0
  7. package/dist/components/ServiceItem/types.d.ts +2 -0
  8. package/dist/styles.css +125 -23
  9. package/dist/types.d.ts +2 -0
  10. package/dist/ui/ExpendedDropDown/ExpandedDropdown.js +16 -19
  11. package/dist/ui/FeatureServiceUI/FeatureServiceUi.d.ts +12 -0
  12. package/dist/ui/FeatureServiceUI/FeatureServiceUi.js +101 -0
  13. package/dist/ui/SeatSection/SeatSection.d.ts +2 -1
  14. package/dist/ui/SeatSection/SeatSection.js +41 -10
  15. package/dist/ui/ServiceBadges/ServiceBadges.d.ts +17 -0
  16. package/dist/ui/ServiceBadges/ServiceBadges.js +33 -0
  17. package/dist/ui/mobileweb/DateTimeSectionMobile.d.ts +2 -1
  18. package/dist/ui/mobileweb/DateTimeSectionMobile.js +2 -2
  19. package/dist/ui/mobileweb/ExpandedDropdownMobile.js +18 -18
  20. package/dist/ui/mobileweb/SeatSectionMobile.d.ts +2 -1
  21. package/dist/ui/mobileweb/SeatSectionMobile.js +28 -16
  22. package/dist/ui/mobileweb/ServiceBadgesMobile.d.ts +17 -0
  23. package/dist/ui/mobileweb/ServiceBadgesMobile.js +35 -0
  24. package/dist/utils/CommonService.d.ts +7 -0
  25. package/dist/utils/CommonService.js +61 -0
  26. package/package.json +1 -1
  27. package/src/assets/images/anims/service_list/dot_animation.json +1 -0
  28. package/src/components/ServiceItem/ServiceItemDesktop.tsx +93 -235
  29. package/src/components/ServiceItem/ServiceItemMobile.tsx +118 -166
  30. package/src/components/ServiceItem/mobileTypes.ts +3 -0
  31. package/src/components/ServiceItem/types.ts +2 -0
  32. package/src/styles.css +10 -0
  33. package/src/types.ts +2 -0
  34. package/src/ui/ExpendedDropDown/ExpandedDropdown.tsx +26 -67
  35. package/src/ui/SeatSection/SeatSection.tsx +87 -32
  36. package/src/ui/ServiceBadges/ServiceBadges.tsx +92 -0
  37. package/src/ui/mobileweb/DateTimeSectionMobile.tsx +3 -0
  38. package/src/ui/mobileweb/ExpandedDropdownMobile.tsx +24 -24
  39. package/src/ui/mobileweb/SeatSectionMobile.tsx +77 -32
  40. package/src/ui/mobileweb/ServiceBadgesMobile.tsx +92 -0
  41. package/src/utils/CommonService.ts +86 -0
@@ -8,6 +8,7 @@ import BottomAmenitiesMobile from "../../ui/mobileweb/BottomAmenitiesMobile";
8
8
  import SeatSectionMobile from "../../ui/mobileweb/SeatSectionMobile";
9
9
  import DateTimeSectionMobile from "../../ui/mobileweb/DateTimeSectionMobile";
10
10
  import ExpandedDropdownMobile from "../../ui/mobileweb/ExpandedDropdownMobile";
11
+ import ServiceBadgesMobile from "../../ui/mobileweb/ServiceBadgesMobile";
11
12
 
12
13
  const SEAT_EXCEPTIONS = ["Asiento mascota"];
13
14
 
@@ -50,57 +51,17 @@ function ServiceItemMobile({
50
51
  let isSoldOut = serviceItem.available_seats <= 0;
51
52
  const isLongOfferText = (serviceItem?.offer_text?.length || 0) > 35;
52
53
 
53
- const startViewerCount = (node: HTMLSpanElement | null) => {
54
- if (!node || !viewersConfig) return;
55
-
56
- const prevId = node.dataset.viewerId;
57
- if (prevId) clearInterval(Number(prevId));
58
-
59
- const { min, max, interval = 5000 } = viewersConfig;
60
- const clamp = (v: number) => Math.min(max, Math.max(min, v));
61
- const initialValue = Math.floor(Math.random() * (max - min + 1)) + min;
62
-
63
- node.textContent = String(initialValue);
64
-
65
- const id = setInterval(() => {
66
- const current = Number(node.textContent) || initialValue;
67
- const delta = Math.ceil(current * 0.2);
68
- const next =
69
- current + Math.floor(Math.random() * (2 * delta + 1)) - delta;
70
- node.textContent = String(clamp(Math.round(next)));
71
- }, interval);
72
-
73
- node.dataset.viewerId = String(id);
74
- };
75
-
76
- const countdownSeconds = 599;
77
-
78
- const startCountdown = (node: HTMLSpanElement | null) => {
79
- if (!node) return;
80
-
81
- const prevId = node.dataset.countdownId;
82
- if (prevId) clearInterval(Number(prevId));
83
-
84
- let remaining = countdownSeconds;
85
-
86
- const formatTime = (totalSecs: number) => {
87
- const m = Math.floor(totalSecs / 60);
88
- const s = totalSecs % 60;
89
- return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
90
- };
91
-
92
- node.textContent = formatTime(remaining);
93
-
94
- const id = setInterval(() => {
95
- remaining -= 1;
96
- if (remaining <= 0) {
97
- remaining = countdownSeconds;
54
+ const hasOfferText = Boolean(serviceItem?.offer_text);
55
+ const offerGradient = "linear-gradient(90deg, #ff5964 0%, #ff8842 100%)";
56
+ const serviceCardStyle: React.CSSProperties = hasOfferText
57
+ ? {
58
+ borderColor: "transparent",
59
+ borderStyle: "solid",
60
+ borderWidth: "6px 6px 0 6px",
61
+ borderRadius: "18px",
62
+ background: `linear-gradient(#fff, #fff) padding-box, ${offerGradient} border-box`,
98
63
  }
99
- node.textContent = formatTime(remaining);
100
- }, 1000);
101
-
102
- node.dataset.countdownId = String(id);
103
- };
64
+ : {};
104
65
 
105
66
  const labelId =
106
67
  typeof serviceItem.boarding_stages === "string"
@@ -174,9 +135,6 @@ function ServiceItemMobile({
174
135
 
175
136
  return (
176
137
  <div
177
- // className={`relative ${
178
- // serviceItem.offer_text ? "mb-[55px]" : "mb-[14px]"
179
- // }
180
138
  className={`relative ${!serviceItem.offer_text ? "mb-[14px]" : showTopLabel || serviceItem?.is_direct_trip ? "mb-[20px]" : "mb-[12px]"} ${
181
139
  serviceItem?.is_direct_trip ||
182
140
  isConexion ||
@@ -187,39 +145,21 @@ function ServiceItemMobile({
187
145
  } `}
188
146
  style={{ backgroundColor: "#fff", zIndex: 1 }}
189
147
  >
190
- {/* <TopAmenitieMobile
191
- showTopLabel={showTopLabel}
192
- isSoldOut={isSoldOut}
193
- seatPriceColor={colors.seatPriceColor}
194
- bombAnim={serviceItem.icons.bombAnim}
195
- priorityStageAnim={serviceItem.icons.priorityStageAnim}
196
- countdownSeconds={countdownSeconds}
197
- onCountdownEnd={() => {
198
- const cardEl = document.getElementById(
199
- `service-card-${serviceItem.id}`,
200
- );
201
- if (!cardEl) return;
202
- cardEl.style.border = "1px solid #ccc";
203
- if (!showTopLabel) {
204
- cardEl.style.borderRadius = "10px";
205
- }
206
- }}
207
- offerText={serviceItem?.offer_text}
208
- /> */}
209
148
  <div
210
- className={" rounded-[20px]"}
211
- style={{
212
- backgroundColor: "#fff",
213
- zIndex: 1,
214
- // borderRadius: showTopLabel ? "10px 0 10px 10px" : "10px",
215
- borderRadius: "12px",
216
- border: "1px solid #ccc",
217
- }}
149
+ className={`bg-white z-1 ${
150
+ hasOfferText
151
+ ? "rounded-[18px]"
152
+ : "rounded-[10px] border border-[#ccc]"
153
+ }`}
154
+ style={serviceCardStyle}
218
155
  >
219
156
  <div style={{ padding: "12px 12px 8px 12px" }}>
220
157
  {/* Header with operator info and favorite */}
221
158
  <div className="flex justify-between items-center mb-[10px]">
222
- <div className="flex items-center justify-between">
159
+ <div
160
+ className="flex items-center justify-between"
161
+ style={{ marginBottom: serviceItem?.offer_text ? "10px" : "" }}
162
+ >
223
163
  <div className="w-[120px] overflow-y-hidden">
224
164
  <img
225
165
  src={serviceItem.operator_details[0]}
@@ -289,6 +229,7 @@ function ServiceItemMobile({
289
229
  arrTime={serviceItem.arr_time}
290
230
  seatTypes={serviceItem.seat_types}
291
231
  seatPriceColor={colors.seatPriceColor}
232
+ tooltipBgColor={colors.tooltipBgColor}
292
233
  currencySign={currencySign}
293
234
  availableSeats={serviceItem.available_seats}
294
235
  removeDuplicateSeats={removeDuplicateSeats}
@@ -317,13 +258,6 @@ function ServiceItemMobile({
317
258
  setShowDropdown={() =>
318
259
  setIsExpanded(isItemExpanded ? null : serviceItem.id)
319
260
  }
320
- // onDropdownToggle={() => {
321
- // setShowDropdown(!showDropdown);
322
- // setAmenetiesAtomValue({
323
- // service: serviceItem,
324
- // showTopLabel: showTopLabel,
325
- // });
326
- // }}
327
261
  onDropdownToggle={() => {
328
262
  setIsExpanded(isItemExpanded ? null : serviceItem.id);
329
263
  }}
@@ -331,77 +265,14 @@ function ServiceItemMobile({
331
265
  />
332
266
  </div>
333
267
 
334
- <div className="absolute -top-[14px] left-0 w-full flex items-center justify-end gap-[12px] pr-[13px] z-10 ">
335
- {showTopLabel && (
336
- <div
337
- className={`flex items-center gap-[2px] py-[4px] px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] z-20 `}
338
- style={{
339
- backgroundColor: isSoldOut ? "#ccc" : colors.ratingBottomColor,
340
- }}
341
- >
342
- <div className={isSoldOut ? "grayscale" : ""}>
343
- <LottiePlayer
344
- animationData={serviceItem.icons.priorityStageAnim}
345
- width="18px"
346
- height="18px"
347
- />
348
- </div>
349
- <div
350
- className={
351
- isSoldOut ? "text-[#bbb]" : `text-[${colors.topLabelColor}]`
352
- }
353
- >
354
- {showTopLabel}
355
- </div>
356
- </div>
357
- )}
358
- {serviceItem?.is_direct_trip === true && (
359
- <div
360
- className={`flex items-center gap-[2px] py-[5px] text-white px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] z-20 `}
361
- style={{
362
- backgroundColor: isSoldOut ? "#ddd" : colors.tooltipBgColor,
363
- color: isSoldOut ? "#bbb" : colors.directoColor,
364
- }}
365
- >
366
- <LottiePlayer
367
- animationData={serviceItem.icons.directoAnim}
368
- width="16px"
369
- height="16px"
370
- />
371
- <div className="ml-[5px]">Directo</div>
372
- </div>
373
- )}
374
- {isConexion && (
375
- <div
376
- className={`flex items-center gap-[2px] py-[5px] text-white px-[10px] rounded-[38px] min-[420]:text-[12px] text-[11px] z-20 ${
377
- isSoldOut ? "text-white" : `text-[${colors.topLabelColor}]`
378
- }`}
379
- style={{
380
- backgroundColor: !isSoldOut && colors.ratingBottomColor,
381
- }}
382
- >
383
- {renderIcon("airportIcon", "14px")}
384
-
385
- <div>Conexión</div>
386
- </div>
387
- )}
388
-
389
- {serviceItem?.train_type_label === "Tren Express (Nuevo)" && (
390
- <div
391
- className={`flex items-center gap-[2px] py-[5px] text-white px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] z-20 `}
392
- style={{
393
- backgroundColor: isSoldOut ? "#ddd" : colors.tooltipColor,
394
- }}
395
- >
396
- <LottiePlayer
397
- animationData={serviceItem.icons.directoAnim}
398
- width="20px"
399
- height="20px"
400
- />
401
- <div>{"Tren Express"}</div>
402
- </div>
403
- )}
404
- </div>
268
+ <ServiceBadgesMobile
269
+ showTopLabel={showTopLabel}
270
+ isSoldOut={isSoldOut}
271
+ colors={colors}
272
+ renderIcon={renderIcon}
273
+ serviceItem={serviceItem}
274
+ isConexion={isConexion}
275
+ />
405
276
  </div>
406
277
 
407
278
  {/* 🔹 EXPANDABLE DROPDOWN (below the card) */}
@@ -409,7 +280,7 @@ function ServiceItemMobile({
409
280
  <div
410
281
  className="px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]"
411
282
  style={{
412
- backgroundColor: isSoldOut ? "#ccc" : colors?.bottomStripColor,
283
+ background: isSoldOut ? "#ccc" : offerGradient,
413
284
  opacity: isSoldOut ? 0.5 : 1,
414
285
  borderRadius: "0 0 14px 14px",
415
286
  zIndex: -1,
@@ -419,15 +290,96 @@ function ServiceItemMobile({
419
290
  className="flex flex-col gap-[8px] text-[12px] min-[420px]:text-[12px] text-[#464647]"
420
291
  style={{ lineHeight: 1.6 }}
421
292
  >
422
- <div className="flex flex-col gap-[4px]">
293
+ <div className="flex justify-between items-start">
294
+ <div
295
+ className={`flex ${isLongOfferText ? "items-start" : "items-center"}`}
296
+ >
297
+ <div className={isLongOfferText ? "mt-[2px]" : ""}>
298
+ <LottiePlayer
299
+ animationData={serviceItem.icons.bombAnim}
300
+ width="14px"
301
+ height="14px"
302
+ />
303
+ </div>
304
+ <div
305
+ className={`ml-[4px] flex-1 outline-none ${isLongOfferText ? "mt-[2px]" : ""}`}
306
+ style={{
307
+ color: "#fff",
308
+ lineHeight: 1.4,
309
+ }}
310
+ >
311
+ {/* <span className="min-[380px]:text-[12px] bold-text">
312
+ {serviceItem?.offer_text || ""}
313
+ </span>{" "} */}
314
+ {/* <span className="min-[380px]:text-[12px]">|</span>{" "} */}
315
+ <span className="whitespace-nowrap min-[380px]:text-[12px]">
316
+ Termina en&nbsp;
317
+ <span
318
+ className="bold-text"
319
+ ref={(node) => commonService.startCountdown(node, 599)}
320
+ style={{
321
+ fontVariantNumeric: "tabular-nums",
322
+ display: "inline-block",
323
+ }}
324
+ />
325
+ </span>
326
+ </div>
327
+ </div>
328
+ <div
329
+ className="flex flex-col items-end"
330
+ style={{
331
+ color: "#fff",
332
+ }}
333
+ >
334
+ <div className="flex items-center">
335
+ <div className="mr-[4px]">
336
+ {" "}
337
+ <LottiePlayer
338
+ animationData={serviceItem.icons.dotAnimation}
339
+ width="12px"
340
+ height="12px"
341
+ />
342
+ </div>
343
+ <span className="flex-1" style={{ lineHeight: 1.4 }}>
344
+ <span
345
+ className="bold-text"
346
+ ref={(node) =>
347
+ commonService.startViewerCount(node, viewersConfig)
348
+ }
349
+ style={{ fontVariantNumeric: "tabular-nums" }}
350
+ />{" "}
351
+ <span className="bold-text">personas</span>{" "}
352
+ <span>
353
+ {" "}
354
+ {/* {viewersConfig.label || " están viendo este viaje"} */}
355
+ viendo
356
+ </span>
357
+ </span>
358
+ </div>
359
+ <div className="flex items-center">
360
+ <span className="whitespace-nowrap">
361
+ ⚡ Quedan pocos{" "}
362
+ <span
363
+ className="bold-text"
364
+ ref={(node) =>
365
+ commonService.startComprandoCount(node, 4, 16)
366
+ }
367
+ style={{ fontVariantNumeric: "tabular-nums" }}
368
+ />{" "}
369
+ comprando
370
+ </span>
371
+ </div>
372
+ </div>
373
+ </div>
374
+ {/* <div className="flex flex-col gap-[4px]">
423
375
  <div
424
376
  className={`flex ${isLongOfferText ? "items-start" : "items-center"}`}
425
377
  >
426
378
  <div className={isLongOfferText ? "mt-[2px]" : ""}>
427
379
  <LottiePlayer
428
380
  animationData={serviceItem.icons.bombAnim}
429
- width="18px"
430
- height="18px"
381
+ width="12px"
382
+ height="12px"
431
383
  />
432
384
  </div>
433
385
  <div
@@ -445,7 +397,7 @@ function ServiceItemMobile({
445
397
  Termina en&nbsp;
446
398
  <span
447
399
  className="bold-text"
448
- ref={startCountdown}
400
+ ref={(node) => commonService.startCountdown(node, 599)}
449
401
  style={{
450
402
  fontVariantNumeric: "tabular-nums",
451
403
  display: "inline-block",
@@ -464,7 +416,7 @@ function ServiceItemMobile({
464
416
  <span className="flex-1" style={{ lineHeight: 1.4 }}>
465
417
  <span
466
418
  className="bold-text"
467
- ref={startViewerCount}
419
+ ref={(node) => commonService.startViewerCount(node, viewersConfig)}
468
420
  style={{ fontVariantNumeric: "tabular-nums" }}
469
421
  />{" "}
470
422
  <span className="bold-text">personas</span>{" "}
@@ -474,7 +426,7 @@ function ServiceItemMobile({
474
426
  </span>
475
427
  </span>
476
428
  </div>
477
- </div>
429
+ </div> */}
478
430
  </div>
479
431
  </div>
480
432
  )}
@@ -117,6 +117,9 @@ export interface MobileServiceItemProps {
117
117
  whiteBoardingIcon?: string;
118
118
  downArrow?: string;
119
119
  personIcon?: string
120
+ specialDeparture?: string;
121
+ fireIcon?: string;
122
+ directoIcon?: string;
120
123
  [key: string]: string | Record<string, string | undefined> | undefined;
121
124
  };
122
125
  useLottieFor?: string[];
@@ -149,6 +149,8 @@ export interface ServiceItemProps {
149
149
  bottomStripColor?: string;
150
150
  directoColor?: string;
151
151
  seatPriceColor?: string;
152
+ rightGradiantColor?: string;
153
+ leftGradiantColor?: string;
152
154
  };
153
155
  cityOrigin?: { value: number; label: string };
154
156
  cityDestination?: { value: number; label: string };
package/src/styles.css CHANGED
@@ -79,6 +79,16 @@
79
79
  }
80
80
  }
81
81
 
82
+ @keyframes pulse-zoom {
83
+ 0%,
84
+ 100% {
85
+ transform: scale(1);
86
+ }
87
+ 50% {
88
+ transform: scale(1.05);
89
+ }
90
+ }
91
+
82
92
  .hide-scrollbar::-webkit-scrollbar {
83
93
  display: none;
84
94
  }
package/src/types.ts CHANGED
@@ -112,6 +112,8 @@ export interface ServiceItemProps {
112
112
  wifiIcon?: string;
113
113
  cortinaIcon?: string;
114
114
  frazaIcon?: string;
115
+ specialDeparture?: string;
116
+ fireIcon?: string;
115
117
  [key: string]: string | Record<string, string | undefined> | undefined;
116
118
  };
117
119
  useLottieFor?: string[];
@@ -31,54 +31,36 @@ function ExpandedDropdown({
31
31
  style={{
32
32
  backgroundColor: "#ffefef",
33
33
  borderRadius: "0 0 10px 10px",
34
- // border: showPromo ? `1px solid ${colors.priceColor}` : "1px solid #ccc",
35
- // border: `1px solid ${colors.priceColor}`,
36
-
37
- // borderTop: "none",
38
34
  }}
39
35
  >
40
- {/* <div className="flex flex-col gap-[12px] text-[13px] text-[#464647]">
41
- {hasPetInfo && (
42
- <div className="flex items-center gap-[10px]">
43
- <LottiePlayer
44
- animationData={getAnimationIcon("petFriendlyAnim")}
45
- width="20px"
46
- height="20px"
47
- />
48
- <div className="h-auto mr-[4px] text-[13px] text-[#464647] bold-text">
49
- <span>{translation?.petFriendly}</span>
50
- </div>
51
- </div>
52
- )}
53
- { serviceItem.is_change_ticket && (
54
- <div className="flex items-center gap-[10px]">
55
- <LottiePlayer
56
- animationData={getAnimationIcon("flexibleIcon")}
57
- width="20px"
58
- height="20px"
59
- />
60
- <div className="h-auto mr-[4px] text-[13px] text-[#464647] bold-text">
61
- <span>{translation?.flexible}</span>
62
- </div>
36
+ <div
37
+ className="flex flex-col gap-[6px] text-[13px] text-[#464647]"
38
+ style={{ lineHeight: 1.5 }}
39
+ >
40
+ {isPeru ? null : isChangeTicket ? (
41
+ <div className="flex gap-[8px]" style={{ lineHeight: 1.5 }}>
42
+ <span style={{ marginTop: "2px" }}>•</span>
43
+ <span>
44
+ <span className="bold-text">Pasaje flexible:</span> Tu pasaje
45
+ puede ser cambiado de manera online{" "}
46
+ <span className="bold-text">
47
+ hasta {serviceItem?.change_ticket_hours || 6} horas antes
48
+ </span>{" "}
49
+ de la salida del bus. El monto será reembolsado a tu billetera
50
+ kupospay.
51
+ </span>
63
52
  </div>
64
- )}
65
- {serviceItem?.is_tracking_enabled && (
66
- <div className={`${grayscaleClass} flex items-center gap-[10px]`}>
67
- <LottiePlayer
68
- animationData={getAnimationIcon("locationAnim")}
69
- width="20px"
70
- height="20px"
71
- />
72
- <div className="h-auto mr-[4px] text-[13px] text-[#464647] bold-text">
73
- <span>{"GPS Tracker"}</span>
74
- </div>
53
+ ) : (
54
+ <div className="flex gap-[8px] text-[13.33px]">
55
+ <span style={{ marginTop: "2px" }}>•</span>
56
+ <span>
57
+ <span>
58
+ <span className="bold-text">Pasaje flexible:</span> Esta empresa
59
+ no permite cambios de pasajes.
60
+ </span>
61
+ </span>
75
62
  </div>
76
63
  )}
77
- </div> */}
78
- <div
79
- className="flex flex-col gap-[10px] text-[13px] text-[#464647]"
80
- style={{ lineHeight: 1.6 }}
81
- >
82
64
  {hasPetInfo && (
83
65
  <div className="flex items-center gap-[10px]">
84
66
  <LottiePlayer
@@ -91,6 +73,7 @@ function ExpandedDropdown({
91
73
  </div>
92
74
  </div>
93
75
  )}
76
+
94
77
  <div className="flex gap-[8px] text-[13.33px]">
95
78
  <span style={{ marginTop: "2px" }}>•</span>
96
79
  <span>
@@ -100,30 +83,6 @@ function ExpandedDropdown({
100
83
  salida del bus.
101
84
  </span>
102
85
  </div>
103
- {isPeru ? null : isChangeTicket ? (
104
- <div className="flex gap-[8px]">
105
- <span style={{ marginTop: "2px" }}>•</span>
106
- <span>
107
- <span className="bold-text">Políticas de cambios:</span> Tu pasaje
108
- puede ser cambiado de manera online{" "}
109
- <span className="bold-text">
110
- hasta {serviceItem?.change_ticket_hours || 6} horas antes
111
- </span>{" "}
112
- de la salida del bus. El monto será reembolsado a tu billetera
113
- kupospay.
114
- </span>
115
- </div>
116
- ) : (
117
- <div className="flex gap-[8px] text-[13.33px]">
118
- <span style={{ marginTop: "2px" }}>•</span>
119
- <span>
120
- <span>
121
- <span className="bold-text">Política de cambios:</span> Esta
122
- empresa no permite cambios de pasajes
123
- </span>
124
- </span>
125
- </div>
126
- )}
127
86
  </div>
128
87
  </div>
129
88
  );