kupos-ui-components-lib 9.1.1 → 9.1.2

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 (47) hide show
  1. package/README copy.md +223 -67
  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 +32 -33
  5. package/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
  6. package/dist/components/ServiceItem/ServiceItemDesktop.js +147 -267
  7. package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
  8. package/dist/components/ServiceItem/ServiceItemMobile.js +87 -278
  9. package/dist/components/ServiceItem/mobileTypes.d.ts +5 -0
  10. package/dist/components/ServiceItem/types.d.ts +7 -0
  11. package/dist/styles.css +131 -32
  12. package/dist/ui/AmenitiesBlock.js +23 -30
  13. package/dist/ui/BottomAmenities/BottomAmenities.js +0 -1
  14. package/dist/ui/DurationBlock.js +4 -4
  15. package/dist/ui/FlexibleBlock.js +5 -6
  16. package/dist/ui/PetBlock.js +1 -3
  17. package/dist/ui/RatingBlock.d.ts +9 -1
  18. package/dist/ui/RatingBlock.js +7 -3
  19. package/dist/utils/CommonService.d.ts +1 -1
  20. package/dist/utils/CommonService.js +2 -0
  21. package/package.json +2 -1
  22. package/src/assets/images/anims/service_list/bomb.json +1 -0
  23. package/src/assets/images/anims/service_list/directo.json +1 -1
  24. package/src/components/ServiceItem/PeruServiceItemDesktop.tsx +1 -0
  25. package/src/components/ServiceItem/RatingHover.tsx +44 -45
  26. package/src/components/ServiceItem/ServiceItemDesktop.tsx +313 -537
  27. package/src/components/ServiceItem/ServiceItemMobile.tsx +213 -530
  28. package/src/components/ServiceItem/mobileTypes.ts +5 -0
  29. package/src/components/ServiceItem/types.ts +7 -0
  30. package/src/ui/AmenitiesBlock.tsx +50 -29
  31. package/src/ui/BottomAmenities/BottomAmenities.tsx +110 -0
  32. package/src/ui/DateTimeSection/DateTimeSection.tsx +207 -0
  33. package/src/ui/DirectoBlock.tsx +31 -0
  34. package/src/ui/DurationBlock.tsx +4 -4
  35. package/src/ui/ExpendedDropDown/ExpandedDropdown.tsx +103 -0
  36. package/src/ui/FlexibleBlock.tsx +6 -5
  37. package/src/ui/KuposButton/KuposButton.tsx +48 -0
  38. package/src/ui/PetBlock.tsx +2 -2
  39. package/src/ui/RatingBlock.tsx +18 -6
  40. package/src/ui/SeatSection/SeatSection.tsx +207 -0
  41. package/src/ui/TopAmenities/TopAmenities.tsx +127 -0
  42. package/src/ui/mobileweb/BottomAmenitiesMobile.tsx +169 -0
  43. package/src/ui/mobileweb/DateTimeSectionMobile.tsx +192 -0
  44. package/src/ui/mobileweb/ExpandedDropdownMobile.tsx +56 -0
  45. package/src/ui/mobileweb/SeatSectionMobile.tsx +256 -0
  46. package/src/ui/mobileweb/TopAmenitieMobile.tsx +126 -0
  47. package/src/utils/CommonService.ts +2 -0
