kupos-ui-components-lib 9.2.9 → 9.2.10

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,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { ServiceItemProps } from "./types";
3
- declare function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isSeatIcon, showAvailableSeats, isPeru, siteType, isAllinBus, viewersConfig, isExpand, setIsExpand, coachKey, t, }: ServiceItemProps & {
3
+ declare function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isSeatIcon, showAvailableSeats, isPeru, siteType, isAllinBus, t, }: ServiceItemProps & {
4
4
  currencySign?: string;
5
5
  }): React.ReactElement;
6
6
  export default PeruServiceItemDesktop;
@@ -14,78 +14,73 @@ import pullmanFlexibleAnimation from "../../assets/images/anims/service_list/pul
14
14
  import pullmanPetFriendlyAnimation from "../../assets/images/anims/service_list/pullmanPetFriendly.json";
15
15
  import pullmanLocationAnimation from "../../assets/images/anims/service_list/pullmanLocation.json";
16
16
  import pullmanPriorityStageAnimation from "../../assets/images/anims/service_list/pullmanPriorityStage.json";
17
+ import pullmanPromoAnimation from "../../assets/images/anims/service_list/promocion.json";
18
+ import pullmanDirectoAnimation from "../../assets/images/anims/service_list/directo.json";
17
19
  import opsitesFlexibleAnimation from "../../assets/images/anims/service_list/opsitesFlexible.json";
18
20
  import opsitesPetFriendlyAnimation from "../../assets/images/anims/service_list/opsitesPetFriendly.json";
19
21
  import opsitesLocationAnimation from "../../assets/images/anims/service_list/opsitesLocation.json";
20
22
  import opsitesPriorityStageAnimation from "../../assets/images/anims/service_list/opsitesPriorityStage.json";
21
- import bombAnimation from "../../assets/images/anims/service_list/bomb.json";
23
+ import opsitesPromoAnimation from "../../assets/images/anims/service_list/promocion.json";
24
+ import opsitesDirectoAnimation from "../../assets/images/anims/service_list/directo.json";
25
+ import linatalFlexibleAnimation from "../../assets/images/anims/service_list/flexible.json";
26
+ import linatalPromoAnimation from "../../assets/images/anims/service_list/promocion.json";
27
+ import linatalDirectoAnimation from "../../assets/images/anims/service_list/directo.json";
28
+ import linatalPriorityStageAnimation from "../../assets/images/anims/service_list/priority_stage.json";
29
+ import linatalPetFriendlyAnimation from "../../assets/images/anims/service_list/pet_friendly.json";
30
+ import linatalLocationAnimation from "../../assets/images/anims/service_list/location.json";
22
31
  import StageTooltip from "../../ui/StagesTooltip";
23
32
  import RatingBlock from "../../ui/RatingBlock";
24
33
  import DurationBlock from "../../ui/DurationBlock";
25
34
  import PetBlock from "../../ui/PetBlock";
26
35
  import FlexibleBlock from "../../ui/FlexibleBlock";
27
36
  import AmenitiesBlock from "../../ui/AmenitiesBlock";
28
- import SeatSection from "../../ui/SeatSection/SeatSection";
29
- import KuposButton from "../../ui/KuposButton/KuposButton";
30
- import BottomAmenities from "../../ui/BottomAmenities/BottomAmenities";
31
37
  const SEAT_EXCEPTIONS = ["Asiento mascota"];
