kupos-ui-components-lib 9.1.2 → 9.1.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 (46) hide show
  1. package/README copy.md +67 -223
  2. package/dist/assets/images/anims/service_list/directo.json +1 -1
  3. package/dist/components/ServiceItem/PeruServiceItemDesktop.js +1 -1
  4. package/dist/components/ServiceItem/RatingHover.js +33 -32
  5. package/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
  6. package/dist/components/ServiceItem/ServiceItemDesktop.js +267 -147
  7. package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
  8. package/dist/components/ServiceItem/ServiceItemMobile.js +278 -87
  9. package/dist/components/ServiceItem/mobileTypes.d.ts +0 -5
  10. package/dist/components/ServiceItem/types.d.ts +0 -7
  11. package/dist/styles.css +32 -131
  12. package/dist/ui/AmenitiesBlock.js +30 -23
  13. package/dist/ui/DurationBlock.js +4 -4
  14. package/dist/ui/FlexibleBlock.js +6 -5
  15. package/dist/ui/PetBlock.js +3 -1
  16. package/dist/ui/RatingBlock.d.ts +1 -9
  17. package/dist/ui/RatingBlock.js +3 -7
  18. package/dist/utils/CommonService.d.ts +1 -1
  19. package/dist/utils/CommonService.js +0 -2
  20. package/package.json +1 -2
  21. package/src/assets/images/anims/service_list/directo.json +1 -1
  22. package/src/components/ServiceItem/PeruServiceItemDesktop.tsx +0 -1
  23. package/src/components/ServiceItem/RatingHover.tsx +45 -44
  24. package/src/components/ServiceItem/ServiceItemDesktop.tsx +537 -313
  25. package/src/components/ServiceItem/ServiceItemMobile.tsx +530 -213
  26. package/src/components/ServiceItem/mobileTypes.ts +0 -5
  27. package/src/components/ServiceItem/types.ts +0 -7
  28. package/src/ui/AmenitiesBlock.tsx +29 -50
  29. package/src/ui/DurationBlock.tsx +4 -4
  30. package/src/ui/FlexibleBlock.tsx +5 -6
  31. package/src/ui/PetBlock.tsx +2 -2
  32. package/src/ui/RatingBlock.tsx +6 -18
  33. package/src/utils/CommonService.ts +0 -2
  34. package/src/assets/images/anims/service_list/bomb.json +0 -1
  35. package/src/ui/BottomAmenities/BottomAmenities.tsx +0 -110
  36. package/src/ui/DateTimeSection/DateTimeSection.tsx +0 -207
  37. package/src/ui/DirectoBlock.tsx +0 -31
  38. package/src/ui/ExpendedDropDown/ExpandedDropdown.tsx +0 -103
  39. package/src/ui/KuposButton/KuposButton.tsx +0 -48
  40. package/src/ui/SeatSection/SeatSection.tsx +0 -207
  41. package/src/ui/TopAmenities/TopAmenities.tsx +0 -127
  42. package/src/ui/mobileweb/BottomAmenitiesMobile.tsx +0 -169
  43. package/src/ui/mobileweb/DateTimeSectionMobile.tsx +0 -192
  44. package/src/ui/mobileweb/ExpandedDropdownMobile.tsx +0 -56
  45. package/src/ui/mobileweb/SeatSectionMobile.tsx +0 -256
  46. package/src/ui/mobileweb/TopAmenitieMobile.tsx +0 -126