@@ -0,0 +1,48 @@
1
+ import React from "react";
2
+
3
+ interface KuposButtonProps {
4
+ isSoldOut: boolean;
5
+ isLoading: boolean;
6
+ buttonColor?: string;
7
+ buyLabel?: string;
8
+ soldOutLabel?: string;
9
+ soldOutIcon?: React.ReactNode;
10
+ onClick: () => void;
11
+ }
12
+
13
+ function KuposButton({
14
+ isSoldOut,
15
+ isLoading,
16
+ buttonColor,
17
+ buyLabel,
18
+ soldOutLabel,
19
+ soldOutIcon,
20
+ onClick,
21
+ }: KuposButtonProps): React.ReactElement {
22
+ const isDisabled = isLoading || isSoldOut;
23
+
24
+ return (
25
+ <button
26
+ onClick={() => (!isSoldOut ? onClick() : null)}
27
+ disabled={isLoading}
28
+ className="w-full py-[12px] text-[12px] font-bold text-white rounded-[14px] border-none px-[20px] flex items-center justify-center"
29
+ style={{
30
+ backgroundColor: isDisabled ? "lightgray" : buttonColor,
31
+ cursor: isDisabled ? "not-allowed" : "pointer",
32
+ }}
33
+ >
34
+ <span className="min-w-[75px] flex justify-center items-center bold-text uppercase">
35
+ {isSoldOut ? soldOutIcon : null}
36
+ {isLoading ? (
37
+ <span className="loader-circle"></span>
38
+ ) : !isSoldOut ? (
39
+ buyLabel
40
+ ) : (
41
+ soldOutLabel
42
+ )}
43
+ </span>
44
+ </button>
45
+ );
46
+ }
47
+
48
+ export default KuposButton;
@@ -13,9 +13,9 @@ const PetBlock = ({ translation, getAnimationIcon, colors, isSoldOut }) => (
13
13
  height="20px"
14
14
  />
15
15
  </div>
16
- <div className="h-auto mr-[4px] text-[13px] text-[#464647]">
16
+ {/* <div className="h-auto mr-[4px] text-[13px] text-[#464647]">
17
17
  <span>{translation?.petFriendly}</span>
18
- </div>
18
+ </div> */}
19
19
  </div>
20
20
  <div
21
21
  className=" hidden group-hover:block absolute top-[24px] left-1/2 -translate-x-1/2 text-white p-3 rounded-[14px] whitespace-normal z-10 mt-2.5 w-[230px] text-center break-normal shadow-service"
@@ -8,8 +8,8 @@ const RatingBlock = ({
8
8
  colors,
9
9
  t,
10
10
  translation,
11
- isPeru = false,
12
- }: any) => (
11
+ isPeru,
12
+ }) => (
13
13
  <div className="flex items-center whitespace-nowrap">
14
14
  {showRating && (
15
15
  <RatingHover
@@ -22,15 +22,27 @@ const RatingBlock = ({
22
22
  />
23
23
  )}
24
24
 
25
- <span
26
- className="ml-[10px] text-[13.33px]"
25
+ <div
26
+ className="group relative ml-[10px] text-[13.33px]"
27
27
  style={{
28
28
  marginLeft: showRating ? "10px" : "0",
29
29
  color: isSoldOut ? "#c0c0c0" : "#464647",
30
30
  }}
31
31
  >
32
- {serviceItem.operator_details[2]}
33
- </span>
32
+ <span className="block max-w-[120px] overflow-hidden text-ellipsis whitespace-nowrap cursor-pointer">
33
+ {serviceItem.operator_details[2]}
34
+ </span>
35
+ <div
36
+ 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]"
37
+ style={{ backgroundColor: colors.bottomStripColor, zIndex: "300" }}
38
+ >
39
+ <div
40
+ 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 "
41
+ style={{ borderBottomColor: colors.bottomStripColor }}
42
+ ></div>
43
+ {serviceItem.operator_details[2]}
44
+ </div>
45
+ </div>
34
46
  </div>
35
47
  );
36
48
 
@@ -0,0 +1,207 @@
1
+ import React from "react";
2
+ import CommonService from "../../utils/CommonService";
3
+
4
+ const SEAT_EXCEPTIONS = ["Asiento mascota"];
5
+
6
+ interface SeatType {
7
+ label: string;
8
+ fare: number;
9
+ key: any;
10
+ }
11
+
12
+ interface SeatSectionProps {
13
+ seatTypes: SeatType[];
14
+ availableSeats: number;
15
+ isSoldOut: boolean;
16
+ priceColor?: string;
17
+ currencySign?: string;
18
+ removeDuplicateSeats?: boolean;
19
+ isPeru?: boolean;
20
+ }
21
+
22
+ function getAllSeatTypes(seatTypes: SeatType[]) {
23
+ if (!seatTypes?.length) {
24
+ return [{ label: "Salon cama", price: 0 }];
25
+ }
26
+
27
+ let seatTypesWithPrices = seatTypes.filter(Boolean).map((val) => ({
28
+ label: val?.label,
29
+ price: val?.fare,
30
+ }));
31
+
32
+ seatTypesWithPrices.sort((a, b) => a.price - b.price);
33
+
34
+ return seatTypesWithPrices;
35
+ }
36
+
37
+ function getSortedSeatTypes(seatTypes: SeatType[]) {
38
+ if (!seatTypes?.length) {
39
+ return [{ label: "Salon cama", price: 0 }];
40
+ }
41
+
42
+ let seatTypesWithPrices = getAllSeatTypes(seatTypes);
43
+ const premiumIndex = seatTypesWithPrices.findIndex(
44
+ (item) => item.label === "Premium",
45
+ );
46
+
47
+ if (premiumIndex >= 3) {
48
+ seatTypesWithPrices[2] = seatTypesWithPrices[premiumIndex];
49
+ }
50
+
51
+ seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
52
+
53
+ const seenPrices = new Set<number>();
54
+ seatTypesWithPrices = seatTypesWithPrices.filter((seat) => {
55
+ if (seenPrices.has(seat.price)) return false;
56
+ seenPrices.add(seat.price);
57
+ return true;
58
+ });
59
+
60
+ return seatTypesWithPrices;
61
+ }
62
+
63
+ function getUniqueSeats(seatTypes: SeatType[]) {
64
+ const allSeatTypes = getAllSeatTypes(seatTypes);
65
+ const seatMap = new Map();
66
+
67
+ allSeatTypes.forEach((seat) => {
68
+ if (SEAT_EXCEPTIONS.includes(seat.label)) return;
69
+
70
+ // Only check if the label already exists in the map, don't compare prices
71
+ if (!seatMap.has(seat.label)) {
72
+ seatMap.set(seat.label, seat);
73
+ }
74
+ });
75
+
76
+ const uniqueByLabel = Array.from(seatMap.values());
77
+ const seenPrices = new Set<number>();
78
+ return uniqueByLabel.filter((seat) => {
79
+ if (seenPrices.has(seat.price)) return false;
80
+ seenPrices.add(seat.price);
81
+ return true;
82
+ });
83
+ }
84
+
85
+ function getNumberOfSeats(seatTypes: SeatType[]) {
86
+ return seatTypes.filter((val) => !SEAT_EXCEPTIONS.includes(val.label)).length;
87
+ }
88
+
89
+ function SeatSection({
90
+ seatTypes,
91
+ availableSeats,
92
+ isSoldOut,
93
+ priceColor,
94
+ currencySign,
95
+ removeDuplicateSeats,
96
+ isPeru,
97
+ }: SeatSectionProps): React.ReactElement {
98
+ const uniqueSeats = getUniqueSeats(seatTypes);
99
+ const sortedSeatTypes = getSortedSeatTypes(seatTypes);
100
+ const numberOfSeats = getNumberOfSeats(seatTypes);
101
+ const isCentered = numberOfSeats < 2 || removeDuplicateSeats;
102
+
103
+ const formatPrice = (price: number) =>
104
+ availableSeats <= 0
105
+ ? CommonService.currency(0, currencySign)
106
+ : CommonService.currency(price, currencySign);
107
+
108
+ const renderSeatNames = () => {
109
+ const seats = removeDuplicateSeats ? uniqueSeats : sortedSeatTypes;
110
+
111
+ return seats.map((val, key: number) =>
112
+ SEAT_EXCEPTIONS.includes(val.label) ? null : (
113
+ <span
114
+ key={key}
115
+ className={`flex items-center justify-between text-[13.33px] ${
116
+ isSoldOut ? "text-[#c0c0c0]" : ""
117
+ }`}
118
+ >
119
+ {typeof val.label === "string" || typeof val.label === "number"
120
+ ? removeDuplicateSeats && isPeru
121
+ ? CommonService.truncateSeatLabel(val.label)
122
+ : val.label
123
+ : null}
124
+ </span>
125
+ ),
126
+ );
127
+ };
128
+
129
+ const renderSeatPrices = () => {
130
+ if (removeDuplicateSeats) {
131
+ return uniqueSeats.map((val, key) => (
132
+ <span key={key}>{formatPrice(val.price)}</span>
133
+ ));
134
+ }
135
+
136
+ return sortedSeatTypes.map((val, key: number) =>
137
+ SEAT_EXCEPTIONS.includes(val.label) ? null : (
138
+ <span key={key} className="flex items-center text-[13.33px] bold-text">
139
+ {typeof val.price === "string" || typeof val.price === "number"
140
+ ? formatPrice(val.price)
141
+ : null}
142
+ </span>
143
+ ),
144
+ );
145
+ };
146
+
147
+ const renderLabels = () => {
148
+ if (isPeru) {
149
+ return (
150
+ <>
151
+ <span
152
+ className="text-[13.33px]"
153
+ style={{
154
+ color: "#999",
155
+ // position: "relative",
156
+ // bottom: numberOfSeats ? "10px" : "",
157
+ }}
158
+ >
159
+ Antes
160
+ </span>
161
+ <span className="text-[13.33px]">Desde</span>
162
+ </>
163
+ );
164
+ }
165
+ return renderSeatNames();
166
+ };
167
+
168
+ const strikethroughStyle: React.CSSProperties = {
169
+ color: "#ccc",
170
+ display: "flex",
171
+ textAlign: "end",
172
+ textDecoration: "line-through",
173
+ ...(isPeru
174
+ ? { position: "relative", top: 0 }
175
+ : { position: "absolute", top: isCentered ? "-10px" : "-18px" }),
176
+ };
177
+
178
+ return (
179
+ <div
180
+ className="relative flex gap-[10px] text-[13.33px] justify-between min-h-[2.2rem]"
181
+ style={isCentered ? { alignItems: "center" } : {}}
182
+ >
183
+ <div className="flex flex-col justify-between" style={{ gap: "10px" }}>
184
+ {renderLabels()}
185
+ </div>
186
+ <div
187
+ className="flex flex-col justify-between absolute inset-y-0 right-0 left-1/2 h-full"
188
+ style={{
189
+ color: isSoldOut ? "#c0c0c0" : priceColor,
190
+ top: 0,
191
+ bottom: 0,
192
+ left: "clamp(60%, 65% + (100vw - 1300px) * 0.1, 65%)",
193
+ right: 0,
194
+ justifyContent: isCentered ? "center" : "",
195
+ gap: "10px",
196
+ }}
197
+ >
198
+ <span className="text-[13.33px]" style={strikethroughStyle}>
199
+ $1.000
200
+ </span>
201
+ {renderSeatPrices()}
202
+ </div>
203
+ </div>
204
+ );
205
+ }
206
+
207
+ export default SeatSection;
@@ -0,0 +1,127 @@
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;
@@ -0,0 +1,169 @@
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;