32
- const ANIMATION_MAP = {
33
- promoAnim: {
34
- kupos: promoAnimation,
35
- },
36
- locationAnim: {
37
- kupos: locationAnimation,
38
- pullman: pullmanLocationAnimation,
39
- opsites: opsitesLocationAnimation,
40
- },
41
- directoAnim: {
42
- kupos: directoAnimation,
43
- },
44
- petFriendlyAnim: {
45
- kupos: petFriendlyAnimation,
46
- pullman: pullmanPetFriendlyAnimation,
47
- opsites: opsitesPetFriendlyAnimation,
48
- },
49
- priorityStageAnim: {
50
- kupos: priorityStageAnimation,
51
- pullman: pullmanPriorityStageAnimation,
52
- opsites: opsitesPriorityStageAnimation,
53
- },
54
- flexibleIcon: {
55
- kupos: flexibleAnimation,
56
- pullman: pullmanFlexibleAnimation,
57
- opsites: opsitesFlexibleAnimation,
58
- },
59
- bombAnimation: {
60
- kupos: bombAnimation,
61
- },
62
- };
63
- function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isSeatIcon, showAvailableSeats, isPeru, siteType, isAllinBus, viewersConfig, isExpand, setIsExpand, coachKey, t = (key) => key, }) {
38
+ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isSeatIcon, showAvailableSeats, isPeru, siteType, isAllinBus, t = (key) => key, }) {
64
39
  var _a, _b, _c, _d;
65
- const startViewerCount = (node) => {
66
- if (!node || !viewersConfig)
67
- return;
68
- const prevId = node.dataset.viewerId;
69
- if (prevId)
70
- clearInterval(Number(prevId));
71
- const { min, max, interval = 5000 } = viewersConfig;
72
- const clamp = (v) => Math.min(max, Math.max(min, v));
73
- const initialValue = Math.floor(Math.random() * (max - min + 1)) + min;
74
- node.textContent = String(initialValue);
75
- const id = setInterval(() => {
76
- const current = Number(node.textContent) || initialValue;
77
- const delta = Math.ceil(current * 0.2);
78
- const next = current + Math.floor(Math.random() * (2 * delta + 1)) - delta;
79
- node.textContent = String(clamp(Math.round(next)));
80
- }, interval);
81
- node.dataset.viewerId = String(id);
40
+ const animationMap = {
41
+ promoAnim: {
42
+ kupos: promoAnimation,
43
+ pullman: pullmanPromoAnimation,
44
+ opsites: opsitesPromoAnimation,
45
+ linatal: linatalPromoAnimation,
46
+ },
47
+ locationAnim: {
48
+ kupos: locationAnimation,
49
+ pullman: pullmanLocationAnimation,
50
+ opsites: opsitesLocationAnimation,
51
+ linatal: linatalLocationAnimation,
52
+ },
53
+ directoAnim: {
54
+ kupos: directoAnimation,
55
+ pullman: pullmanDirectoAnimation,
56
+ opsites: opsitesDirectoAnimation,
57
+ linatal: linatalDirectoAnimation,
58
+ },
59
+ petFriendlyAnim: {
60
+ kupos: petFriendlyAnimation,
61
+ pullman: pullmanPetFriendlyAnimation,
62
+ opsites: opsitesPetFriendlyAnimation,
63
+ linatal: linatalPetFriendlyAnimation,
64
+ },
65
+ priorityStageAnim: {
66
+ kupos: priorityStageAnimation,
67
+ pullman: pullmanPriorityStageAnimation,
68
+ opsites: opsitesPriorityStageAnimation,
69
+ linatal: linatalPriorityStageAnimation,
70
+ },
71
+ flexibleIcon: {
72
+ kupos: flexibleAnimation,
73
+ pullman: pullmanFlexibleAnimation,
74
+ opsites: opsitesFlexibleAnimation,
75
+ linatal: linatalFlexibleAnimation,
76
+ },
82
77
  };
83
78
  const getAnimationIcon = (icon) => {
84
- var _a;
85
- const animation = ANIMATION_MAP[icon];
79
+ const animation = animationMap[icon];
86
80
  if (!animation)
87
81
  return null;
88
- return (_a = animation[siteType]) !== null && _a !== void 0 ? _a : animation.kupos;
82
+ const currentSiteType = siteType || "kupos";
83
+ return animation[currentSiteType];
89
84
  };
90
85
  const SvgAmenities = ({ moreAnemities, name, color, }) => {
91
86
  var _a;
@@ -317,55 +312,18 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
317
312
  const dropoffName = ((_b = serviceItem.stage_details_arr) === null || _b === void 0 ? void 0 : _b.length)
318
313
  ? extractStage(serviceItem.stage_details_arr, 1)
319
314
  : null;
320
- const countdownSeconds = 599;
321
- const startCountdown = (node) => {
322
- if (!node)
323
- return;
324
- const prevId = node.dataset.countdownId;
325
- if (prevId)
326
- clearInterval(Number(prevId));
327
- let remaining = countdownSeconds;
328
- const formatTime = (totalSecs) => {
329
- const m = Math.floor(totalSecs / 60);
330
- const s = totalSecs % 60;
331
- return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
332
- };
333
- node.textContent = formatTime(remaining);
334
- const id = setInterval(() => {
335
- remaining -= 1;
336
- if (remaining <= 0) {
337
- remaining = countdownSeconds;
338
- }
339
- node.textContent = formatTime(remaining);
340
- }, 1000);
341
- node.dataset.countdownId = String(id);
342
- };
343
315
  const items = [
344
316
  {
345
- key: "amenities",
346
- width: "20%",
347
- condition: true,
348
- render: (React.createElement(AmenitiesBlock, { serviceItem: serviceItem, metaData: metaData, isSoldOut: isSoldOut, colors: colors, getAnimationIcon: getAnimationIcon, getAmenityName: CommonService.getAmenityName, SvgAmenities: SvgAmenities, isPeru: isPeru })),
317
+ key: "rating",
318
+ width: "30%",
319
+ render: (React.createElement(RatingBlock, { showRating: showRating, serviceItem: serviceItem, isSoldOut: isSoldOut, colors: colors, t: t, translation: translation, isPeru: isPeru })),
349
320
  },
350
321
  {
351
322
  key: "duration",
352
- width: "12%",
323
+ width: "20%",
353
324
  condition: serviceItem.duration,
354
325
  render: (React.createElement(DurationBlock, { serviceItem: serviceItem, translation: translation, renderIcon: renderIcon, isSoldOut: isSoldOut, colors: colors })),
355
326
  },
356
- // {
357
- // key: "directo",
358
- // width: "12%",
359
- // condition: serviceItem?.is_direct_trip === true,
360
- // render: (
361
- // <DirectoBlock
362
- // translation={translation}
363
- // getAnimationIcon={getAnimationIcon}
364
- // colors={colors}
365
- // isSoldOut={isSoldOut}
366
- // />
367
- // ),
368
- // },
369
327
  {
370
328
  key: "pet",
371
329
  width: "20%",
@@ -376,137 +334,48 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
376
334
  {
377
335
  key: "flexible",
378
336
  width: "20%",
379
- condition: serviceItem.is_change_ticket === true,
337
+ condition: false,
380
338
  render: (React.createElement(FlexibleBlock, { translation: translation, getAnimationIcon: getAnimationIcon, colors: colors, serviceItem: serviceItem, isSoldOut: isSoldOut })),
381
339
  },
340
+ {
341
+ key: "amenities",
342
+ width: "20%",
343
+ render: (React.createElement(AmenitiesBlock, { serviceItem: serviceItem, metaData: metaData, isSoldOut: isSoldOut, colors: colors, isPeru: isPeru, getAnimationIcon: getAnimationIcon, getAmenityName: CommonService.getAmenityName, SvgAmenities: SvgAmenities })),
344
+ },
382
345
  ];
383
- const otherItems = items.filter((i) => i.key !== "pet" && i.key !== "flexible" && !!i.condition);
384
- const isItemExpanded = serviceItem.id === isExpand || isExpand === true;
385
- const grayscaleClass = isSoldOut ? "grayscale" : "";
386
- // const items = [
387
- // {
388
- // key: "rating",
389
- // width: "30%",
390
- // render: (
391
- // <RatingBlock
392
- // showRating={showRating}
393
- // serviceItem={serviceItem}
394
- // isSoldOut={isSoldOut}
395
- // colors={colors}
396
- // t={t}
397
- // translation={translation}
398
- // isPeru={isPeru}
399
- // />
400
- // ),
401
- // },
402
- // {
403
- // key: "duration",
404
- // width: "20%",
405
- // condition: serviceItem.duration,
406
- // render: (
407
- // <DurationBlock
408
- // serviceItem={serviceItem}
409
- // translation={translation}
410
- // renderIcon={renderIcon}
411
- // isSoldOut={isSoldOut}
412
- // colors={colors}
413
- // />
414
- // ),
415
- // },
416
- // {
417
- // key: "pet",
418
- // width: "20%",
419
- // condition:
420
- // serviceItem.pet_seat_info &&
421
- // Object.keys(serviceItem.pet_seat_info).length > 0,
422
- // render: (
423
- // <PetBlock
424
- // translation={translation}
425
- // getAnimationIcon={getAnimationIcon}
426
- // colors={colors}
427
- // isSoldOut={isSoldOut}
428
- // />
429
- // ),
430
- // },
431
- // {
432
- // key: "flexible",
433
- // width: "20%",
434
- // condition: false,
435
- // render: (
436
- // <FlexibleBlock
437
- // translation={translation}
438
- // getAnimationIcon={getAnimationIcon}
439
- // colors={colors}
440
- // serviceItem={serviceItem}
441
- // isSoldOut={isSoldOut}
442
- // />
443
- // ),
444
- // },
445
- // {
446
- // key: "amenities",
447
- // width: "20%",
448
- // render: (
449
- // <AmenitiesBlock
450
- // serviceItem={serviceItem}
451
- // metaData={metaData}
452
- // isSoldOut={isSoldOut}
453
- // colors={colors}
454
- // isPeru={isPeru}
455
- // getAnimationIcon={getAnimationIcon}
456
- // getAmenityName={CommonService.getAmenityName}
457
- // SvgAmenities={SvgAmenities}
458
- // />
459
- // ),
460
- // },
461
- // ];
462
- // const amenitiesItem = items.find((i) => i.key === "amenities");
463
- // const otherItems = items.filter(
464
- // (i) => i.key !== "amenities" && i.condition !== false,
465
- // );
346
+ const amenitiesItem = items.find((i) => i.key === "amenities");
347
+ const otherItems = items.filter((i) => i.key !== "amenities" && i.condition !== false);
466
348
  return (React.createElement("div", { className: `relative ${serviceItem.offer_text ? "mb-[55px]" : "mb-[10px]"} ${(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ||
467
349
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.train_type_label) === "Tren Express (Nuevo)" ||
468
350
  showTopLabel
469
351
  ? "mt-[24px]"
470
352
  : "mt-[20px]"} ` },
471
- React.createElement("div", { id: `service-card-${serviceItem.id}`, className: "bg-white mx-auto relative rounded-[10px] border border-[#ccc]" },
472
- React.createElement("div", { className: " pt-[20px]", style: {
473
- padding: coachKey ? "15px 15px 20px 15px" : "20px 15px 11px 15px",
474
- } },
475
- React.createElement("div", { className: "grid text-[#464647] w-full [grid-template-columns:14%_40%_0.5%_24%_13.5%] gap-x-[2%] items-center",
476
- // style={{ marginTop: showTopLabel ? "8px" : "" }}
477
- style: {
478
- marginTop: showTopLabel || (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) ? "8px" : "",
479
- } },
480
- React.createElement("div", { style: {
481
- display: "flex",
482
- flexDirection: "column",
483
- // gap: "5px",
484
- } },
485
- React.createElement("div", {
486
- // className="flex items-center justify-center m-[auto]"
487
- className: "" },
488
- React.createElement("img", { src: serviceItem.operator_details[0], alt: "service logo", className: `h-[30px] w-[auto] ${isSoldOut ? "grayscale" : ""}` }),
489
- isCiva ? (React.createElement("div", { className: "text-[13.33px] black-text ml-2" }, serviceItem.operator_details[2])) : null),
490
- React.createElement(RatingBlock, { showRating: showRating, serviceItem: serviceItem, isSoldOut: isSoldOut, colors: colors, t: t, translation: translation, isPeru: isPeru })),
353
+ React.createElement("div", { className: "bg-white rounded-[20px] shadow-service mx-auto relative" },
354
+ React.createElement("div", { className: "p-[15px] pt-[20px]" },
355
+ React.createElement("div", { className: "grid text-[#464647] w-full [grid-template-columns:14%_40%_0.5%_24%_13.5%] gap-x-[2%] items-center", style: { marginTop: showTopLabel ? "8px" : "" } },
356
+ React.createElement("div", { className: "flex items-center justify-center m-[auto]" },
357
+ React.createElement("div", { className: " " },
358
+ React.createElement("img", { src: serviceItem.operator_details[0], alt: "service logo", className: ` h-auto object-contain ${isSoldOut ? "grayscale" : ""}` })),
359
+ isCiva ? (React.createElement("div", { className: "text-[13.33px] black-text ml-2" }, serviceItem.operator_details[2])) : null),
491
360
  React.createElement("div", { className: `min-h-[2.5rem] grid grid-cols-[0.8fr_auto_26%_1fr] gap-x-4 items-center text-[13.33px] ${isSoldOut ? "text-[#c0c0c0]" : ""}`, style: {
492
361
  gridTemplateRows: "1fr",
493
362
  } },
494
- React.createElement("div", { className: "flex flex-col gap-[4px]" },
363
+ React.createElement("div", { className: "flex flex-col gap-[10px]" },
495
364
  orignLabel ? (React.createElement("div", { className: "w-[60px] h-[20px] flex items-center bold-text" }, orignLabel)) : (React.createElement("div", { className: "h-[20px] flex items-center" },
496
365
  React.createElement("img", { src: (_c = serviceItem.icons) === null || _c === void 0 ? void 0 : _c.origin, alt: "origin", className: `w-[18px] h-auto mr-[8px] ${isSoldOut ? "grayscale" : ""}` }))),
497
366
  !isCiva &&
498
367
  (destinationLabel ? (React.createElement("div", { className: "w-[60px] h-[20px] flex items-center bold-text" }, destinationLabel)) : (React.createElement("div", { className: "h-[20px] flex items-center" },
499
368
  React.createElement("img", { src: (_d = serviceItem.icons) === null || _d === void 0 ? void 0 : _d.destination, className: `w-[18px] h-auto mr-[8px] ${isSoldOut ? "grayscale" : ""}`, style: { opacity: isSoldOut ? 0.5 : 1 } }))))),
500
- React.createElement("div", { className: "flex flex-col gap-[4px]" },
369
+ React.createElement("div", { className: "flex flex-col gap-[10px]" },
501
370
  React.createElement(StageTooltip, { stageData: serviceItem.boarding_stages, direction: 1, terminals: busStage, serviceItem: serviceItem, metaData: metaData, colors: colors },
502
371
  React.createElement("span", { className: "cursor-pointer bold-text capitalize" }, DateService.getServiceItemDate(serviceItem.travel_date))),
503
372
  !isCiva && (React.createElement(StageTooltip, { stageData: serviceItem.boarding_stages, direction: 1, terminals: busStage, serviceItem: serviceItem, metaData: metaData, colors: colors },
504
373
  React.createElement("span", { className: "cursor-pointer bold-text capitalize" }, DateService.getServiceItemDate(serviceItem.arrival_date))))),
505
- React.createElement("div", { className: "flex flex-col gap-[4px] items-center" },
374
+ React.createElement("div", { className: "flex flex-col gap-[10px] items-center" },
506
375
  React.createElement("div", { className: "h-[20px] flex items-center justify-center" },
507
376
  React.createElement("div", null, "\u2022")),
508
377
  !isCiva && (React.createElement("div", { className: "h-[20px] flex items-center justify-center" }, removeArrivalTime ? null : serviceItem.arr_time ? (React.createElement("div", null, "\u2022")) : null))),
509
- React.createElement("div", { className: "flex flex-col gap-[4px]" },
378
+ React.createElement("div", { className: "flex flex-col gap-[10px]" },
510
379
  React.createElement(StageTooltip, { stageData: serviceItem.dropoff_stages, direction: 2, terminals: busStage, serviceItem: serviceItem, metaData: metaData, colors: colors },
511
380
  React.createElement("div", { className: "font-[900] bold-text" }, DateService.formatTime(serviceItem.dep_time))),
512
381
  !isCiva && (React.createElement(StageTooltip, { stageData: serviceItem.dropoff_stages, direction: 2, terminals: busStage, serviceItem: serviceItem, metaData: metaData, colors: colors },
@@ -522,47 +391,62 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
522
391
  margin: "auto",
523
392
  } }),
524
393
  React.createElement("div", { className: "content-center" },
525
- React.createElement(SeatSection, { seatTypes: serviceItem.seat_types, serviceItem: serviceItem, availableSeats: serviceItem.available_seats, isSoldOut: isSoldOut, priceColor: colors.priceColor, currencySign: currencySign, removeDuplicateSeats: removeDuplicateSeats, isPeru: isPeru })),
394
+ React.createElement("div", { className: `relative flex gap-[10px] text-[13.33px] justify-between min-h-[2.5rem] ${getNumberOfSeats() < 3 ? "" : ""}`, style: getNumberOfSeats() < 2
395
+ ? { alignItems: "center" }
396
+ : { alignItems: "center" } },
397
+ React.createElement("div", { className: "flex flex-col justify-between" }, getSeatNames()),
398
+ React.createElement("div", { className: "flex flex-col justify-between absolute inset-y-0 right-0 left-1/2 h-full", style: {
399
+ color: isSoldOut ? "#c0c0c0" : colors.priceColor,
400
+ top: 0,
401
+ bottom: 0,
402
+ left: "68%",
403
+ right: 0,
404
+ justifyContent: getNumberOfSeats() < 2 ? "center" : "center",
405
+ } },
406
+ React.createElement("span", { style: {
407
+ position: "absolute",
408
+ top: -5,
409
+ fontWeight: "initial",
410
+ fontSize: "12px",
411
+ left: 0,
412
+ color: "#6a6a6a",
413
+ } }, "Desde"),
414
+ getSeatPrice()))),
526
415
  React.createElement("div", null,
527
- showLastSeats ? (React.createElement("div", { className: "flex justify-end mr-[11px] ", style: {
528
- position: "absolute",
529
- top: serviceDetailsLoading ? "7px" : "5px",
530
- right: "16px",
531
- } }, (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) < 10 &&
532
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) > 0 && (React.createElement("div", { className: "text-[12px] text-[#464647] mt-1 text-center" }, "\u00A1\u00DAltimos Asientos!")))) : null,
533
- React.createElement(KuposButton, { isSoldOut: isSoldOut, isLoading: serviceDetailsLoading, buttonColor: colors.kuposButtonColor, buyLabel: translation === null || translation === void 0 ? void 0 : translation.buyButton, soldOutLabel: translation === null || translation === void 0 ? void 0 : translation.soldOutButton, soldOutIcon: renderIcon("soldOutIcon", "14px"), onClick: checkMidnight }))),
534
- React.createElement(BottomAmenities, { otherItems: otherItems, serviceItem: serviceItem, grayscaleClass: grayscaleClass, isSoldOut: isSoldOut, isItemExpanded: isItemExpanded, colors: colors, translation: translation, getAnimationIcon: getAnimationIcon, downArrowIcon: renderIcon("downArrow", "10px"), onToggleExpand: () => setIsExpand && setIsExpand(isItemExpanded ? null : serviceItem.id), isPeru: isPeru }))),
416
+ React.createElement("button", { onClick: () => (!isSoldOut ? checkMidnight() : null), disabled: serviceDetailsLoading, className: `w-full ${serviceDetailsLoading || isSoldOut ? "py-[12px]" : "py-[12px]"} text-[13.33px] font-bold text-white rounded-[10px] border-none px-[20px] flex items-center justify-center`, style: {
417
+ backgroundColor: serviceDetailsLoading || isSoldOut
418
+ ? "lightgray"
419
+ : colors.kuposButtonColor,
420
+ cursor: serviceDetailsLoading || isSoldOut
421
+ ? "not-allowed"
422
+ : "pointer",
423
+ } },
424
+ React.createElement("span", { className: "min-w-[75px] flex justify-center items-center bold-text uppercase" },
425
+ isSoldOut ? renderIcon("soldOutIcon", "14px") : null,
426
+ serviceDetailsLoading ? (React.createElement("span", { className: "loader-circle" })) : !isSoldOut ? (translation === null || translation === void 0 ? void 0 : translation.buyButton) : (translation === null || translation === void 0 ? void 0 : translation.soldOutButton))))),
427
+ showLastSeats ? (React.createElement("div", { className: "flex justify-end mr-[11px]" }, (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) < 10 &&
428
+ (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) > 0 && (React.createElement("div", { className: "text-[12px] text-[red] mt-1 text-center" }, "\u00A1 \u00DAltimos Asientos!")))) : null,
429
+ React.createElement("div", { className: "flex items-center mt-[15px] border-t border-[#eee] pt-[10px]" },
430
+ React.createElement("div", { className: "grid items-center gap-[2%] flex-1", style: {
431
+ gridTemplateColumns: "30% 18% 23% 23%",
432
+ // otherItems
433
+ // .map((i) => i.width)
434
+ // .join(" "),
435
+ } }, otherItems.map((item) => (React.createElement("div", { key: item.key, className: "flex items-center " }, item.render)))),
436
+ React.createElement("div", { className: "flex items-center ml-[12px] shrink-0 w-[130px] justify-end" }, amenitiesItem === null || amenitiesItem === void 0 ? void 0 : amenitiesItem.render)))),
535
437
  children,
536
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) && (React.createElement("div", { className: "text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[36px] pt-[50px] -z-10 rounded-b-[14px] text-[14px]", style: {
537
- backgroundColor: colors === null || colors === void 0 ? void 0 : colors.bottomStripColor,
438
+ (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) && (React.createElement("div", { className: ` text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[36px] pt-[50px] -z-10 rounded-b-[14px] text-[14px]`, style: {
439
+ backgroundColor: isSoldOut
440
+ ? colors === null || colors === void 0 ? void 0 : colors.bottomStripColor
441
+ : colors === null || colors === void 0 ? void 0 : colors.bottomStripColor,
538
442
  opacity: isSoldOut ? 0.5 : 1,
539
443
  } },
540
- React.createElement("div", { className: "flex justify-between items-center w-full" },
541
- React.createElement("div", { className: "flex items-center " },
542
- React.createElement("div", { className: "flex items-center" },
543
- React.createElement(LottiePlayer, { animationData: getAnimationIcon("bombAnimation"), width: "18px", height: "18px" }),
544
- React.createElement("div", { className: "flex items-center mt-[2px]" },
545
- React.createElement("span", { className: "bold-text ml-[6px]" },
546
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) || "",
547
- "\u00A0"),
548
- " ",
549
- "| Termina en\u00A0",
550
- React.createElement("span", { className: "bold-text text-end", ref: startCountdown, style: {
551
- fontVariantNumeric: "tabular-nums",
552
- display: "inline-block",
553
- // minWidth: "70px",
554
- } })))),
555
- React.createElement("div", { className: "flex items-center" },
556
- renderIcon("personIcon", "16px"),
557
- "\u00A0",
558
- React.createElement("span", { className: "ml-[6px]" },
559
- React.createElement("span", { className: "bold-text", ref: startViewerCount, style: { fontVariantNumeric: "tabular-nums" } }),
560
- " ",
561
- React.createElement("span", { className: "bold-text" }, "personas"),
562
- " ",
563
- React.createElement("span", null,
564
- " ",
565
- (viewersConfig === null || viewersConfig === void 0 ? void 0 : viewersConfig.label) || " están viendo este viaje")))))),
444
+ React.createElement(LottiePlayer
445
+ // animationData={serviceItem.icons.promoAnim}
446
+ , {
447
+ // animationData={serviceItem.icons.promoAnim}
448
+ animationData: getAnimationIcon("promoAnim"), width: "18px", height: "18px" }),
449
+ React.createElement("span", { className: "ml-[10px]" }, serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text))),
566
450
  React.createElement("div", { className: "absolute -top-[11px] left-0 w-full flex items-center justify-end gap-[12px] pr-[15px] z-10 " },
567
451
  showTopLabel && (React.createElement("div", { className: `flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-20`, style: {
568
452
  backgroundColor: isSoldOut ? "#ddd" : colors.ratingBottomColor,
@@ -587,7 +471,7 @@ function PeruServiceItemDesktop({ serviceItem, onBookButtonPress, colors, metaDa
587
471
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_transpordo) && (React.createElement("div", { className: `flex items-center gap-[10px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20`, style: {
588
472
  backgroundColor: isSoldOut ? "#ddd" : colors.tooltipColor,
589
473
  } },
590
- renderIcon("connectingServiceIcon", "12px"),
474
+ React.createElement(LottiePlayer, { animationData: serviceItem.icons.connectingServiceIcon, width: "14px", height: "14px" }),
591
475
  React.createElement("div", null, "Conexión"))),
592
476
  (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_direct_trip) && (React.createElement("div", { className: `flex items-center gap-[10px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20 `, style: {
593
477
  backgroundColor: isSoldOut ? "#ddd" : colors.tooltipColor,
@@ -263,7 +263,7 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
263
263
  },
264
264
  ];
265
265
  const otherItems = items.filter((i) => i.key !== "pet" && i.key !== "flexible" && !!i.condition);
266
- 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 })) : (React.createElement("div", {
266
+ 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 })) : (React.createElement("div", {
267
267
  // className={`relative ${
268
268
  // serviceItem.offer_text ? "mb-[55px]" : "mb-[10px]"
269
269
  // } mt-[14px]`}
@@ -364,7 +364,7 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
364
364
  // animationData={serviceItem.icons.priorityStageAnim}
365
365
  animationData: getAnimationIcon("priorityStageAnim"), width: "14px", height: "14px" })),
366
366
  React.createElement("div", { className: isSoldOut ? "text-white" : `text-[${colors.topLabelColor}]` }, showTopLabel))),
367
- (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_transpordo) && (React.createElement("div", { className: `flex items-center gap-[6px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20`, style: {
367
+ (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.is_transpordo) && (React.createElement("div", { className: `flex items-center gap-[10px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20`, style: {
368
368
  backgroundColor: isSoldOut ? "#ddd" : colors.tooltipColor,
369
369
  } },
370
370
  renderIcon("connectingServiceIcon", "12px"),
@@ -6,7 +6,7 @@ const RatingBlock = ({ showRating, serviceItem, isSoldOut, colors, t, translatio
6
6
  marginLeft: showRating ? "6px" : "0",
7
7
  color: isSoldOut ? "#c0c0c0" : "#464647",
8
8
  } },
9
- React.createElement("span", { className: "block max-w-[120px] overflow-hidden text-ellipsis whitespace-nowrap cursor-pointer text-[12px]" }, serviceItem.operator_details[2]),
9
+ React.createElement("span", { className: "block max-w-[120px] overflow-hidden whitespace-nowrap cursor-pointer" }, serviceItem.operator_details[2]),
10
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-nowrap z-10 mt-2.5 w-max text-center shadow-service text-[12px]", style: { backgroundColor: colors.bottomStripColor, zIndex: "300" } },
11
11
  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: colors.bottomStripColor } }),
12
12
  serviceItem.operator_details[2]))));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kupos-ui-components-lib",
3
- "version": "9.2.9",
3
+ "version": "9.2.10",
4
4
  "description": "A reusable UI components package",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -34,53 +34,15 @@ import linatalDirectoAnimation from "../../assets/images/anims/service_list/dire
34
34
  import linatalPriorityStageAnimation from "../../assets/images/anims/service_list/priority_stage.json";
35
35
  import linatalPetFriendlyAnimation from "../../assets/images/anims/service_list/pet_friendly.json";
36
36
  import linatalLocationAnimation from "../../assets/images/anims/service_list/location.json";
37
-
38
- import bombAnimation from "../../assets/images/anims/service_list/bomb.json";
39
-
40
37
  import StageTooltip from "../../ui/StagesTooltip";
41
38
  import RatingBlock from "../../ui/RatingBlock";
42
39
  import DurationBlock from "../../ui/DurationBlock";
43
40
  import PetBlock from "../../ui/PetBlock";
44
41
  import FlexibleBlock from "../../ui/FlexibleBlock";
45
42
  import AmenitiesBlock from "../../ui/AmenitiesBlock";
46
- import SeatSection from "../../ui/SeatSection/SeatSection";
47
- import KuposButton from "../../ui/KuposButton/KuposButton";
48
- import BottomAmenities from "../../ui/BottomAmenities/BottomAmenities";
49
43
 
50
44
  const SEAT_EXCEPTIONS = ["Asiento mascota"];
51
45
 
52
- const ANIMATION_MAP: Record<string, Record<string, any>> = {
53
- promoAnim: {
54
- kupos: promoAnimation,
55
- },
56
- locationAnim: {
57
- kupos: locationAnimation,
58
- pullman: pullmanLocationAnimation,
59
- opsites: opsitesLocationAnimation,
60
- },
61
- directoAnim: {
62
- kupos: directoAnimation,
63
- },
64
- petFriendlyAnim: {
65
- kupos: petFriendlyAnimation,
66
- pullman: pullmanPetFriendlyAnimation,
67
- opsites: opsitesPetFriendlyAnimation,
68
- },
69
- priorityStageAnim: {
70
- kupos: priorityStageAnimation,
71
- pullman: pullmanPriorityStageAnimation,
72
- opsites: opsitesPriorityStageAnimation,
73
- },
74
- flexibleIcon: {
75
- kupos: flexibleAnimation,
76
- pullman: pullmanFlexibleAnimation,
77
- opsites: opsitesFlexibleAnimation,
78
- },
79
- bombAnimation: {
80
- kupos: bombAnimation,
81
- },
82
- };
83
-
84
46
  function PeruServiceItemDesktop({
85
47
  serviceItem,
86
48
  onBookButtonPress,
@@ -105,39 +67,52 @@ function PeruServiceItemDesktop({
105
67
  isPeru,
106
68
  siteType,
107
69
  isAllinBus,
108
- viewersConfig,
109
- isExpand,
110
- setIsExpand,
111
- coachKey,
112
70
  t = (key: string) => key,
113
71
  }: ServiceItemProps & { currencySign?: string }): React.ReactElement {
114
- const startViewerCount = (node: HTMLSpanElement | null) => {
115
- if (!node || !viewersConfig) return;
116
-
117
- const prevId = node.dataset.viewerId;
118
- if (prevId) clearInterval(Number(prevId));
119
-
120
- const { min, max, interval = 5000 } = viewersConfig;
121
- const clamp = (v: number) => Math.min(max, Math.max(min, v));
122
- const initialValue = Math.floor(Math.random() * (max - min + 1)) + min;
123
-
124
- node.textContent = String(initialValue);
125
-
126
- const id = setInterval(() => {
127
- const current = Number(node.textContent) || initialValue;
128
- const delta = Math.ceil(current * 0.2);
129
- const next =
130
- current + Math.floor(Math.random() * (2 * delta + 1)) - delta;
131
- node.textContent = String(clamp(Math.round(next)));
132
- }, interval);
133
-
134
- node.dataset.viewerId = String(id);
72
+ const animationMap: Record<string, Record<string, any>> = {
73
+ promoAnim: {
74
+ kupos: promoAnimation,
75
+ pullman: pullmanPromoAnimation,
76
+ opsites: opsitesPromoAnimation,
77
+ linatal: linatalPromoAnimation,
78
+ },
79
+ locationAnim: {
80
+ kupos: locationAnimation,
81
+ pullman: pullmanLocationAnimation,
82
+ opsites: opsitesLocationAnimation,
83
+ linatal: linatalLocationAnimation,
84
+ },
85
+ directoAnim: {
86
+ kupos: directoAnimation,
87
+ pullman: pullmanDirectoAnimation,
88
+ opsites: opsitesDirectoAnimation,
89
+ linatal: linatalDirectoAnimation,
90
+ },
91
+ petFriendlyAnim: {
92
+ kupos: petFriendlyAnimation,
93
+ pullman: pullmanPetFriendlyAnimation,
94
+ opsites: opsitesPetFriendlyAnimation,
95
+ linatal: linatalPetFriendlyAnimation,
96
+ },
97
+ priorityStageAnim: {
98
+ kupos: priorityStageAnimation,
99
+ pullman: pullmanPriorityStageAnimation,
100
+ opsites: opsitesPriorityStageAnimation,
101
+ linatal: linatalPriorityStageAnimation,
102
+ },
103
+ flexibleIcon: {
104
+ kupos: flexibleAnimation,
105
+ pullman: pullmanFlexibleAnimation,
106
+ opsites: opsitesFlexibleAnimation,
107
+ linatal: linatalFlexibleAnimation,
108
+ },
135
109
  };
136
110
 
137
111
  const getAnimationIcon = (icon: string) => {
138
- const animation = ANIMATION_MAP[icon];
112
+ const animation = animationMap[icon];
139
113
  if (!animation) return null;
140
- return animation[siteType] ?? animation.kupos;
114
+ const currentSiteType = siteType || "kupos";
115
+ return animation[currentSiteType];
141
116
  };
142
117
  const SvgAmenities = ({
143
118
  moreAnemities,
@@ -475,56 +450,26 @@ function PeruServiceItemDesktop({
475
450
  ? extractStage(serviceItem.stage_details_arr, 1)
476
451
  : null;
477
452
 
478
- const countdownSeconds = 599;
479
-
480
- const startCountdown = (node: HTMLSpanElement | null) => {
481
- if (!node) return;
482
-
483
- const prevId = node.dataset.countdownId;
484
- if (prevId) clearInterval(Number(prevId));
485
-
486
- let remaining = countdownSeconds;
487
-
488
- const formatTime = (totalSecs: number) => {
489
- const m = Math.floor(totalSecs / 60);
490
- const s = totalSecs % 60;
491
- return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
492
- };
493
-
494
- node.textContent = formatTime(remaining);
495
-
496
- const id = setInterval(() => {
497
- remaining -= 1;
498
- if (remaining <= 0) {
499
- remaining = countdownSeconds;
500
- }
501
- node.textContent = formatTime(remaining);
502
- }, 1000);
503
-
504
- node.dataset.countdownId = String(id);
505
- };
506
-
507
453
  const items = [
508
454
  {
509
- key: "amenities",
510
- width: "20%",
511
- condition: true,
455
+ key: "rating",
456
+ width: "30%",
512
457
  render: (
513
- <AmenitiesBlock
458
+ <RatingBlock
459
+ showRating={showRating}
514
460
  serviceItem={serviceItem}
515
- metaData={metaData}
516
461
  isSoldOut={isSoldOut}
517
462
  colors={colors}
518
- getAnimationIcon={getAnimationIcon}
519
- getAmenityName={CommonService.getAmenityName}
520
- SvgAmenities={SvgAmenities}
463
+ t={t}
464
+ translation={translation}
521
465
  isPeru={isPeru}
522
466
  />
523
467
  ),
524
468
  },
469
+
525
470
  {
526
471
  key: "duration",
527
- width: "12%",
472
+ width: "20%",
528
473
  condition: serviceItem.duration,
529
474
  render: (
530
475
  <DurationBlock
@@ -537,20 +482,6 @@ function PeruServiceItemDesktop({
537
482
  ),
538
483
  },
539
484
 
540
- // {
541
- // key: "directo",
542
- // width: "12%",
543
- // condition: serviceItem?.is_direct_trip === true,
544
- // render: (
545
- // <DirectoBlock
546
- // translation={translation}
547
- // getAnimationIcon={getAnimationIcon}
548
- // colors={colors}
549
- // isSoldOut={isSoldOut}
550
- // />
551
- // ),
552
- // },
553
-
554
485
  {
555
486
  key: "pet",
556
487
  width: "20%",
@@ -570,7 +501,7 @@ function PeruServiceItemDesktop({
570
501
  {
571
502
  key: "flexible",
572
503
  width: "20%",
573
- condition: serviceItem.is_change_ticket === true,
504
+ condition: false,
574
505
  render: (
575
506
  <FlexibleBlock
576
507
  translation={translation}
@@ -581,101 +512,30 @@ function PeruServiceItemDesktop({
581
512
  />
582
513
  ),
583
514
  },
515
+
516
+ {
517
+ key: "amenities",
518
+ width: "20%",
519
+ render: (
520
+ <AmenitiesBlock
521
+ serviceItem={serviceItem}
522
+ metaData={metaData}
523
+ isSoldOut={isSoldOut}
524
+ colors={colors}
525
+ isPeru={isPeru}
526
+ getAnimationIcon={getAnimationIcon}
527
+ getAmenityName={CommonService.getAmenityName}
528
+ SvgAmenities={SvgAmenities}
529
+ />
530
+ ),
531
+ },
584
532
  ];
585
533
 
534
+ const amenitiesItem = items.find((i) => i.key === "amenities");
586
535
  const otherItems = items.filter(
587
- (i) => i.key !== "pet" && i.key !== "flexible" && !!i.condition,
536
+ (i) => i.key !== "amenities" && i.condition !== false,
588
537
  );
589
538
 
590
- const isItemExpanded = serviceItem.id === isExpand || isExpand === true;
591
- const grayscaleClass = isSoldOut ? "grayscale" : "";
592
-
593
- // const items = [
594
- // {
595
- // key: "rating",
596
- // width: "30%",
597
- // render: (
598
- // <RatingBlock
599
- // showRating={showRating}
600
- // serviceItem={serviceItem}
601
- // isSoldOut={isSoldOut}
602
- // colors={colors}
603
- // t={t}
604
- // translation={translation}
605
- // isPeru={isPeru}
606
- // />
607
- // ),
608
- // },
609
-
610
- // {
611
- // key: "duration",
612
- // width: "20%",
613
- // condition: serviceItem.duration,
614
- // render: (
615
- // <DurationBlock
616
- // serviceItem={serviceItem}
617
- // translation={translation}
618
- // renderIcon={renderIcon}
619
- // isSoldOut={isSoldOut}
620
- // colors={colors}
621
- // />
622
- // ),
623
- // },
624
-
625
- // {
626
- // key: "pet",
627
- // width: "20%",
628
- // condition:
629
- // serviceItem.pet_seat_info &&
630
- // Object.keys(serviceItem.pet_seat_info).length > 0,
631
- // render: (
632
- // <PetBlock
633
- // translation={translation}
634
- // getAnimationIcon={getAnimationIcon}
635
- // colors={colors}
636
- // isSoldOut={isSoldOut}
637
- // />
638
- // ),
639
- // },
640
-
641
- // {
642
- // key: "flexible",
643
- // width: "20%",
644
- // condition: false,
645
- // render: (
646
- // <FlexibleBlock
647
- // translation={translation}
648
- // getAnimationIcon={getAnimationIcon}
649
- // colors={colors}
650
- // serviceItem={serviceItem}
651
- // isSoldOut={isSoldOut}
652
- // />
653
- // ),
654
- // },
655
-
656
- // {
657
- // key: "amenities",
658
- // width: "20%",
659
- // render: (
660
- // <AmenitiesBlock
661
- // serviceItem={serviceItem}
662
- // metaData={metaData}
663
- // isSoldOut={isSoldOut}
664
- // colors={colors}
665
- // isPeru={isPeru}
666
- // getAnimationIcon={getAnimationIcon}
667
- // getAmenityName={CommonService.getAmenityName}
668
- // SvgAmenities={SvgAmenities}
669
- // />
670
- // ),
671
- // },
672
- // ];
673
-
674
- // const amenitiesItem = items.find((i) => i.key === "amenities");
675
- // const otherItems = items.filter(
676
- // (i) => i.key !== "amenities" && i.condition !== false,
677
- // );
678
-
679
539
  return (
680
540
  <div
681
541
  className={`relative ${
@@ -689,15 +549,9 @@ function PeruServiceItemDesktop({
689
549
  } `}
690
550
  >
691
551
  <div
692
- id={`service-card-${serviceItem.id}`}
693
- className="bg-white mx-auto relative rounded-[10px] border border-[#ccc]"
552
+ className={"bg-white rounded-[20px] shadow-service mx-auto relative"}
694
553
  >
695
- <div
696
- className=" pt-[20px]"
697
- style={{
698
- padding: coachKey ? "15px 15px 20px 15px" : "20px 15px 11px 15px",
699
- }}
700
- >
554
+ <div className="p-[15px] pt-[20px]">
701
555
  {/* Header with operator info and favorite */}
702
556
  {/* <div className="flex justify-between items-center mb-[15px]">
703
557
  <div className="flex items-center justify-between w-[250px]">
@@ -725,48 +579,10 @@ function PeruServiceItemDesktop({
725
579
  {/* <div className="grid grid-cols-[1.5fr_1fr_auto] gap-[3rem] sm:gap-[4rem] md:gap-[5rem] lg:gap-[6rem] xl:gap-[5rem] 2xl:gap-[7rem] text-[#464647]"> */}
726
580
  <div
727
581
  className="grid text-[#464647] w-full [grid-template-columns:14%_40%_0.5%_24%_13.5%] gap-x-[2%] items-center"
728
- // style={{ marginTop: showTopLabel ? "8px" : "" }}
729
- style={{
730
- marginTop:
731
- showTopLabel || serviceItem?.is_direct_trip ? "8px" : "",
732
- }}
582
+ style={{ marginTop: showTopLabel ? "8px" : "" }}
733
583
  >
734
584
  {/* OPERATOR LOGO */}
735
- <div
736
- style={{
737
- display: "flex",
738
- flexDirection: "column",
739
- // gap: "5px",
740
- }}
741
- >
742
- <div
743
- // className="flex items-center justify-center m-[auto]"
744
- className=""
745
- >
746
- <img
747
- src={serviceItem.operator_details[0]}
748
- alt="service logo"
749
- className={`h-[30px] w-[auto] ${
750
- isSoldOut ? "grayscale" : ""
751
- }`}
752
- />
753
- {isCiva ? (
754
- <div className="text-[13.33px] black-text ml-2">
755
- {serviceItem.operator_details[2]}
756
- </div>
757
- ) : null}
758
- </div>
759
- <RatingBlock
760
- showRating={showRating}
761
- serviceItem={serviceItem}
762
- isSoldOut={isSoldOut}
763
- colors={colors}
764
- t={t}
765
- translation={translation}
766
- isPeru={isPeru}
767
- />
768
- </div>
769
- {/* <div className="flex items-center justify-center m-[auto]">
585
+ <div className="flex items-center justify-center m-[auto]">
770
586
  <div className=" ">
771
587
  <img
772
588
  src={serviceItem.operator_details[0]}
@@ -781,7 +597,7 @@ function PeruServiceItemDesktop({
781
597
  {serviceItem.operator_details[2]}
782
598
  </div>
783
599
  ) : null}
784
- </div> */}
600
+ </div>
785
601
 
786
602
  {/* DATE AND TIME - Grid Layout */}
787
603
  <div
@@ -793,7 +609,7 @@ function PeruServiceItemDesktop({
793
609
  }}
794
610
  >
795
611
  {/* ICONS COLUMN */}
796
- <div className="flex flex-col gap-[4px]">
612
+ <div className="flex flex-col gap-[10px]">
797
613
  {/* Origin Icon */}
798
614
  {orignLabel ? (
799
615
  <div className="w-[60px] h-[20px] flex items-center bold-text">
@@ -831,7 +647,7 @@ function PeruServiceItemDesktop({
831
647
  </div>
832
648
 
833
649
  {/* DATES COLUMN */}
834
- <div className="flex flex-col gap-[4px]">
650
+ <div className="flex flex-col gap-[10px]">
835
651
  {/* Departure Date */}
836
652
  <StageTooltip
837
653
  stageData={serviceItem.boarding_stages}
@@ -864,7 +680,7 @@ function PeruServiceItemDesktop({
864
680
  </div>
865
681
 
866
682
  {/* DOTS COLUMN */}
867
- <div className="flex flex-col gap-[4px] items-center">
683
+ <div className="flex flex-col gap-[10px] items-center">
868
684
  {/* Departure Dot */}
869
685
  <div className="h-[20px] flex items-center justify-center">
870
686
  <div>•</div>
@@ -881,7 +697,7 @@ function PeruServiceItemDesktop({
881
697
  </div>
882
698
 
883
699
  {/* TIMES COLUMN */}
884
- <div className="flex flex-col gap-[4px]">
700
+ <div className="flex flex-col gap-[10px]">
885
701
  {/* Departure Time */}
886
702
  <StageTooltip
887
703
  stageData={serviceItem.dropoff_stages}
@@ -927,18 +743,6 @@ function PeruServiceItemDesktop({
927
743
  ></div>
928
744
  {/* SEATS */}
929
745
  <div className="content-center">
930
- <SeatSection
931
- seatTypes={serviceItem.seat_types}
932
- serviceItem={serviceItem}
933
- availableSeats={serviceItem.available_seats}
934
- isSoldOut={isSoldOut}
935
- priceColor={colors.priceColor}
936
- currencySign={currencySign}
937
- removeDuplicateSeats={removeDuplicateSeats}
938
- isPeru={isPeru}
939
- />
940
- </div>
941
- {/* <div className="content-center">
942
746
  <div
943
747
  className={`relative flex gap-[10px] text-[13.33px] justify-between min-h-[2.5rem] ${
944
748
  getNumberOfSeats() < 3 ? "" : ""
@@ -980,38 +784,10 @@ function PeruServiceItemDesktop({
980
784
  {getSeatPrice()}
981
785
  </div>
982
786
  </div>
983
- </div> */}
787
+ </div>
984
788
 
985
789
  {/* BUTTON */}
986
790
  <div>
987
- {showLastSeats ? (
988
- <div
989
- className="flex justify-end mr-[11px] "
990
- style={{
991
- position: "absolute",
992
- top: serviceDetailsLoading ? "7px" : "5px",
993
- right: "16px",
994
- }}
995
- >
996
- {serviceItem?.available_seats < 10 &&
997
- serviceItem?.available_seats > 0 && (
998
- <div className="text-[12px] text-[#464647] mt-1 text-center">
999
- ¡Últimos Asientos!
1000
- </div>
1001
- )}
1002
- </div>
1003
- ) : null}
1004
- <KuposButton
1005
- isSoldOut={isSoldOut}
1006
- isLoading={serviceDetailsLoading}
1007
- buttonColor={colors.kuposButtonColor}
1008
- buyLabel={translation?.buyButton}
1009
- soldOutLabel={translation?.soldOutButton}
1010
- soldOutIcon={renderIcon("soldOutIcon", "14px")}
1011
- onClick={checkMidnight}
1012
- />
1013
- </div>
1014
- {/* <div>
1015
791
  <button
1016
792
  onClick={() => (!isSoldOut ? checkMidnight() : null)}
1017
793
  disabled={serviceDetailsLoading}
@@ -1041,24 +817,9 @@ function PeruServiceItemDesktop({
1041
817
  )}
1042
818
  </span>
1043
819
  </button>
1044
- </div> */}
820
+ </div>
1045
821
  </div>
1046
- <BottomAmenities
1047
- otherItems={otherItems}
1048
- serviceItem={serviceItem}
1049
- grayscaleClass={grayscaleClass}
1050
- isSoldOut={isSoldOut}
1051
- isItemExpanded={isItemExpanded}
1052
- colors={colors}
1053
- translation={translation}
1054
- getAnimationIcon={getAnimationIcon}
1055
- downArrowIcon={renderIcon("downArrow", "10px")}
1056
- onToggleExpand={() =>
1057
- setIsExpand && setIsExpand(isItemExpanded ? null : serviceItem.id)
1058
- }
1059
- isPeru={isPeru}
1060
- />
1061
- {/* {showLastSeats ? (
822
+ {showLastSeats ? (
1062
823
  <div className="flex justify-end mr-[11px]">
1063
824
  {serviceItem?.available_seats < 10 &&
1064
825
  serviceItem?.available_seats > 0 && (
@@ -1067,13 +828,18 @@ function PeruServiceItemDesktop({
1067
828
  </div>
1068
829
  )}
1069
830
  </div>
1070
- ) : null} */}
1071
- {/*
831
+ ) : null}
832
+
1072
833
  <div className="flex items-center mt-[15px] border-t border-[#eee] pt-[10px]">
834
+ {/* 🔹 LEFT SIDE (GRID ITEMS) */}
1073
835
  <div
1074
836
  className="grid items-center gap-[2%] flex-1"
1075
837
  style={{
1076
838
  gridTemplateColumns: "30% 18% 23% 23%",
839
+
840
+ // otherItems
841
+ // .map((i) => i.width)
842
+ // .join(" "),
1077
843
  }}
1078
844
  >
1079
845
  {otherItems.map((item) => (
@@ -1083,16 +849,17 @@ function PeruServiceItemDesktop({
1083
849
  ))}
1084
850
  </div>
1085
851
 
852
+ {/* 🔹 RIGHT SIDE (ALWAYS END) */}
1086
853
  <div className="flex items-center ml-[12px] shrink-0 w-[130px] justify-end">
1087
854
  {amenitiesItem?.render}
1088
855
  </div>
1089
- </div> */}
856
+ </div>
1090
857
  </div>
1091
858
  </div>
1092
859
 
1093
860
  {children}
1094
861
  {/* Bottom discount banner */}
1095
- {/* {serviceItem?.offer_text && (
862
+ {serviceItem?.offer_text && (
1096
863
  <div
1097
864
  className={` text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[36px] pt-[50px] -z-10 rounded-b-[14px] text-[14px]`}
1098
865
  style={{
@@ -1110,84 +877,6 @@ function PeruServiceItemDesktop({
1110
877
  />
1111
878
  <span className="ml-[10px]">{serviceItem?.offer_text}</span>
1112
879
  </div>
1113
- )} */}
1114
-
1115
- {serviceItem?.offer_text && (
1116
- <div
1117
- className="text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[36px] pt-[50px] -z-10 rounded-b-[14px] text-[14px]"
1118
- style={{
1119
- backgroundColor: colors?.bottomStripColor,
1120
- opacity: isSoldOut ? 0.5 : 1,
1121
- }}
1122
- >
1123
- {/* <div className="flex justify-between items-center w-full">
1124
- <div className="flex items-center">
1125
- <LottiePlayer
1126
- animationData={getAnimationIcon("bombAnimation")}
1127
- width="18px"
1128
- height="18px"
1129
- />
1130
- <span className="bold-text ml-[8px]">
1131
- {" "}
1132
- {serviceItem?.offer_text || ""}
1133
- </span>
1134
- </div>
1135
- <div>
1136
- Termina en&nbsp;
1137
- <span
1138
- className="bold-text text-end"
1139
- ref={startCountdown}
1140
- style={{
1141
- fontVariantNumeric: "tabular-nums",
1142
- display: "inline-block",
1143
- // minWidth: "70px",
1144
- }}
1145
- />
1146
- </div>
1147
- </div> */}
1148
- <div className="flex justify-between items-center w-full">
1149
- <div className="flex items-center ">
1150
- <div className="flex items-center">
1151
- <LottiePlayer
1152
- animationData={getAnimationIcon("bombAnimation")}
1153
- width="18px"
1154
- height="18px"
1155
- />
1156
- <div className="flex items-center mt-[2px]">
1157
- <span className="bold-text ml-[6px]">
1158
- {serviceItem?.offer_text || ""}&nbsp;
1159
- </span>{" "}
1160
- | Termina en&nbsp;
1161
- <span
1162
- className="bold-text text-end"
1163
- ref={startCountdown}
1164
- style={{
1165
- fontVariantNumeric: "tabular-nums",
1166
- display: "inline-block",
1167
- // minWidth: "70px",
1168
- }}
1169
- />
1170
- </div>
1171
- </div>
1172
- </div>
1173
- <div className="flex items-center">
1174
- {renderIcon("personIcon", "16px")}
1175
- &nbsp;
1176
- <span className="ml-[6px]">
1177
- <span
1178
- className="bold-text"
1179
- ref={startViewerCount}
1180
- style={{ fontVariantNumeric: "tabular-nums" }}
1181
- />{" "}
1182
- <span className="bold-text">personas</span>{" "}
1183
- <span>
1184
- {" "}
1185
- {viewersConfig?.label || " están viendo este viaje"}
1186
- </span>
1187
- </span>
1188
- </div>
1189
- </div>
1190
- </div>
1191
880
  )}
1192
881
 
1193
882
  <div className="absolute -top-[11px] left-0 w-full flex items-center justify-end gap-[12px] pr-[15px] z-10 ">
@@ -1272,12 +961,11 @@ function PeruServiceItemDesktop({
1272
961
  backgroundColor: isSoldOut ? "#ddd" : colors.tooltipColor,
1273
962
  }}
1274
963
  >
1275
- {renderIcon("connectingServiceIcon", "12px")}
1276
- {/* <LottiePlayer
964
+ <LottiePlayer
1277
965
  animationData={serviceItem.icons.connectingServiceIcon}
1278
966
  width="14px"
1279
967
  height="14px"
1280
- /> */}
968
+ />
1281
969
  <div>{"Conexión"}</div>
1282
970
  </div>
1283
971
  )}
@@ -429,7 +429,6 @@ function ServiceItemPB({
429
429
  isPeru={isPeru}
430
430
  siteType={siteType}
431
431
  isAllinBus={isAllinBus}
432
- viewersConfig={viewersConfig}
433
432
  />
434
433
  ) : (
435
434
  <div
@@ -752,7 +751,7 @@ function ServiceItemPB({
752
751
  )}
753
752
  {serviceItem?.is_transpordo && (
754
753
  <div
755
- className={`flex items-center gap-[6px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20`}
754
+ className={`flex items-center gap-[10px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20`}
756
755
  style={{
757
756
  backgroundColor: isSoldOut ? "#ddd" : colors.tooltipColor,
758
757
  }}
@@ -32,7 +32,7 @@ const RatingBlock = ({
32
32
  color: isSoldOut ? "#c0c0c0" : "#464647",
33
33
  }}
34
34
  >
35
- <span className="block max-w-[120px] overflow-hidden text-ellipsis whitespace-nowrap cursor-pointer text-[12px]">
35
+ <span className="block max-w-[120px] overflow-hidden whitespace-nowrap cursor-pointer">
36
36
  {serviceItem.operator_details[2]}
37
37
  </span>
38
38
  <div