kupos-ui-components-lib 9.0.6 → 9.0.8
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.
- package/dist/components/ServiceItem/ServiceItemDesktop.js +32 -69
- package/dist/styles.css +13 -3
- package/dist/ui/BottomAmenities/BottomAmenities.js +3 -2
- package/dist/ui/DateTimeSection/DateTimeSection.d.ts +28 -0
- package/dist/ui/DateTimeSection/DateTimeSection.js +58 -0
- package/dist/ui/DirectoBlock.d.ts +8 -0
- package/dist/ui/DirectoBlock.js +11 -0
- package/dist/ui/ExpendedDropDown/ExpandedDropdown.d.ts +1 -0
- package/dist/ui/ExpendedDropDown/ExpandedDropdown.js +28 -18
- package/dist/ui/SeatSection/SeatSection.js +1 -1
- package/dist/ui/TopAmenities/PromoCountdown.d.ts +18 -0
- package/dist/ui/TopAmenities/PromoCountdown.js +55 -0
- package/dist/ui/TopAmenities/TopAmenities.d.ts +4 -1
- package/dist/ui/TopAmenities/TopAmenities.js +31 -4
- package/dist/utils/CommonService.d.ts +1 -1
- package/package.json +2 -1
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +66 -197
- package/src/ui/BottomAmenities/BottomAmenities.tsx +3 -2
- package/src/ui/DateTimeSection/DateTimeSection.tsx +207 -0
- package/src/ui/DirectoBlock.tsx +31 -0
- package/src/ui/ExpendedDropDown/ExpandedDropdown.tsx +35 -5
- package/src/ui/SeatSection/SeatSection.tsx +1 -1
- package/src/ui/TopAmenities/TopAmenities.tsx +37 -3
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ServiceItemProps } from "./types";
|
|
3
|
-
import DateService from "../../utils/DateService";
|
|
4
3
|
import CommonService from "../../utils/CommonService";
|
|
5
4
|
import ModalEventManager from "../../utils/ModalEventManager";
|
|
6
5
|
import InternationalServicePopupBody from "../InternationalServicePopupBody";
|
|
@@ -28,14 +27,15 @@ import bombAnimation from "../../assets/images/anims/service_list/bomb.json";
|
|
|
28
27
|
|
|
29
28
|
import RatingBlock from "../../ui/RatingBlock";
|
|
30
29
|
import DurationBlock from "../../ui/DurationBlock";
|
|
30
|
+
import DirectoBlock from "../../ui/DirectoBlock";
|
|
31
31
|
import PetBlock from "../../ui/PetBlock";
|
|
32
32
|
import FlexibleBlock from "../../ui/FlexibleBlock";
|
|
33
33
|
import AmenitiesBlock from "../../ui/AmenitiesBlock";
|
|
34
|
-
import StageTooltip from "../../ui/StagesTooltip";
|
|
35
34
|
import KuposButton from "../../ui/KuposButton/KuposButton";
|
|
36
35
|
import TopAmenities from "../../ui/TopAmenities/TopAmenities";
|
|
37
36
|
import BottomAmenities from "../../ui/BottomAmenities/BottomAmenities";
|
|
38
37
|
import SeatSection from "../../ui/SeatSection/SeatSection";
|
|
38
|
+
import DateTimeSection from "../../ui/DateTimeSection/DateTimeSection";
|
|
39
39
|
|
|
40
40
|
const SEAT_EXCEPTIONS = ["Asiento mascota"];
|
|
41
41
|
|
|
@@ -71,22 +71,6 @@ const ANIMATION_MAP: Record<string, Record<string, any>> = {
|
|
|
71
71
|
},
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
const convertTo24Hour = (depTime: string): string => {
|
|
75
|
-
const hasAM = depTime.includes("AM");
|
|
76
|
-
const hasPM = depTime.includes("PM");
|
|
77
|
-
const [timePart] = depTime.split(/AM|PM/).map((part) => part.trim());
|
|
78
|
-
const [hour, minute] = timePart.split(":").map(Number);
|
|
79
|
-
const pad = (n: number) => (n < 10 ? "0" + n : String(n));
|
|
80
|
-
|
|
81
|
-
if (hasAM) {
|
|
82
|
-
return `${pad(hour === 12 ? 0 : hour)}:${pad(minute)}`;
|
|
83
|
-
}
|
|
84
|
-
if (hasPM) {
|
|
85
|
-
return `${hour === 12 ? hour : hour + 12}:${pad(minute)}`;
|
|
86
|
-
}
|
|
87
|
-
return timePart;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
74
|
function ServiceItemPB({
|
|
91
75
|
serviceItem,
|
|
92
76
|
onBookButtonPress,
|
|
@@ -282,10 +266,7 @@ function ServiceItemPB({
|
|
|
282
266
|
onBookButtonPress();
|
|
283
267
|
};
|
|
284
268
|
|
|
285
|
-
const
|
|
286
|
-
const hasAM = depTime.includes("AM");
|
|
287
|
-
const hasPM = depTime.includes("PM");
|
|
288
|
-
const cleanedDepTime = convertTo24Hour(depTime);
|
|
269
|
+
const countdownSeconds = 7830;
|
|
289
270
|
|
|
290
271
|
const items = [
|
|
291
272
|
{
|
|
@@ -323,16 +304,14 @@ function ServiceItemPB({
|
|
|
323
304
|
{
|
|
324
305
|
key: "directo",
|
|
325
306
|
width: "12%",
|
|
326
|
-
condition: serviceItem?.is_direct_trip,
|
|
307
|
+
condition: !serviceItem?.is_direct_trip,
|
|
327
308
|
render: (
|
|
328
|
-
<
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
<div>{translation?.directService}</div>
|
|
335
|
-
</div>
|
|
309
|
+
<DirectoBlock
|
|
310
|
+
translation={translation}
|
|
311
|
+
getAnimationIcon={getAnimationIcon}
|
|
312
|
+
colors={colors}
|
|
313
|
+
isSoldOut={isSoldOut}
|
|
314
|
+
/>
|
|
336
315
|
),
|
|
337
316
|
},
|
|
338
317
|
|
|
@@ -416,18 +395,31 @@ function ServiceItemPB({
|
|
|
416
395
|
buttonColor={colors.kuposButtonColor}
|
|
417
396
|
boardingIcon={renderIcon("whiteBoardingIcon", "14px")}
|
|
418
397
|
getAnimationIcon={getAnimationIcon}
|
|
398
|
+
countdownSeconds={countdownSeconds}
|
|
399
|
+
onCountdownEnd={() => {
|
|
400
|
+
const cardEl = document.getElementById(
|
|
401
|
+
`service-card-${serviceItem.id}`,
|
|
402
|
+
);
|
|
403
|
+
if (!cardEl) return;
|
|
404
|
+
cardEl.style.border = "1px solid #ccc";
|
|
405
|
+
if (!showTopLabel) {
|
|
406
|
+
cardEl.style.borderRadius = "10px";
|
|
407
|
+
}
|
|
408
|
+
}}
|
|
419
409
|
/>
|
|
420
410
|
<div
|
|
421
|
-
|
|
411
|
+
id={`service-card-${serviceItem.id}`}
|
|
412
|
+
className="bg-white mx-auto relative "
|
|
422
413
|
style={{
|
|
423
|
-
border:
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
borderRadius:
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
414
|
+
border:
|
|
415
|
+
countdownSeconds > 0
|
|
416
|
+
? `1px solid ${colors.priceColor}`
|
|
417
|
+
: "1px solid #ccc",
|
|
418
|
+
borderRadius: showTopLabel
|
|
419
|
+
? "10px 0 10px 10px"
|
|
420
|
+
: countdownSeconds > 0
|
|
421
|
+
? "10px 0 10px 10px"
|
|
422
|
+
: "10px",
|
|
431
423
|
}}
|
|
432
424
|
>
|
|
433
425
|
<div
|
|
@@ -480,153 +472,18 @@ function ServiceItemPB({
|
|
|
480
472
|
</div>
|
|
481
473
|
|
|
482
474
|
{/* DATE AND TIME - Grid Layout */}
|
|
483
|
-
<
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
{
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
<div className="w-[60px] h-[20px] flex items-center">
|
|
496
|
-
{orignLabel}
|
|
497
|
-
</div>
|
|
498
|
-
) : (
|
|
499
|
-
<div className="h-[20px] flex items-center">
|
|
500
|
-
<img
|
|
501
|
-
src={serviceItem.icons?.origin}
|
|
502
|
-
alt="origin"
|
|
503
|
-
className={`w-[16px] h-auto mr-[8px] ${
|
|
504
|
-
isSoldOut ? "grayscale" : ""
|
|
505
|
-
}`}
|
|
506
|
-
/>
|
|
507
|
-
</div>
|
|
508
|
-
)}
|
|
509
|
-
|
|
510
|
-
{/* Destination Icon */}
|
|
511
|
-
{!isCiva &&
|
|
512
|
-
(destinationLabel ? (
|
|
513
|
-
<div className="w-[60px] h-[20px] flex items-center">
|
|
514
|
-
{destinationLabel}
|
|
515
|
-
</div>
|
|
516
|
-
) : (
|
|
517
|
-
<div className="h-[20px] flex items-center">
|
|
518
|
-
<img
|
|
519
|
-
src={serviceItem.icons?.destination}
|
|
520
|
-
className={`w-[16px] h-auto mr-[8px] ${
|
|
521
|
-
isSoldOut ? "grayscale" : ""
|
|
522
|
-
}`}
|
|
523
|
-
style={{ opacity: isSoldOut ? 0.5 : 1 }}
|
|
524
|
-
/>
|
|
525
|
-
</div>
|
|
526
|
-
))}
|
|
527
|
-
</div>
|
|
528
|
-
|
|
529
|
-
{/* DATES COLUMN */}
|
|
530
|
-
<div className="flex flex-col gap-[6px]">
|
|
531
|
-
{/* Departure Date */}
|
|
532
|
-
<StageTooltip
|
|
533
|
-
stageData={serviceItem.boarding_stages}
|
|
534
|
-
direction={1}
|
|
535
|
-
terminals={busStage}
|
|
536
|
-
serviceItem={serviceItem}
|
|
537
|
-
metaData={metaData}
|
|
538
|
-
colors={colors}
|
|
539
|
-
>
|
|
540
|
-
<span className="cursor-pointer bold-text capitalize">
|
|
541
|
-
{DateService.getServiceItemDate(
|
|
542
|
-
serviceItem.travel_date,
|
|
543
|
-
)}
|
|
544
|
-
</span>
|
|
545
|
-
</StageTooltip>
|
|
546
|
-
|
|
547
|
-
{/* Arrival Date */}
|
|
548
|
-
{!isCiva && (
|
|
549
|
-
<StageTooltip
|
|
550
|
-
stageData={serviceItem.boarding_stages}
|
|
551
|
-
direction={1}
|
|
552
|
-
terminals={busStage}
|
|
553
|
-
serviceItem={serviceItem}
|
|
554
|
-
metaData={metaData}
|
|
555
|
-
colors={colors}
|
|
556
|
-
>
|
|
557
|
-
<span className="cursor-pointer bold-text capitalize">
|
|
558
|
-
{DateService.getServiceItemDate(
|
|
559
|
-
serviceItem.arrival_date,
|
|
560
|
-
)}
|
|
561
|
-
</span>
|
|
562
|
-
</StageTooltip>
|
|
563
|
-
)}
|
|
564
|
-
</div>
|
|
565
|
-
|
|
566
|
-
{/* DOTS COLUMN */}
|
|
567
|
-
<div className="flex flex-col gap-[6px] items-center">
|
|
568
|
-
{/* Departure Dot */}
|
|
569
|
-
<div className="h-[20px] flex items-center justify-center">
|
|
570
|
-
<div>•</div>
|
|
571
|
-
</div>
|
|
572
|
-
|
|
573
|
-
{/* Arrival Dot */}
|
|
574
|
-
{!isCiva && (
|
|
575
|
-
<div className="h-[20px] flex items-center justify-center">
|
|
576
|
-
{removeArrivalTime ? null : serviceItem.arr_time ? (
|
|
577
|
-
<div>•</div>
|
|
578
|
-
) : null}
|
|
579
|
-
</div>
|
|
580
|
-
)}
|
|
581
|
-
</div>
|
|
582
|
-
|
|
583
|
-
{/* TIMES COLUMN */}
|
|
584
|
-
<div className="flex flex-col gap-[6px]">
|
|
585
|
-
{/* Departure Time */}
|
|
586
|
-
<StageTooltip
|
|
587
|
-
stageData={serviceItem.dropoff_stages}
|
|
588
|
-
direction={2}
|
|
589
|
-
terminals={busStage}
|
|
590
|
-
serviceItem={serviceItem}
|
|
591
|
-
metaData={metaData}
|
|
592
|
-
colors={colors}
|
|
593
|
-
>
|
|
594
|
-
<div className="font-[900] bold-text">
|
|
595
|
-
{isLinatal ? (
|
|
596
|
-
<>
|
|
597
|
-
{cleanedDepTime}{" "}
|
|
598
|
-
<span>{hasPM ? "PM" : hasAM ? "AM" : ""}</span>
|
|
599
|
-
{!serviceItem?.dep_time.includes("AM") &&
|
|
600
|
-
!serviceItem?.dep_time.includes("PM") &&
|
|
601
|
-
DateService.ampmOnly(serviceItem.dep_time)}
|
|
602
|
-
</>
|
|
603
|
-
) : (
|
|
604
|
-
DateService.formatTime(serviceItem.dep_time)
|
|
605
|
-
)}
|
|
606
|
-
</div>
|
|
607
|
-
</StageTooltip>
|
|
608
|
-
|
|
609
|
-
{/* Arrival Time */}
|
|
610
|
-
{!isCiva && (
|
|
611
|
-
<StageTooltip
|
|
612
|
-
stageData={serviceItem.dropoff_stages}
|
|
613
|
-
direction={2}
|
|
614
|
-
terminals={busStage}
|
|
615
|
-
serviceItem={serviceItem}
|
|
616
|
-
metaData={metaData}
|
|
617
|
-
colors={colors}
|
|
618
|
-
>
|
|
619
|
-
<div className="font-[900] bold-text">
|
|
620
|
-
{removeArrivalTime
|
|
621
|
-
? null
|
|
622
|
-
: serviceItem.arr_time
|
|
623
|
-
? DateService.formatTime(serviceItem.arr_time)
|
|
624
|
-
: null}
|
|
625
|
-
</div>
|
|
626
|
-
</StageTooltip>
|
|
627
|
-
)}
|
|
628
|
-
</div>
|
|
629
|
-
</div>
|
|
475
|
+
<DateTimeSection
|
|
476
|
+
serviceItem={serviceItem}
|
|
477
|
+
isSoldOut={isSoldOut}
|
|
478
|
+
isCiva={isCiva}
|
|
479
|
+
isLinatal={isLinatal}
|
|
480
|
+
removeArrivalTime={removeArrivalTime}
|
|
481
|
+
orignLabel={orignLabel}
|
|
482
|
+
destinationLabel={destinationLabel}
|
|
483
|
+
busStage={busStage}
|
|
484
|
+
metaData={metaData}
|
|
485
|
+
colors={colors}
|
|
486
|
+
/>
|
|
630
487
|
<div
|
|
631
488
|
style={{
|
|
632
489
|
width: "1px",
|
|
@@ -699,16 +556,28 @@ function ServiceItemPB({
|
|
|
699
556
|
</div>
|
|
700
557
|
|
|
701
558
|
{/* 🔹 EXPANDABLE DROPDOWN (below the card) */}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
559
|
+
<div
|
|
560
|
+
style={{
|
|
561
|
+
display: "grid",
|
|
562
|
+
gridTemplateRows: isItemExpanded ? "1fr" : "0fr",
|
|
563
|
+
opacity: isItemExpanded ? 1 : 0,
|
|
564
|
+
transition:
|
|
565
|
+
"grid-template-rows 0.3s ease-in-out, opacity 0.25s ease-in-out",
|
|
566
|
+
}}
|
|
567
|
+
>
|
|
568
|
+
<div
|
|
569
|
+
style={{ overflow: "hidden", minHeight: 0, marginTop: "-10px" }}
|
|
570
|
+
>
|
|
571
|
+
<ExpandedDropdown
|
|
572
|
+
serviceItem={serviceItem}
|
|
573
|
+
showPromo={showPromo}
|
|
574
|
+
colors={colors}
|
|
575
|
+
grayscaleClass={grayscaleClass}
|
|
576
|
+
translation={translation}
|
|
577
|
+
getAnimationIcon={getAnimationIcon}
|
|
578
|
+
/>
|
|
579
|
+
</div>
|
|
580
|
+
</div>
|
|
712
581
|
|
|
713
582
|
{children}
|
|
714
583
|
{/* Bottom discount banner */}
|
|
@@ -53,7 +53,8 @@ function BottomAmenities({
|
|
|
53
53
|
<div
|
|
54
54
|
className="grid items-center gap-[2%] flex-1 "
|
|
55
55
|
style={{
|
|
56
|
-
gridTemplateColumns: "
|
|
56
|
+
// gridTemplateColumns: " 28% 21% 23% 23%",
|
|
57
|
+
gridTemplateColumns: "28% 17% 23% 23%",
|
|
57
58
|
}}
|
|
58
59
|
>
|
|
59
60
|
{otherItems.map((item) => (
|
|
@@ -95,7 +96,7 @@ function BottomAmenities({
|
|
|
95
96
|
{/* DOWN ARROW ICON */}
|
|
96
97
|
{showDownArrow ? (
|
|
97
98
|
<div
|
|
98
|
-
className=
|
|
99
|
+
className={`flex items-center cursor-pointer ml-[4px] transition-transform duration-300 w-[14px] h-[14px] ${isItemExpanded ? "rotate-180" : ""}`}
|
|
99
100
|
onClick={onToggleExpand}
|
|
100
101
|
>
|
|
101
102
|
{downArrowIcon}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import DateService from "../../utils/DateService";
|
|
3
|
+
import StageTooltip from "../StagesTooltip";
|
|
4
|
+
|
|
5
|
+
interface DateTimeSectionProps {
|
|
6
|
+
serviceItem: {
|
|
7
|
+
icons?: { origin?: string; destination?: string; [key: string]: any };
|
|
8
|
+
boarding_stages?: string;
|
|
9
|
+
dropoff_stages?: string;
|
|
10
|
+
travel_date: string;
|
|
11
|
+
arrival_date: string;
|
|
12
|
+
dep_time: string;
|
|
13
|
+
arr_time: string;
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
};
|
|
16
|
+
isSoldOut: boolean;
|
|
17
|
+
isCiva?: boolean;
|
|
18
|
+
isLinatal?: boolean;
|
|
19
|
+
removeArrivalTime?: boolean;
|
|
20
|
+
orignLabel?: string;
|
|
21
|
+
destinationLabel?: string;
|
|
22
|
+
busStage?: Record<string, string>;
|
|
23
|
+
metaData?: any;
|
|
24
|
+
colors: Record<string, any>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function DateTimeSection({
|
|
28
|
+
serviceItem,
|
|
29
|
+
isSoldOut,
|
|
30
|
+
isCiva,
|
|
31
|
+
isLinatal,
|
|
32
|
+
removeArrivalTime,
|
|
33
|
+
orignLabel,
|
|
34
|
+
destinationLabel,
|
|
35
|
+
busStage,
|
|
36
|
+
metaData,
|
|
37
|
+
colors,
|
|
38
|
+
}: DateTimeSectionProps): React.ReactElement {
|
|
39
|
+
const depTime = serviceItem.dep_time || "";
|
|
40
|
+
const hasAM = depTime.includes("AM");
|
|
41
|
+
const hasPM = depTime.includes("PM");
|
|
42
|
+
|
|
43
|
+
const convertTo24Hour = (depTime: string): string => {
|
|
44
|
+
const hasAM = depTime.includes("AM");
|
|
45
|
+
const hasPM = depTime.includes("PM");
|
|
46
|
+
const [timePart] = depTime.split(/AM|PM/).map((part) => part.trim());
|
|
47
|
+
const [hour, minute] = timePart.split(":").map(Number);
|
|
48
|
+
const pad = (n: number) => (n < 10 ? "0" + n : String(n));
|
|
49
|
+
|
|
50
|
+
if (hasAM) {
|
|
51
|
+
return `${pad(hour === 12 ? 0 : hour)}:${pad(minute)}`;
|
|
52
|
+
}
|
|
53
|
+
if (hasPM) {
|
|
54
|
+
return `${hour === 12 ? hour : hour + 12}:${pad(minute)}`;
|
|
55
|
+
}
|
|
56
|
+
return timePart;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const cleanedDepTime = convertTo24Hour(depTime);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div
|
|
63
|
+
className={`min-h-[2.2rem] grid grid-cols-[26px_auto_26%_1fr] gap-x-4 items-center text-[13.33px] ${
|
|
64
|
+
isSoldOut ? "text-[#c0c0c0]" : ""
|
|
65
|
+
}`}
|
|
66
|
+
style={{
|
|
67
|
+
gridTemplateRows: "1fr",
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
{/* ICONS COLUMN */}
|
|
71
|
+
<div className="flex flex-col gap-[6px]">
|
|
72
|
+
{/* Origin Icon */}
|
|
73
|
+
{orignLabel ? (
|
|
74
|
+
<div className="w-[60px] h-[20px] flex items-center">
|
|
75
|
+
{orignLabel}
|
|
76
|
+
</div>
|
|
77
|
+
) : (
|
|
78
|
+
<div className="h-[20px] flex items-center">
|
|
79
|
+
<img
|
|
80
|
+
src={serviceItem.icons?.origin}
|
|
81
|
+
alt="origin"
|
|
82
|
+
className={`w-[16px] h-auto mr-[8px] ${
|
|
83
|
+
isSoldOut ? "grayscale" : ""
|
|
84
|
+
}`}
|
|
85
|
+
/>
|
|
86
|
+
</div>
|
|
87
|
+
)}
|
|
88
|
+
|
|
89
|
+
{/* Destination Icon */}
|
|
90
|
+
{!isCiva &&
|
|
91
|
+
(destinationLabel ? (
|
|
92
|
+
<div className="w-[60px] h-[20px] flex items-center">
|
|
93
|
+
{destinationLabel}
|
|
94
|
+
</div>
|
|
95
|
+
) : (
|
|
96
|
+
<div className="h-[20px] flex items-center">
|
|
97
|
+
<img
|
|
98
|
+
src={serviceItem.icons?.destination}
|
|
99
|
+
className={`w-[16px] h-auto mr-[8px] ${
|
|
100
|
+
isSoldOut ? "grayscale" : ""
|
|
101
|
+
}`}
|
|
102
|
+
style={{ opacity: isSoldOut ? 0.5 : 1 }}
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
105
|
+
))}
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
{/* DATES COLUMN */}
|
|
109
|
+
<div className="flex flex-col gap-[6px]">
|
|
110
|
+
{/* Departure Date */}
|
|
111
|
+
<StageTooltip
|
|
112
|
+
stageData={serviceItem.boarding_stages}
|
|
113
|
+
direction={1}
|
|
114
|
+
terminals={busStage}
|
|
115
|
+
serviceItem={serviceItem}
|
|
116
|
+
metaData={metaData}
|
|
117
|
+
colors={colors}
|
|
118
|
+
>
|
|
119
|
+
<span className="cursor-pointer bold-text capitalize">
|
|
120
|
+
{DateService.getServiceItemDate(serviceItem.travel_date)}
|
|
121
|
+
</span>
|
|
122
|
+
</StageTooltip>
|
|
123
|
+
|
|
124
|
+
{/* Arrival Date */}
|
|
125
|
+
{!isCiva && (
|
|
126
|
+
<StageTooltip
|
|
127
|
+
stageData={serviceItem.boarding_stages}
|
|
128
|
+
direction={1}
|
|
129
|
+
terminals={busStage}
|
|
130
|
+
serviceItem={serviceItem}
|
|
131
|
+
metaData={metaData}
|
|
132
|
+
colors={colors}
|
|
133
|
+
>
|
|
134
|
+
<span className="cursor-pointer bold-text capitalize">
|
|
135
|
+
{DateService.getServiceItemDate(serviceItem.arrival_date)}
|
|
136
|
+
</span>
|
|
137
|
+
</StageTooltip>
|
|
138
|
+
)}
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
{/* DOTS COLUMN */}
|
|
142
|
+
<div className="flex flex-col gap-[6px] items-center">
|
|
143
|
+
{/* Departure Dot */}
|
|
144
|
+
<div className="h-[20px] flex items-center justify-center">
|
|
145
|
+
<div>•</div>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
{/* Arrival Dot */}
|
|
149
|
+
{!isCiva && (
|
|
150
|
+
<div className="h-[20px] flex items-center justify-center">
|
|
151
|
+
{removeArrivalTime ? null : serviceItem.arr_time ? (
|
|
152
|
+
<div>•</div>
|
|
153
|
+
) : null}
|
|
154
|
+
</div>
|
|
155
|
+
)}
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
{/* TIMES COLUMN */}
|
|
159
|
+
<div className="flex flex-col gap-[6px]">
|
|
160
|
+
{/* Departure Time */}
|
|
161
|
+
<StageTooltip
|
|
162
|
+
stageData={serviceItem.dropoff_stages}
|
|
163
|
+
direction={2}
|
|
164
|
+
terminals={busStage}
|
|
165
|
+
serviceItem={serviceItem}
|
|
166
|
+
metaData={metaData}
|
|
167
|
+
colors={colors}
|
|
168
|
+
>
|
|
169
|
+
<div className="font-[900] bold-text">
|
|
170
|
+
{isLinatal ? (
|
|
171
|
+
<>
|
|
172
|
+
{cleanedDepTime} <span>{hasPM ? "PM" : hasAM ? "AM" : ""}</span>
|
|
173
|
+
{!serviceItem?.dep_time.includes("AM") &&
|
|
174
|
+
!serviceItem?.dep_time.includes("PM") &&
|
|
175
|
+
DateService.ampmOnly(serviceItem.dep_time)}
|
|
176
|
+
</>
|
|
177
|
+
) : (
|
|
178
|
+
DateService.formatTime(serviceItem.dep_time)
|
|
179
|
+
)}
|
|
180
|
+
</div>
|
|
181
|
+
</StageTooltip>
|
|
182
|
+
|
|
183
|
+
{/* Arrival Time */}
|
|
184
|
+
{!isCiva && (
|
|
185
|
+
<StageTooltip
|
|
186
|
+
stageData={serviceItem.dropoff_stages}
|
|
187
|
+
direction={2}
|
|
188
|
+
terminals={busStage}
|
|
189
|
+
serviceItem={serviceItem}
|
|
190
|
+
metaData={metaData}
|
|
191
|
+
colors={colors}
|
|
192
|
+
>
|
|
193
|
+
<div className="font-[900] bold-text">
|
|
194
|
+
{removeArrivalTime
|
|
195
|
+
? null
|
|
196
|
+
: serviceItem.arr_time
|
|
197
|
+
? DateService.formatTime(serviceItem.arr_time)
|
|
198
|
+
: null}
|
|
199
|
+
</div>
|
|
200
|
+
</StageTooltip>
|
|
201
|
+
)}
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export default DateTimeSection;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import LottiePlayer from "../assets/LottiePlayer";
|
|
3
|
+
|
|
4
|
+
const DirectoBlock = ({ translation, isSoldOut, colors, getAnimationIcon }) => (
|
|
5
|
+
<div className="flex items-center relative whitespace-nowrap mt-[3px]">
|
|
6
|
+
<div className={`w-[18px] mr-[4px] ${isSoldOut ? "grayscale" : ""}`}>
|
|
7
|
+
<LottiePlayer
|
|
8
|
+
animationData={getAnimationIcon("directoAnim")}
|
|
9
|
+
width="14px"
|
|
10
|
+
height="14px"
|
|
11
|
+
/>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div className="group text-[13.33px] cursor-pointer">
|
|
15
|
+
{translation?.directService}
|
|
16
|
+
<div
|
|
17
|
+
className="hidden group-hover:block absolute top-[24px] left-1/2 -translate-x-1/2 text-white p-3 rounded-[14px] whitespace-nowrap w-fit z-10 mt-2.5 text-center shadow-service text-[12px]"
|
|
18
|
+
style={{ backgroundColor: colors.tooltipColor }}
|
|
19
|
+
>
|
|
20
|
+
{/* Tooltip arrow */}
|
|
21
|
+
<div
|
|
22
|
+
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"
|
|
23
|
+
style={{ borderBottomColor: colors.tooltipColor }}
|
|
24
|
+
></div>
|
|
25
|
+
{translation?.directServiceText}
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
export default DirectoBlock;
|
|
@@ -3,6 +3,7 @@ import LottiePlayer from "../../assets/LottiePlayer";
|
|
|
3
3
|
|
|
4
4
|
interface ExpandedDropdownProps {
|
|
5
5
|
serviceItem: {
|
|
6
|
+
change_ticket_hours?: number;
|
|
6
7
|
pet_seat_info?: Record<string, any>;
|
|
7
8
|
is_change_ticket?: boolean;
|
|
8
9
|
is_tracking_enabled?: boolean;
|
|
@@ -30,17 +31,17 @@ function ExpandedDropdown({
|
|
|
30
31
|
|
|
31
32
|
return (
|
|
32
33
|
<div
|
|
33
|
-
className="px-[15px] pt-[26px] pb-[14px] -mt-[16px] pt-[
|
|
34
|
+
className="px-[15px] pt-[26px] pb-[14px] -mt-[16px] pt-[35px] relative -z-9"
|
|
34
35
|
style={{
|
|
35
|
-
backgroundColor: "#
|
|
36
|
+
backgroundColor: "#ffefef",
|
|
36
37
|
borderRadius: "0 0 10px 10px",
|
|
37
38
|
// border: showPromo ? `1px solid ${colors.priceColor}` : "1px solid #ccc",
|
|
38
|
-
border: `1px solid ${colors.priceColor}`,
|
|
39
|
+
// border: `1px solid ${colors.priceColor}`,
|
|
39
40
|
|
|
40
|
-
borderTop: "none",
|
|
41
|
+
// borderTop: "none",
|
|
41
42
|
}}
|
|
42
43
|
>
|
|
43
|
-
<div className="flex flex-col gap-[12px] text-[13px] text-[#464647]">
|
|
44
|
+
{/* <div className="flex flex-col gap-[12px] text-[13px] text-[#464647]">
|
|
44
45
|
{hasPetInfo && (
|
|
45
46
|
<div className="flex items-center gap-[10px]">
|
|
46
47
|
<LottiePlayer
|
|
@@ -77,6 +78,35 @@ function ExpandedDropdown({
|
|
|
77
78
|
</div>
|
|
78
79
|
</div>
|
|
79
80
|
)}
|
|
81
|
+
</div> */}
|
|
82
|
+
<div
|
|
83
|
+
className="flex flex-col gap-[10px] text-[13px] text-[#464647]"
|
|
84
|
+
style={{ lineHeight: 1.6 }}
|
|
85
|
+
>
|
|
86
|
+
<div className="flex gap-[8px] text-[13.33px]">
|
|
87
|
+
<span style={{ marginTop: "2px" }}>•</span>
|
|
88
|
+
<span>
|
|
89
|
+
<span className="bold-text">Políticas de anulación:</span> Tu pasaje
|
|
90
|
+
puede ser anulado de forma online{" "}
|
|
91
|
+
<span className="bold-text">
|
|
92
|
+
hasta {serviceItem?.change_ticket_hours ?? 6} horas antes
|
|
93
|
+
</span>{" "}
|
|
94
|
+
de la salida del bus. Al anular tu pasaje recibirás una devolución
|
|
95
|
+
del 85% del monto de tu compra.
|
|
96
|
+
</span>
|
|
97
|
+
</div>
|
|
98
|
+
<div className="flex gap-[8px]">
|
|
99
|
+
<span style={{ marginTop: "2px" }}>•</span>
|
|
100
|
+
<span>
|
|
101
|
+
<span className="bold-text">Políticas de cambios:</span> Tu pasaje
|
|
102
|
+
puede ser cambiado de manera online{" "}
|
|
103
|
+
<span className="bold-text">
|
|
104
|
+
hasta {serviceItem?.change_ticket_hours ?? 6} horas antes
|
|
105
|
+
</span>{" "}
|
|
106
|
+
de la salida del bus. El monto será reembolsado a tu billetera
|
|
107
|
+
kupospay.
|
|
108
|
+
</span>
|
|
109
|
+
</div>
|
|
80
110
|
</div>
|
|
81
111
|
</div>
|
|
82
112
|
);
|
|
@@ -157,7 +157,7 @@ function SeatSection({
|
|
|
157
157
|
|
|
158
158
|
return (
|
|
159
159
|
<div
|
|
160
|
-
className="relative flex gap-[10px] text-[13.33px] justify-between min-h-[2.
|
|
160
|
+
className="relative flex gap-[10px] text-[13.33px] justify-between min-h-[2.2rem]"
|
|
161
161
|
style={isCentered ? { alignItems: "center" } : {}}
|
|
162
162
|
>
|
|
163
163
|
<div className="flex flex-col justify-between" style={{ gap: "10px" }}>
|