@@ -1,127 +0,0 @@
1
- import React from "react";
2
- import LottiePlayer from "../../assets/LottiePlayer";
3
-
4
- interface TopAmenitiesProps {
5
- showPromo: boolean;
6
- showTopLabel: string | boolean;
7
- isSoldOut: boolean;
8
- priceColor?: string;
9
- buttonColor?: string;
10
- boardingIcon?: React.ReactNode;
11
- getAnimationIcon: (icon: string) => any;
12
- countdownSeconds?: number;
13
- promoText?: string;
14
- onCountdownEnd?: () => void;
15
- offerText?: string;
16
- }
17
-
18
- function TopAmenities({
19
- showPromo,
20
- showTopLabel,
21
- isSoldOut,
22
- priceColor,
23
- buttonColor,
24
- boardingIcon,
25
- getAnimationIcon,
26
- countdownSeconds = 0,
27
- onCountdownEnd,
28
- offerText,
29
- }: TopAmenitiesProps): React.ReactElement {
30
- const pad = (n: number) => String(n).padStart(2, "0");
31
-
32
- const startCountdown = (el: HTMLSpanElement | null) => {
33
- if (!el || el.dataset.timerStarted) return;
34
- el.dataset.timerStarted = "true";
35
- let remaining = countdownSeconds;
36
-
37
- const update = () => {
38
- const hrs = Math.floor(remaining / 3600);
39
- const mins = Math.floor((remaining % 3600) / 60);
40
- const secs = remaining % 60;
41
- el.textContent = `${pad(hrs)}:${pad(mins)}:${pad(secs)}`;
42
- };
43
-
44
- update();
45
- const timer = setInterval(() => {
46
- if (remaining <= 0) {
47
- clearInterval(timer);
48
- const promoBar = el.closest("[data-promo-bar]") as HTMLElement;
49
- if (promoBar) promoBar.style.display = "none";
50
- if (onCountdownEnd) onCountdownEnd();
51
- return;
52
- }
53
- remaining--;
54
- update();
55
- }, 1000);
56
- };
57
- return (
58
- <div
59
- style={{
60
- display: "flex",
61
- justifyContent: "flex-end",
62
- position: "relative",
63
- zIndex: "-1",
64
- }}
65
- >
66
- {offerText && (
67
- <div
68
- data-promo-bar
69
- style={{
70
- backgroundColor: priceColor,
71
- position: "relative",
72
- right: showTopLabel ? "-21px" : "",
73
- padding: "0 14px",
74
- borderTopRightRadius: "10px",
75
- borderTopLeftRadius: "10px",
76
- }}
77
- >
78
- <div style={{ display: "flex", alignItems: "center" }}>
79
- <LottiePlayer
80
- animationData={getAnimationIcon("bombAnimation")}
81
- width="20px"
82
- height="20px"
83
- />
84
- <span
85
- className="flex items-center py-[10px] pl-[6px] text-white text-[13.33px] z-20"
86
- style={{ paddingRight: showTopLabel ? "18px" : "" }}
87
- >
88
- <span className="bold-text">{offerText}&nbsp;</span> | Termina
89
- en&nbsp;
90
- <span
91
- className="bold-text"
92
- ref={startCountdown}
93
- style={{
94
- fontVariantNumeric: "tabular-nums",
95
- display: "inline-block",
96
- minWidth: "70px",
97
- }}
98
- />
99
- {/* <span className="bold-text">02:10:30</span> */}
100
- </span>
101
- </div>
102
- </div>
103
- )}
104
-
105
- {showTopLabel && (
106
- <div
107
- className="flex items-center py-[10px] px-[14px] text-[13.33px] z-20"
108
- style={{
109
- backgroundColor: isSoldOut ? "#ddd" : buttonColor,
110
- borderTopRightRadius: "10px",
111
- borderTopLeftRadius: "10px",
112
- }}
113
- >
114
- <LottiePlayer
115
- animationData={getAnimationIcon("priorityStageAnim")}
116
- width="14px"
117
- height="14px"
118
- />
119
- {/* {boardingIcon} */}
120
- <div className="text-white pl-[6px]">{showTopLabel}</div>
121
- </div>
122
- )}
123
- </div>
124
- );
125
- }
126
-
127
- export default TopAmenities;
@@ -1,169 +0,0 @@
1
- import React from "react";
2
- import LottiePlayer from "../../assets/LottiePlayer";
3
-
4
- interface BottomAmenitiesMobileProps {
5
- isSoldOut: boolean;
6
- amenitiesNodes: React.ReactNode;
7
- hoursIcon: React.ReactNode;
8
- duration: string;
9
- isDirectTrip?: boolean;
10
- directoColor?: string;
11
- directoAnim?: any;
12
- isChangeTicket?: boolean;
13
- isPetSeat: boolean;
14
- petSeatInfo?: Record<string, any>;
15
- petFriendlyAnim?: any;
16
- flexibleAnim?: any;
17
- isTrackingEnabled?: boolean;
18
- locationAnim?: any;
19
- downArrowIcon?: string;
20
- showDropdown: boolean;
21
- setShowDropdown: (val: boolean) => void;
22
- onDropdownToggle: () => void;
23
- isItemExpanded?: boolean;
24
- }
25
-
26
- function BottomAmenitiesMobile({
27
- isSoldOut,
28
- amenitiesNodes,
29
- hoursIcon,
30
- duration,
31
- isDirectTrip,
32
- directoColor,
33
- directoAnim,
34
- isChangeTicket,
35
- isPetSeat,
36
- petSeatInfo,
37
- petFriendlyAnim,
38
- flexibleAnim,
39
- isTrackingEnabled,
40
- locationAnim,
41
- downArrowIcon,
42
- showDropdown,
43
- setShowDropdown,
44
- onDropdownToggle,
45
- isItemExpanded,
46
- }: BottomAmenitiesMobileProps): React.ReactElement {
47
- return (
48
- <div className={`${"flex justify-between items-center items-center "}`}>
49
- <div className="w-[55%] flex justify-between items-center">
50
- <div style={{ opacity: isSoldOut ? 0.5 : 1 }}>{amenitiesNodes}</div>
51
-
52
- <div
53
- className="flex relative "
54
- style={{ color: isSoldOut ? "#bbb" : "text-[#464647]" }}
55
- >
56
- <div
57
- className={`w-[12px] h-auto mr-[2px] ${
58
- isSoldOut ? "grayscale" : ""
59
- }`}
60
- >
61
- {hoursIcon}
62
- </div>
63
- &nbsp;
64
- <div
65
- className={`cursor-default group min-[420]:text-[13px] text-[12px] ${
66
- isSoldOut ? "text-[#c0c0c0]" : ""
67
- }`}
68
- style={{ lineHeight: "normal" }}
69
- >
70
- {duration}hrs
71
- </div>
72
- </div>
73
-
74
- {isDirectTrip && (
75
- <div
76
- className={`flex items-center gap-[2px] text-white min-[420]:text-[12px] text-[10px] z-20 `}
77
- style={{
78
- // backgroundColor: isSoldOut ? "#ddd" : colors.tooltipBgColor,
79
- color: isSoldOut ? "#bbb" : directoColor,
80
- }}
81
- >
82
- <LottiePlayer
83
- animationData={directoAnim}
84
- width="14px"
85
- height="14px"
86
- />
87
- <div className="ml-[5px]">Directo</div>
88
- </div>
89
- )}
90
- </div>
91
-
92
- <div className="flex items-center">
93
- <div>
94
- {(isChangeTicket || isPetSeat) && (
95
- <div className="flex items-center">
96
- {petSeatInfo && Object.keys(petSeatInfo).length > 0 ? (
97
- <div className="flex items-center">
98
- <div className={`relative group cursor-default `}>
99
- <div className="flex items-center">
100
- <div
101
- className={`mr-[5px] ${isSoldOut ? "grayscale" : ""}`}
102
- >
103
- <LottiePlayer
104
- animationData={petFriendlyAnim}
105
- width="16px"
106
- height="16px"
107
- />
108
- </div>
109
- </div>
110
- </div>
111
- </div>
112
- ) : null}
113
-
114
- {/* Flexible ticket */}
115
- {isChangeTicket && (
116
- <div className="flex items-center">
117
- <div className="relative group cursor-default">
118
- <div className="flex items-center">
119
- <div
120
- className={`mr-[5px] ${isSoldOut ? "grayscale" : ""}`}
121
- >
122
- <LottiePlayer
123
- animationData={flexibleAnim}
124
- width="16px"
125
- height="16px"
126
- />
127
- </div>
128
- </div>
129
- </div>
130
- </div>
131
- )}
132
-
133
- {isTrackingEnabled && (
134
- <div className="flex items-center mr-[10px]">
135
- <div
136
- className={`h-auto mr-[4px] min-[420]:text-[13px] text-[11px] text-[#464647] ${
137
- isSoldOut ? "grayscale" : ""
138
- }`}
139
- >
140
- <LottiePlayer
141
- animationData={locationAnim}
142
- width="16px"
143
- height="16px"
144
- />
145
- </div>
146
- </div>
147
- )}
148
- </div>
149
- )}
150
- </div>
151
- <div onClick={onDropdownToggle}>
152
- {/* {(isChangeTicket || isPetSeat) && ( */}
153
- <img
154
- src={downArrowIcon}
155
- alt="icon"
156
- width={14}
157
- height={14}
158
- className={`${
159
- showDropdown ? "rotate-180" : ""
160
- } transition-transform duration-300`}
161
- />
162
- {/* )} */}
163
- </div>
164
- </div>
165
- </div>
166
- );
167
- }
168
-
169
- export default BottomAmenitiesMobile;
@@ -1,192 +0,0 @@
1
- import React from "react";
2
- import DateService from "../../utils/DateService";
3
- import SeatSectionMobile from "./SeatSectionMobile";
4
-
5
- interface DateTimeSectionMobileProps {
6
- onBookButtonPress: () => void;
7
- isCiva: boolean;
8
- isSoldOut: boolean;
9
- isLinatal: boolean;
10
- isPeru: boolean;
11
- orignLabel?: React.ReactNode;
12
- destinationLabel?: React.ReactNode;
13
- originIcon?: string;
14
- destinationIcon?: string;
15
- travelDate: string;
16
- arrivalDate: string;
17
- depTime: string;
18
- arrTime: string;
19
- seatTypes: any[];
20
- seatPriceColor: string;
21
- currencySign: string;
22
- availableSeats: number;
23
- removeDuplicateSeats?: boolean;
24
- }
25
-
26
- const pad = (n: number) => (n < 10 ? "0" + n : String(n));
27
-
28
- const getCleanedDepTime = (raw: string) => {
29
- const depTimeStr = raw || "";
30
- const hasAM = depTimeStr.includes("AM");
31
- const hasPM = depTimeStr.includes("PM");
32
- const [timePart] = depTimeStr.split(/AM|PM/).map((s) => s.trim());
33
- const [hour, minute] = timePart.split(":").map(Number);
34
-
35
- let cleaned: string;
36
- if (hasAM) {
37
- cleaned = hour === 12 ? `00:${pad(minute)}` : `${pad(hour)}:${pad(minute)}`;
38
- } else if (hasPM) {
39
- cleaned =
40
- hour === 12 ? `${hour}:${pad(minute)}` : `${hour + 12}:${pad(minute)}`;
41
- } else {
42
- cleaned = timePart;
43
- }
44
-
45
- return { cleaned, hasAM, hasPM };
46
- };
47
-
48
- interface TimeRowProps {
49
- label?: React.ReactNode;
50
- icon?: string;
51
- alt: string;
52
- date: string;
53
- timeContent: React.ReactNode;
54
- isSoldOut: boolean;
55
- }
56
-
57
- const TimeRow: React.FC<TimeRowProps> = ({
58
- label,
59
- icon,
60
- alt,
61
- date,
62
- timeContent,
63
- isSoldOut,
64
- }) => (
65
- <div
66
- className={`flex items-center min-[420]:text-[13px] text-[12px] justify-between ${
67
- isSoldOut ? "text-[#c0c0c0]" : ""
68
- }`}
69
- >
70
- <div className="flex items-center" style={{ flex: 1 }}>
71
- <div>
72
- {" "}
73
- {label ? (
74
- <div className="w-[60px]">{label}</div>
75
- ) : (
76
- <div className="w-[12px] h-auto mr-[5px]">
77
- <img
78
- src={icon}
79
- alt={alt}
80
- className={`w-[12px] h-auto mr-[5px] ${
81
- isSoldOut ? "grayscale" : ""
82
- }`}
83
- />
84
- </div>
85
- )}
86
- </div>
87
- <div
88
- className="flex items-center relative capitalize justify-between"
89
- style={{ flex: 1 }}
90
- >
91
- <span className="cursor-pointer black-text">
92
- {DateService.getServiceItemDate(date)}
93
- </span>
94
- <div className="absolute left-[50%]">•</div>
95
- <div className="font-[900] relative black-text">{timeContent}</div>
96
- </div>
97
- </div>
98
- </div>
99
- );
100
-
101
- function DateTimeSectionMobile({
102
- onBookButtonPress,
103
- isCiva,
104
- isSoldOut,
105
- isLinatal,
106
- isPeru,
107
- orignLabel,
108
- destinationLabel,
109
- originIcon,
110
- destinationIcon,
111
- travelDate,
112
- arrivalDate,
113
- depTime,
114
- arrTime,
115
- seatTypes,
116
- seatPriceColor,
117
- currencySign,
118
- availableSeats,
119
- removeDuplicateSeats,
120
- }: DateTimeSectionMobileProps): React.ReactElement {
121
- const { cleaned: cleanedDepTime, hasAM, hasPM } = getCleanedDepTime(depTime);
122
-
123
- const depTimeContent = isLinatal ? (
124
- <div>
125
- <span>
126
- {" "}
127
- {cleanedDepTime} <span>{hasPM ? "PM" : hasAM ? "AM" : ""}</span>
128
- </span>
129
- <span>
130
- {depTime.includes("AM") || depTime.includes("PM")
131
- ? null
132
- : DateService.ampmOnly(depTime)}
133
- </span>
134
- </div>
135
- ) : (
136
- DateService.formatTime(depTime)
137
- );
138
-
139
- return (
140
- <div
141
- className="flex justify-between gap-[5px] w-full"
142
- onClick={onBookButtonPress}
143
- >
144
- {/* DATE AND TIME */}
145
- <div
146
- className="min-h-[2.5rem] flex flex-col justify-between gap-[4px] w-[50%] "
147
- style={{ justifyContent: isCiva && "center" }}
148
- >
149
- <TimeRow
150
- label={orignLabel}
151
- icon={originIcon}
152
- alt="origin"
153
- date={travelDate}
154
- timeContent={depTimeContent}
155
- isSoldOut={isSoldOut}
156
- />
157
- {isCiva ? null : (
158
- <TimeRow
159
- label={destinationLabel}
160
- icon={destinationIcon}
161
- alt="destination"
162
- date={arrivalDate}
163
- timeContent={DateService.formatTime(arrTime)}
164
- isSoldOut={isSoldOut}
165
- />
166
- )}
167
- </div>
168
- {isPeru ? null : (
169
- <div
170
- style={{
171
- width: "1px",
172
- height: "2.5rem",
173
- backgroundColor: "#ccc",
174
- margin: "auto",
175
- }}
176
- ></div>
177
- )}
178
- {/* SEATS */}
179
- <SeatSectionMobile
180
- seatTypes={seatTypes}
181
- isSoldOut={isSoldOut}
182
- isPeru={isPeru}
183
- seatPriceColor={seatPriceColor}
184
- currencySign={currencySign}
185
- availableSeats={availableSeats}
186
- removeDuplicateSeats={removeDuplicateSeats}
187
- />
188
- </div>
189
- );
190
- }
191
-
192
- export default DateTimeSectionMobile;
@@ -1,56 +0,0 @@
1
- import React from "react";
2
-
3
- interface ExpandedDropdownMobileProps {
4
- serviceItem: {
5
- change_ticket_hours?: number;
6
- pet_seat_info?: Record<string, any>;
7
- is_change_ticket?: boolean;
8
- is_tracking_enabled?: boolean;
9
- };
10
- }
11
-
12
- function ExpandedDropdownMobile({
13
- serviceItem,
14
- }: ExpandedDropdownMobileProps): React.ReactElement {
15
- return (
16
- <div
17
- className="px-[12px] pt-[22px] pb-[12px] relative -z-9"
18
- style={{
19
- backgroundColor: "#ffefef",
20
- borderRadius: "0 0 14px 14px",
21
- }}
22
- >
23
- <div
24
- className="flex flex-col gap-[8px] text-[11px] min-[420px]:text-[12px] text-[#464647]"
25
- style={{ lineHeight: 1.6 }}
26
- >
27
- <div className="flex gap-[6px]">
28
- <span style={{ marginTop: "2px" }}>•</span>
29
- <span>
30
- <span className="bold-text">Políticas de anulación:</span> Tu pasaje
31
- puede ser anulado de forma online{" "}
32
- <span className="bold-text">
33
- hasta {serviceItem?.change_ticket_hours ?? 6} horas antes
34
- </span>{" "}
35
- de la salida del bus. Al anular tu pasaje recibirás una devolución
36
- del 85% del monto de tu compra.
37
- </span>
38
- </div>
39
- <div className="flex gap-[6px]">
40
- <span style={{ marginTop: "2px" }}>•</span>
41
- <span>
42
- <span className="bold-text">Políticas de cambios:</span> Tu pasaje
43
- puede ser cambiado de manera online{" "}
44
- <span className="bold-text">
45
- hasta {serviceItem?.change_ticket_hours ?? 6} horas antes
46
- </span>{" "}
47
- de la salida del bus. El monto será reembolsado a tu billetera
48
- kupospay.
49
- </span>
50
- </div>
51
- </div>
52
- </div>
53
- );
54
- }
55
-
56
- export default ExpandedDropdownMobile;