kupos-ui-components-lib 9.1.2 → 9.1.4
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/README copy.md +67 -223
- package/dist/assets/images/anims/service_list/directo.json +1 -1
- package/dist/components/FilterBar/FilterBarDesktop.d.ts +1 -1
- package/dist/components/FilterBar/FilterBarDesktop.js +38 -3
- package/dist/components/FilterBar/tyoes.d.ts +1 -0
- package/dist/components/ServiceItem/PeruServiceItemDesktop.js +1 -1
- package/dist/components/ServiceItem/RatingHover.js +33 -32
- package/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemDesktop.js +267 -147
- package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemMobile.js +278 -87
- package/dist/components/ServiceItem/mobileTypes.d.ts +0 -5
- package/dist/components/ServiceItem/types.d.ts +0 -7
- package/dist/styles.css +32 -131
- package/dist/ui/AmenitiesBlock.js +30 -23
- package/dist/ui/DurationBlock.js +4 -4
- package/dist/ui/FlexibleBlock.js +6 -5
- package/dist/ui/PetBlock.js +3 -1
- package/dist/ui/RatingBlock.d.ts +1 -9
- package/dist/ui/RatingBlock.js +3 -7
- package/dist/utils/CommonService.d.ts +1 -1
- package/dist/utils/CommonService.js +0 -2
- package/package.json +1 -2
- package/src/assets/images/anims/service_list/directo.json +1 -1
- package/src/components/FilterBar/FilterBarDesktop.tsx +46 -3
- package/src/components/FilterBar/tyoes.ts +1 -0
- package/src/components/ServiceItem/PeruServiceItemDesktop.tsx +0 -1
- package/src/components/ServiceItem/RatingHover.tsx +45 -44
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +537 -313
- package/src/components/ServiceItem/ServiceItemMobile.tsx +530 -213
- package/src/components/ServiceItem/mobileTypes.ts +0 -5
- package/src/components/ServiceItem/types.ts +0 -7
- package/src/ui/AmenitiesBlock.tsx +29 -50
- package/src/ui/DurationBlock.tsx +4 -4
- package/src/ui/FlexibleBlock.tsx +5 -6
- package/src/ui/PetBlock.tsx +2 -2
- package/src/ui/RatingBlock.tsx +6 -18
- package/src/utils/CommonService.ts +0 -2
- package/src/assets/images/anims/service_list/bomb.json +0 -1
- package/src/ui/BottomAmenities/BottomAmenities.tsx +0 -110
- package/src/ui/DateTimeSection/DateTimeSection.tsx +0 -207
- package/src/ui/DirectoBlock.tsx +0 -31
- package/src/ui/ExpendedDropDown/ExpandedDropdown.tsx +0 -103
- package/src/ui/KuposButton/KuposButton.tsx +0 -48
- package/src/ui/SeatSection/SeatSection.tsx +0 -207
- package/src/ui/TopAmenities/TopAmenities.tsx +0 -127
- package/src/ui/mobileweb/BottomAmenitiesMobile.tsx +0 -169
- package/src/ui/mobileweb/DateTimeSectionMobile.tsx +0 -192
- package/src/ui/mobileweb/ExpandedDropdownMobile.tsx +0 -56
- package/src/ui/mobileweb/SeatSectionMobile.tsx +0 -256
- package/src/ui/mobileweb/TopAmenitieMobile.tsx +0 -126
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
2
|
import { ServiceItemProps } from "./types";
|
|
3
|
+
import DateService from "../../utils/DateService";
|
|
3
4
|
import CommonService from "../../utils/CommonService";
|
|
5
|
+
import RatingHover from "./RatingHover";
|
|
4
6
|
import ModalEventManager from "../../utils/ModalEventManager";
|
|
5
7
|
import InternationalServicePopupBody from "../InternationalServicePopupBody";
|
|
6
8
|
import LottiePlayer from "../../assets/LottiePlayer";
|
|
7
9
|
import PeruServiceItemDesktop from "./PeruServiceItemDesktop";
|
|
8
|
-
import ExpandedDropdown from "../../ui/ExpendedDropDown/ExpandedDropdown";
|
|
9
10
|
import promoAnimation from "../../assets/images/anims/service_list/promocion.json";
|
|
10
11
|
import flexibleAnimation from "../../assets/images/anims/service_list/flexible.json";
|
|
11
12
|
import locationAnimation from "../../assets/images/anims/service_list/location.json";
|
|
@@ -17,60 +18,32 @@ import pullmanFlexibleAnimation from "../../assets/images/anims/service_list/pul
|
|
|
17
18
|
import pullmanPetFriendlyAnimation from "../../assets/images/anims/service_list/pullmanPetFriendly.json";
|
|
18
19
|
import pullmanLocationAnimation from "../../assets/images/anims/service_list/pullmanLocation.json";
|
|
19
20
|
import pullmanPriorityStageAnimation from "../../assets/images/anims/service_list/pullmanPriorityStage.json";
|
|
21
|
+
import pullmanPromoAnimation from "../../assets/images/anims/service_list/promocion.json";
|
|
22
|
+
import pullmanDirectoAnimation from "../../assets/images/anims/service_list/directo.json";
|
|
20
23
|
|
|
21
24
|
import opsitesFlexibleAnimation from "../../assets/images/anims/service_list/opsitesFlexible.json";
|
|
22
25
|
import opsitesPetFriendlyAnimation from "../../assets/images/anims/service_list/opsitesPetFriendly.json";
|
|
23
26
|
import opsitesLocationAnimation from "../../assets/images/anims/service_list/opsitesLocation.json";
|
|
24
27
|
import opsitesPriorityStageAnimation from "../../assets/images/anims/service_list/opsitesPriorityStage.json";
|
|
28
|
+
import opsitesPromoAnimation from "../../assets/images/anims/service_list/promocion.json";
|
|
29
|
+
import opsitesDirectoAnimation from "../../assets/images/anims/service_list/directo.json";
|
|
25
30
|
|
|
26
|
-
import
|
|
31
|
+
import linatalFlexibleAnimation from "../../assets/images/anims/service_list/flexible.json";
|
|
32
|
+
import linatalPromoAnimation from "../../assets/images/anims/service_list/promocion.json";
|
|
33
|
+
import linatalDirectoAnimation from "../../assets/images/anims/service_list/directo.json";
|
|
34
|
+
import linatalPriorityStageAnimation from "../../assets/images/anims/service_list/priority_stage.json";
|
|
35
|
+
import linatalPetFriendlyAnimation from "../../assets/images/anims/service_list/pet_friendly.json";
|
|
36
|
+
import linatalLocationAnimation from "../../assets/images/anims/service_list/location.json";
|
|
27
37
|
|
|
28
38
|
import RatingBlock from "../../ui/RatingBlock";
|
|
29
39
|
import DurationBlock from "../../ui/DurationBlock";
|
|
30
|
-
import DirectoBlock from "../../ui/DirectoBlock";
|
|
31
40
|
import PetBlock from "../../ui/PetBlock";
|
|
32
41
|
import FlexibleBlock from "../../ui/FlexibleBlock";
|
|
33
42
|
import AmenitiesBlock from "../../ui/AmenitiesBlock";
|
|
34
|
-
import
|
|
35
|
-
import TopAmenities from "../../ui/TopAmenities/TopAmenities";
|
|
36
|
-
import BottomAmenities from "../../ui/BottomAmenities/BottomAmenities";
|
|
37
|
-
import SeatSection from "../../ui/SeatSection/SeatSection";
|
|
38
|
-
import DateTimeSection from "../../ui/DateTimeSection/DateTimeSection";
|
|
43
|
+
import StageTooltip from "../../ui/StagesTooltip";
|
|
39
44
|
|
|
40
45
|
const SEAT_EXCEPTIONS = ["Asiento mascota"];
|
|
41
46
|
|
|
42
|
-
const ANIMATION_MAP: Record<string, Record<string, any>> = {
|
|
43
|
-
promoAnim: {
|
|
44
|
-
kupos: promoAnimation,
|
|
45
|
-
},
|
|
46
|
-
locationAnim: {
|
|
47
|
-
kupos: locationAnimation,
|
|
48
|
-
pullman: pullmanLocationAnimation,
|
|
49
|
-
opsites: opsitesLocationAnimation,
|
|
50
|
-
},
|
|
51
|
-
directoAnim: {
|
|
52
|
-
kupos: directoAnimation,
|
|
53
|
-
},
|
|
54
|
-
petFriendlyAnim: {
|
|
55
|
-
kupos: petFriendlyAnimation,
|
|
56
|
-
pullman: pullmanPetFriendlyAnimation,
|
|
57
|
-
opsites: opsitesPetFriendlyAnimation,
|
|
58
|
-
},
|
|
59
|
-
priorityStageAnim: {
|
|
60
|
-
kupos: priorityStageAnimation,
|
|
61
|
-
pullman: pullmanPriorityStageAnimation,
|
|
62
|
-
opsites: opsitesPriorityStageAnimation,
|
|
63
|
-
},
|
|
64
|
-
flexibleIcon: {
|
|
65
|
-
kupos: flexibleAnimation,
|
|
66
|
-
pullman: pullmanFlexibleAnimation,
|
|
67
|
-
opsites: opsitesFlexibleAnimation,
|
|
68
|
-
},
|
|
69
|
-
bombAnimation: {
|
|
70
|
-
kupos: bombAnimation,
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
|
|
74
47
|
function ServiceItemPB({
|
|
75
48
|
serviceItem,
|
|
76
49
|
onBookButtonPress,
|
|
@@ -98,12 +71,48 @@ function ServiceItemPB({
|
|
|
98
71
|
t = (key: string) => key,
|
|
99
72
|
siteType,
|
|
100
73
|
isAllinBus,
|
|
101
|
-
isExpand,
|
|
102
|
-
setIsExpand,
|
|
103
|
-
coachKey,
|
|
104
74
|
}: ServiceItemProps & { currencySign?: string }): React.ReactElement {
|
|
75
|
+
const animationMap: Record<string, Record<string, any>> = {
|
|
76
|
+
promoAnim: {
|
|
77
|
+
kupos: promoAnimation,
|
|
78
|
+
pullman: pullmanPromoAnimation,
|
|
79
|
+
opsites: opsitesPromoAnimation,
|
|
80
|
+
linatal: linatalPromoAnimation,
|
|
81
|
+
},
|
|
82
|
+
locationAnim: {
|
|
83
|
+
kupos: locationAnimation,
|
|
84
|
+
pullman: pullmanLocationAnimation,
|
|
85
|
+
opsites: opsitesLocationAnimation,
|
|
86
|
+
linatal: linatalLocationAnimation,
|
|
87
|
+
},
|
|
88
|
+
directoAnim: {
|
|
89
|
+
kupos: directoAnimation,
|
|
90
|
+
pullman: pullmanDirectoAnimation,
|
|
91
|
+
opsites: opsitesDirectoAnimation,
|
|
92
|
+
linatal: linatalDirectoAnimation,
|
|
93
|
+
},
|
|
94
|
+
petFriendlyAnim: {
|
|
95
|
+
kupos: petFriendlyAnimation,
|
|
96
|
+
pullman: pullmanPetFriendlyAnimation,
|
|
97
|
+
opsites: opsitesPetFriendlyAnimation,
|
|
98
|
+
linatal: linatalPetFriendlyAnimation,
|
|
99
|
+
},
|
|
100
|
+
priorityStageAnim: {
|
|
101
|
+
kupos: priorityStageAnimation,
|
|
102
|
+
pullman: pullmanPriorityStageAnimation,
|
|
103
|
+
opsites: opsitesPriorityStageAnimation,
|
|
104
|
+
linatal: linatalPriorityStageAnimation,
|
|
105
|
+
},
|
|
106
|
+
flexibleIcon: {
|
|
107
|
+
kupos: flexibleAnimation,
|
|
108
|
+
pullman: pullmanFlexibleAnimation,
|
|
109
|
+
opsites: opsitesFlexibleAnimation,
|
|
110
|
+
linatal: linatalFlexibleAnimation,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
105
114
|
const getAnimationIcon = (icon: string) => {
|
|
106
|
-
const animation =
|
|
115
|
+
const animation = animationMap[icon];
|
|
107
116
|
if (!animation) return null;
|
|
108
117
|
return animation[siteType] ?? animation.kupos;
|
|
109
118
|
};
|
|
@@ -142,7 +151,9 @@ function ServiceItemPB({
|
|
|
142
151
|
style={{
|
|
143
152
|
filter: color === "white" ? "brightness(0) invert(1)" : "",
|
|
144
153
|
}}
|
|
145
|
-
className=
|
|
154
|
+
className={`object-contain ${
|
|
155
|
+
moreAnemities ? "w-[16px] h-[16px]" : "w-[16px] h-[16px]"
|
|
156
|
+
}`}
|
|
146
157
|
/>
|
|
147
158
|
);
|
|
148
159
|
};
|
|
@@ -160,11 +171,6 @@ function ServiceItemPB({
|
|
|
160
171
|
|
|
161
172
|
let isSoldOut = serviceItem.available_seats <= 0;
|
|
162
173
|
|
|
163
|
-
const showPromo = Math.random() > 0.5;
|
|
164
|
-
|
|
165
|
-
const isItemExpanded = serviceItem.id === isExpand || isExpand === true;
|
|
166
|
-
const grayscaleClass = isSoldOut ? "grayscale" : "";
|
|
167
|
-
|
|
168
174
|
const renderIcon = (iconKey: string, size: string = "14px") => {
|
|
169
175
|
const iconValue = serviceItem.icons?.[iconKey];
|
|
170
176
|
if (iconValue) {
|
|
@@ -173,7 +179,7 @@ function ServiceItemPB({
|
|
|
173
179
|
<img
|
|
174
180
|
src={iconValue}
|
|
175
181
|
alt={iconKey}
|
|
176
|
-
className={`${`w-[${size}] h-[${size}]`} `}
|
|
182
|
+
className={`${`w-[${size}] h-[${size}]`} mr-[5px]`}
|
|
177
183
|
/>
|
|
178
184
|
);
|
|
179
185
|
}
|
|
@@ -181,8 +187,136 @@ function ServiceItemPB({
|
|
|
181
187
|
return null;
|
|
182
188
|
};
|
|
183
189
|
|
|
190
|
+
const getAllSeatTypes = () => {
|
|
191
|
+
if (!serviceItem?.seat_types?.length) {
|
|
192
|
+
return [{ label: "Salon cama", price: 0 }];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
let seatTypesWithPrices = serviceItem.seat_types
|
|
196
|
+
.filter((item) => getFilteredSeats(item))
|
|
197
|
+
.map((val) => ({
|
|
198
|
+
label: val?.label,
|
|
199
|
+
price: val?.fare,
|
|
200
|
+
}));
|
|
201
|
+
|
|
202
|
+
seatTypesWithPrices.sort((a, b) => a.price - b.price);
|
|
203
|
+
|
|
204
|
+
return seatTypesWithPrices;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const getSortedSeatTypes = () => {
|
|
208
|
+
if (!serviceItem?.seat_types?.length) {
|
|
209
|
+
return [{ label: "Salon cama", price: 0 }];
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
let seatTypesWithPrices = getAllSeatTypes();
|
|
213
|
+
const premiumIndex = seatTypesWithPrices.findIndex(
|
|
214
|
+
(item) => item.label === "Premium",
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
if (premiumIndex >= 3) {
|
|
218
|
+
seatTypesWithPrices[2] = seatTypesWithPrices[premiumIndex];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
|
|
222
|
+
|
|
223
|
+
return seatTypesWithPrices;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const getUniqueSeats = () => {
|
|
227
|
+
const allSeatTypes = getAllSeatTypes();
|
|
228
|
+
const seatMap = new Map();
|
|
229
|
+
|
|
230
|
+
allSeatTypes.forEach((seat) => {
|
|
231
|
+
if (SEAT_EXCEPTIONS.includes(seat.label)) return;
|
|
232
|
+
|
|
233
|
+
// Only check if the label already exists in the map, don't compare prices
|
|
234
|
+
if (!seatMap.has(seat.label)) {
|
|
235
|
+
seatMap.set(seat.label, seat);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
return Array.from(seatMap.values());
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const getNumberOfSeats = () => {
|
|
243
|
+
return serviceItem.seat_types.filter(
|
|
244
|
+
(val) => !SEAT_EXCEPTIONS.includes(val.label),
|
|
245
|
+
).length;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const getSeatNames = () => {
|
|
249
|
+
const uniqueSeats = getUniqueSeats();
|
|
250
|
+
const sortedSeatTypes = getSortedSeatTypes();
|
|
251
|
+
|
|
252
|
+
if (removeDuplicateSeats) {
|
|
253
|
+
return uniqueSeats.map((val, key: number) =>
|
|
254
|
+
SEAT_EXCEPTIONS.includes(val.label) ? null : (
|
|
255
|
+
<span
|
|
256
|
+
key={key}
|
|
257
|
+
className={`flex items-center justify-between text-[13.33px] ${
|
|
258
|
+
isSoldOut ? "text-[#c0c0c0]" : ""
|
|
259
|
+
}`}
|
|
260
|
+
>
|
|
261
|
+
{typeof val.label === "string" || typeof val.label === "number"
|
|
262
|
+
? isPeru
|
|
263
|
+
? CommonService.truncateSeatLabel(val.label)
|
|
264
|
+
: val.label
|
|
265
|
+
: null}
|
|
266
|
+
</span>
|
|
267
|
+
),
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
return sortedSeatTypes.map((val, key: number) =>
|
|
271
|
+
SEAT_EXCEPTIONS.includes(val.label) ? null : (
|
|
272
|
+
<span
|
|
273
|
+
key={key}
|
|
274
|
+
className={`flex items-center justify-between text-[13.33px] ${
|
|
275
|
+
isSoldOut ? "text-[#c0c0c0]" : ""
|
|
276
|
+
}`}
|
|
277
|
+
>
|
|
278
|
+
{typeof val.label === "string" || typeof val.label === "number"
|
|
279
|
+
? val.label
|
|
280
|
+
: null}
|
|
281
|
+
</span>
|
|
282
|
+
),
|
|
283
|
+
);
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const getSeatPrice = () => {
|
|
287
|
+
const sortedSeatTypes = getSortedSeatTypes();
|
|
288
|
+
const uniqueSeats = getUniqueSeats();
|
|
289
|
+
if (removeDuplicateSeats) {
|
|
290
|
+
return uniqueSeats.map((val, key) => (
|
|
291
|
+
<span key={key}>
|
|
292
|
+
{serviceItem?.available_seats <= 0
|
|
293
|
+
? CommonService.currency(0, currencySign)
|
|
294
|
+
: CommonService.currency(val.price, currencySign)}
|
|
295
|
+
</span>
|
|
296
|
+
));
|
|
297
|
+
}
|
|
298
|
+
return sortedSeatTypes.map((val, key: number) => {
|
|
299
|
+
return SEAT_EXCEPTIONS.includes(val.label) ? null : (
|
|
300
|
+
<span key={key} className="flex items-center text-[13.33px] bold-text">
|
|
301
|
+
{typeof val.price === "string"
|
|
302
|
+
? serviceItem?.available_seats <= 0
|
|
303
|
+
? CommonService.currency(0, currencySign)
|
|
304
|
+
: CommonService.currency(val.price, currencySign)
|
|
305
|
+
: typeof val.price === "number"
|
|
306
|
+
? serviceItem?.available_seats <= 0
|
|
307
|
+
? CommonService.currency(0, currencySign)
|
|
308
|
+
: CommonService.currency(val.price, currencySign)
|
|
309
|
+
: null}
|
|
310
|
+
</span>
|
|
311
|
+
);
|
|
312
|
+
});
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const getFilteredSeats = (item) => {
|
|
316
|
+
return item;
|
|
317
|
+
};
|
|
318
|
+
|
|
184
319
|
const checkMidnight = () => {
|
|
185
|
-
setIsExpand?.(null);
|
|
186
320
|
if (
|
|
187
321
|
cityOrigin?.label &&
|
|
188
322
|
cityDestination?.label &&
|
|
@@ -261,63 +395,57 @@ function ServiceItemPB({
|
|
|
261
395
|
),
|
|
262
396
|
});
|
|
263
397
|
return;
|
|
398
|
+
} else {
|
|
399
|
+
onBookButtonPress();
|
|
264
400
|
}
|
|
265
|
-
|
|
266
|
-
onBookButtonPress();
|
|
267
401
|
};
|
|
268
402
|
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
node.textContent = formatTime(remaining);
|
|
295
|
-
}, 1000);
|
|
296
|
-
|
|
297
|
-
node.dataset.countdownId = String(id);
|
|
298
|
-
};
|
|
403
|
+
const depTime = serviceItem.dep_time || "";
|
|
404
|
+
|
|
405
|
+
// Extract hours and minutes and check for AM/PM
|
|
406
|
+
const hasAM = depTime.includes("AM");
|
|
407
|
+
const hasPM = depTime.includes("PM");
|
|
408
|
+
const [timePart] = depTime.split(/AM|PM/).map((part) => part.trim());
|
|
409
|
+
const [hour, minute] = timePart.split(":").map(Number);
|
|
410
|
+
|
|
411
|
+
// Convert to 24-hour format
|
|
412
|
+
let cleanedDepTime;
|
|
413
|
+
if (hasAM) {
|
|
414
|
+
cleanedDepTime =
|
|
415
|
+
hour === 12
|
|
416
|
+
? `00:${minute < 10 ? "0" + minute : minute}`
|
|
417
|
+
: `${hour < 10 ? "0" + hour : hour}:${
|
|
418
|
+
minute < 10 ? "0" + minute : minute
|
|
419
|
+
}`;
|
|
420
|
+
} else if (hasPM) {
|
|
421
|
+
cleanedDepTime =
|
|
422
|
+
hour === 12
|
|
423
|
+
? `${hour}:${minute < 10 ? "0" + minute : minute}`
|
|
424
|
+
: `${hour + 12}:${minute < 10 ? "0" + minute : minute}`;
|
|
425
|
+
} else {
|
|
426
|
+
cleanedDepTime = timePart;
|
|
427
|
+
}
|
|
299
428
|
|
|
300
429
|
const items = [
|
|
301
430
|
{
|
|
302
|
-
key: "
|
|
303
|
-
width: "
|
|
304
|
-
condition: true,
|
|
431
|
+
key: "rating",
|
|
432
|
+
width: "30%",
|
|
305
433
|
render: (
|
|
306
|
-
<
|
|
434
|
+
<RatingBlock
|
|
435
|
+
showRating={showRating}
|
|
307
436
|
serviceItem={serviceItem}
|
|
308
|
-
metaData={metaData}
|
|
309
437
|
isSoldOut={isSoldOut}
|
|
310
438
|
colors={colors}
|
|
439
|
+
t={t}
|
|
440
|
+
translation={translation}
|
|
311
441
|
isPeru={isPeru}
|
|
312
|
-
getAnimationIcon={getAnimationIcon}
|
|
313
|
-
getAmenityName={CommonService.getAmenityName}
|
|
314
|
-
SvgAmenities={SvgAmenities}
|
|
315
442
|
/>
|
|
316
443
|
),
|
|
317
444
|
},
|
|
445
|
+
|
|
318
446
|
{
|
|
319
447
|
key: "duration",
|
|
320
|
-
width: "
|
|
448
|
+
width: "20%",
|
|
321
449
|
condition: serviceItem.duration,
|
|
322
450
|
render: (
|
|
323
451
|
<DurationBlock
|
|
@@ -330,20 +458,6 @@ function ServiceItemPB({
|
|
|
330
458
|
),
|
|
331
459
|
},
|
|
332
460
|
|
|
333
|
-
{
|
|
334
|
-
key: "directo",
|
|
335
|
-
width: "12%",
|
|
336
|
-
condition: serviceItem?.is_direct_trip === true,
|
|
337
|
-
render: (
|
|
338
|
-
<DirectoBlock
|
|
339
|
-
translation={translation}
|
|
340
|
-
getAnimationIcon={getAnimationIcon}
|
|
341
|
-
colors={colors}
|
|
342
|
-
isSoldOut={isSoldOut}
|
|
343
|
-
/>
|
|
344
|
-
),
|
|
345
|
-
},
|
|
346
|
-
|
|
347
461
|
{
|
|
348
462
|
key: "pet",
|
|
349
463
|
width: "20%",
|
|
@@ -374,10 +488,28 @@ function ServiceItemPB({
|
|
|
374
488
|
/>
|
|
375
489
|
),
|
|
376
490
|
},
|
|
491
|
+
|
|
492
|
+
{
|
|
493
|
+
key: "amenities",
|
|
494
|
+
width: "20%",
|
|
495
|
+
render: (
|
|
496
|
+
<AmenitiesBlock
|
|
497
|
+
serviceItem={serviceItem}
|
|
498
|
+
metaData={metaData}
|
|
499
|
+
isSoldOut={isSoldOut}
|
|
500
|
+
colors={colors}
|
|
501
|
+
isPeru={isPeru}
|
|
502
|
+
getAnimationIcon={getAnimationIcon}
|
|
503
|
+
getAmenityName={CommonService.getAmenityName}
|
|
504
|
+
SvgAmenities={SvgAmenities}
|
|
505
|
+
/>
|
|
506
|
+
),
|
|
507
|
+
},
|
|
377
508
|
];
|
|
378
509
|
|
|
510
|
+
const amenitiesItem = items.find((i) => i.key === "amenities");
|
|
379
511
|
const otherItems = items.filter(
|
|
380
|
-
(i) => i.key !== "
|
|
512
|
+
(i) => i.key !== "amenities" && i.condition !== false,
|
|
381
513
|
);
|
|
382
514
|
|
|
383
515
|
return (
|
|
@@ -412,10 +544,6 @@ function ServiceItemPB({
|
|
|
412
544
|
/>
|
|
413
545
|
) : (
|
|
414
546
|
<div
|
|
415
|
-
// className={`relative ${
|
|
416
|
-
// serviceItem.offer_text ? "mb-[55px]" : "mb-[10px]"
|
|
417
|
-
// } mt-[14px]`}
|
|
418
|
-
|
|
419
547
|
className={`relative ${
|
|
420
548
|
serviceItem.offer_text ? "mb-[55px]" : "mb-[10px]"
|
|
421
549
|
} ${
|
|
@@ -426,105 +554,182 @@ function ServiceItemPB({
|
|
|
426
554
|
: "mt-[20px]"
|
|
427
555
|
} `}
|
|
428
556
|
>
|
|
429
|
-
{/* <TopAmenities
|
|
430
|
-
showPromo={showPromo}
|
|
431
|
-
showTopLabel={showTopLabel}
|
|
432
|
-
isSoldOut={isSoldOut}
|
|
433
|
-
priceColor={colors.priceColor}
|
|
434
|
-
buttonColor={colors.kuposButtonColor}
|
|
435
|
-
boardingIcon={renderIcon("whiteBoardingIcon", "14px")}
|
|
436
|
-
getAnimationIcon={getAnimationIcon}
|
|
437
|
-
countdownSeconds={countdownSeconds}
|
|
438
|
-
onCountdownEnd={() => {
|
|
439
|
-
const cardEl = document.getElementById(
|
|
440
|
-
`service-card-${serviceItem.id}`,
|
|
441
|
-
);
|
|
442
|
-
if (!cardEl) return;
|
|
443
|
-
cardEl.style.border = "1px solid #ccc";
|
|
444
|
-
if (!showTopLabel) {
|
|
445
|
-
cardEl.style.borderRadius = "10px";
|
|
446
|
-
}
|
|
447
|
-
}}
|
|
448
|
-
offerText={serviceItem?.offer_text}
|
|
449
|
-
/> */}
|
|
450
557
|
<div
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
// border:
|
|
455
|
-
// countdownSeconds > 0 && serviceItem?.offer_text
|
|
456
|
-
// ? `1px solid ${colors.priceColor}`
|
|
457
|
-
// : "1px solid #ccc",
|
|
458
|
-
// borderRadius: showTopLabel
|
|
459
|
-
// ? "10px 0 10px 10px"
|
|
460
|
-
// : countdownSeconds > 0 && serviceItem?.offer_text
|
|
461
|
-
// ? "10px 0 10px 10px"
|
|
462
|
-
// : "10px",
|
|
463
|
-
// }}
|
|
558
|
+
className={
|
|
559
|
+
"bg-white rounded-[20px] shadow-service mx-auto relative"
|
|
560
|
+
}
|
|
464
561
|
>
|
|
465
|
-
<div
|
|
466
|
-
// className="p-[15px] pt-[20px]"
|
|
467
|
-
className=" pt-[20px]"
|
|
468
|
-
style={{
|
|
469
|
-
padding: coachKey
|
|
470
|
-
? "15px 15px 20px 15px"
|
|
471
|
-
: "20px 15px 11px 15px",
|
|
472
|
-
}}
|
|
473
|
-
>
|
|
562
|
+
<div className="p-[15px] pt-[20px]">
|
|
474
563
|
<div
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
// style={{ marginTop: showTopLabel ? "8px" : "" }}
|
|
564
|
+
className="grid text-[#464647] w-full [grid-template-columns:14%_30%_2.5%_30%_15.5%] gap-x-[2%] items-center"
|
|
565
|
+
style={{ marginTop: showTopLabel ? "8px" : "" }}
|
|
478
566
|
>
|
|
479
567
|
{/* OPERATOR LOGO */}
|
|
480
|
-
<div
|
|
481
|
-
|
|
482
|
-
display: "flex",
|
|
483
|
-
flexDirection: "column",
|
|
484
|
-
gap: "5px",
|
|
485
|
-
}}
|
|
486
|
-
>
|
|
487
|
-
<div
|
|
488
|
-
// className="flex items-center justify-center m-[auto]"
|
|
489
|
-
className=""
|
|
490
|
-
>
|
|
568
|
+
<div className="flex items-center justify-center m-[auto]">
|
|
569
|
+
<div className=" ">
|
|
491
570
|
<img
|
|
492
571
|
src={serviceItem.operator_details[0]}
|
|
493
572
|
alt="service logo"
|
|
494
|
-
className={`h-auto
|
|
573
|
+
className={` h-auto object-contain ${
|
|
495
574
|
isSoldOut ? "grayscale" : ""
|
|
496
575
|
}`}
|
|
497
576
|
/>
|
|
498
|
-
{isCiva ? (
|
|
499
|
-
<div className="text-[13.33px] black-text ml-2">
|
|
500
|
-
{serviceItem.operator_details[2]}
|
|
501
|
-
</div>
|
|
502
|
-
) : null}
|
|
503
577
|
</div>
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
t={t}
|
|
510
|
-
translation={translation}
|
|
511
|
-
isPeru={isPeru}
|
|
512
|
-
/>
|
|
578
|
+
{isCiva ? (
|
|
579
|
+
<div className="text-[13.33px] black-text ml-2">
|
|
580
|
+
{serviceItem.operator_details[2]}
|
|
581
|
+
</div>
|
|
582
|
+
) : null}
|
|
513
583
|
</div>
|
|
514
584
|
|
|
515
585
|
{/* DATE AND TIME - Grid Layout */}
|
|
516
|
-
<
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
586
|
+
<div
|
|
587
|
+
className={`min-h-[2.5rem] grid grid-cols-[26px_auto_26%_1fr] gap-x-4 items-center text-[13.33px] ${
|
|
588
|
+
isSoldOut ? "text-[#c0c0c0]" : ""
|
|
589
|
+
}`}
|
|
590
|
+
style={{
|
|
591
|
+
gridTemplateRows: "1fr",
|
|
592
|
+
}}
|
|
593
|
+
>
|
|
594
|
+
{/* ICONS COLUMN */}
|
|
595
|
+
<div className="flex flex-col gap-[6px]">
|
|
596
|
+
{/* Origin Icon */}
|
|
597
|
+
{orignLabel ? (
|
|
598
|
+
<div className="w-[60px] h-[20px] flex items-center">
|
|
599
|
+
{orignLabel}
|
|
600
|
+
</div>
|
|
601
|
+
) : (
|
|
602
|
+
<div className="h-[20px] flex items-center">
|
|
603
|
+
<img
|
|
604
|
+
src={serviceItem.icons?.origin}
|
|
605
|
+
alt="origin"
|
|
606
|
+
className={`w-[18px] h-auto mr-[8px] ${
|
|
607
|
+
isSoldOut ? "grayscale" : ""
|
|
608
|
+
}`}
|
|
609
|
+
/>
|
|
610
|
+
</div>
|
|
611
|
+
)}
|
|
612
|
+
|
|
613
|
+
{/* Destination Icon */}
|
|
614
|
+
{!isCiva &&
|
|
615
|
+
(destinationLabel ? (
|
|
616
|
+
<div className="w-[60px] h-[20px] flex items-center">
|
|
617
|
+
{destinationLabel}
|
|
618
|
+
</div>
|
|
619
|
+
) : (
|
|
620
|
+
<div className="h-[20px] flex items-center">
|
|
621
|
+
<img
|
|
622
|
+
src={serviceItem.icons?.destination}
|
|
623
|
+
className={`w-[18px] h-auto mr-[8px] ${
|
|
624
|
+
isSoldOut ? "grayscale" : ""
|
|
625
|
+
}`}
|
|
626
|
+
style={{ opacity: isSoldOut ? 0.5 : 1 }}
|
|
627
|
+
/>
|
|
628
|
+
</div>
|
|
629
|
+
))}
|
|
630
|
+
</div>
|
|
631
|
+
|
|
632
|
+
{/* DATES COLUMN */}
|
|
633
|
+
<div className="flex flex-col gap-[6px]">
|
|
634
|
+
{/* Departure Date */}
|
|
635
|
+
<StageTooltip
|
|
636
|
+
stageData={serviceItem.boarding_stages}
|
|
637
|
+
direction={1}
|
|
638
|
+
terminals={busStage}
|
|
639
|
+
serviceItem={serviceItem}
|
|
640
|
+
metaData={metaData}
|
|
641
|
+
colors={colors}
|
|
642
|
+
>
|
|
643
|
+
<span className="cursor-pointer bold-text capitalize">
|
|
644
|
+
{DateService.getServiceItemDate(
|
|
645
|
+
serviceItem.travel_date,
|
|
646
|
+
)}
|
|
647
|
+
</span>
|
|
648
|
+
</StageTooltip>
|
|
649
|
+
|
|
650
|
+
{/* Arrival Date */}
|
|
651
|
+
{!isCiva && (
|
|
652
|
+
<StageTooltip
|
|
653
|
+
stageData={serviceItem.boarding_stages}
|
|
654
|
+
direction={1}
|
|
655
|
+
terminals={busStage}
|
|
656
|
+
serviceItem={serviceItem}
|
|
657
|
+
metaData={metaData}
|
|
658
|
+
colors={colors}
|
|
659
|
+
>
|
|
660
|
+
<span className="cursor-pointer bold-text capitalize">
|
|
661
|
+
{DateService.getServiceItemDate(
|
|
662
|
+
serviceItem.arrival_date,
|
|
663
|
+
)}
|
|
664
|
+
</span>
|
|
665
|
+
</StageTooltip>
|
|
666
|
+
)}
|
|
667
|
+
</div>
|
|
668
|
+
|
|
669
|
+
{/* DOTS COLUMN */}
|
|
670
|
+
<div className="flex flex-col gap-[6px] items-center">
|
|
671
|
+
{/* Departure Dot */}
|
|
672
|
+
<div className="h-[20px] flex items-center justify-center">
|
|
673
|
+
<div>•</div>
|
|
674
|
+
</div>
|
|
675
|
+
|
|
676
|
+
{/* Arrival Dot */}
|
|
677
|
+
{!isCiva && (
|
|
678
|
+
<div className="h-[20px] flex items-center justify-center">
|
|
679
|
+
{removeArrivalTime ? null : serviceItem.arr_time ? (
|
|
680
|
+
<div>•</div>
|
|
681
|
+
) : null}
|
|
682
|
+
</div>
|
|
683
|
+
)}
|
|
684
|
+
</div>
|
|
685
|
+
|
|
686
|
+
{/* TIMES COLUMN */}
|
|
687
|
+
<div className="flex flex-col gap-[6px]">
|
|
688
|
+
{/* Departure Time */}
|
|
689
|
+
<StageTooltip
|
|
690
|
+
stageData={serviceItem.dropoff_stages}
|
|
691
|
+
direction={2}
|
|
692
|
+
terminals={busStage}
|
|
693
|
+
serviceItem={serviceItem}
|
|
694
|
+
metaData={metaData}
|
|
695
|
+
colors={colors}
|
|
696
|
+
>
|
|
697
|
+
<div className="font-[900] bold-text">
|
|
698
|
+
{isLinatal ? (
|
|
699
|
+
<>
|
|
700
|
+
{cleanedDepTime}{" "}
|
|
701
|
+
<span>{hasPM ? "PM" : hasAM ? "AM" : ""}</span>
|
|
702
|
+
{!serviceItem?.dep_time.includes("AM") &&
|
|
703
|
+
!serviceItem?.dep_time.includes("PM") &&
|
|
704
|
+
DateService.ampmOnly(serviceItem.dep_time)}
|
|
705
|
+
</>
|
|
706
|
+
) : (
|
|
707
|
+
DateService.formatTime(serviceItem.dep_time)
|
|
708
|
+
)}
|
|
709
|
+
</div>
|
|
710
|
+
</StageTooltip>
|
|
711
|
+
|
|
712
|
+
{/* Arrival Time */}
|
|
713
|
+
{!isCiva && (
|
|
714
|
+
<StageTooltip
|
|
715
|
+
stageData={serviceItem.dropoff_stages}
|
|
716
|
+
direction={2}
|
|
717
|
+
terminals={busStage}
|
|
718
|
+
serviceItem={serviceItem}
|
|
719
|
+
metaData={metaData}
|
|
720
|
+
colors={colors}
|
|
721
|
+
>
|
|
722
|
+
<div className="font-[900] bold-text">
|
|
723
|
+
{removeArrivalTime
|
|
724
|
+
? null
|
|
725
|
+
: serviceItem.arr_time
|
|
726
|
+
? DateService.formatTime(serviceItem.arr_time)
|
|
727
|
+
: null}
|
|
728
|
+
</div>
|
|
729
|
+
</StageTooltip>
|
|
730
|
+
)}
|
|
731
|
+
</div>
|
|
732
|
+
</div>
|
|
528
733
|
<div
|
|
529
734
|
style={{
|
|
530
735
|
width: "1px",
|
|
@@ -534,84 +739,139 @@ function ServiceItemPB({
|
|
|
534
739
|
></div>
|
|
535
740
|
{/* SEATS */}
|
|
536
741
|
<div className="content-center">
|
|
537
|
-
<
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
{/* BUTTON */}
|
|
549
|
-
|
|
550
|
-
<div>
|
|
551
|
-
{showLastSeats ? (
|
|
742
|
+
<div
|
|
743
|
+
className={`relative flex gap-[10px] text-[13.33px] justify-between min-h-[2.5rem] ${
|
|
744
|
+
getNumberOfSeats() < 3 ? "" : ""
|
|
745
|
+
}`}
|
|
746
|
+
style={
|
|
747
|
+
getNumberOfSeats() < 2 || removeDuplicateSeats
|
|
748
|
+
? { alignItems: "center" }
|
|
749
|
+
: {}
|
|
750
|
+
}
|
|
751
|
+
>
|
|
552
752
|
<div
|
|
553
|
-
className="flex
|
|
753
|
+
className="flex flex-col justify-between"
|
|
754
|
+
style={{ gap: "10px" }}
|
|
755
|
+
>
|
|
756
|
+
{getSeatNames()}
|
|
757
|
+
</div>
|
|
758
|
+
<div
|
|
759
|
+
className="flex flex-col justify-between absolute inset-y-0 right-0 left-1/2 h-full"
|
|
554
760
|
style={{
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
761
|
+
color: isSoldOut ? "#c0c0c0" : colors.priceColor,
|
|
762
|
+
top: 0,
|
|
763
|
+
bottom: 0,
|
|
764
|
+
left: "clamp(60%, 65% + (100vw - 1300px) * 0.1, 65%)",
|
|
765
|
+
// left: "68%",
|
|
766
|
+
right: 0,
|
|
767
|
+
justifyContent:
|
|
768
|
+
getNumberOfSeats() < 2 || removeDuplicateSeats
|
|
769
|
+
? "center"
|
|
770
|
+
: "",
|
|
771
|
+
gap: "10px",
|
|
560
772
|
}}
|
|
561
773
|
>
|
|
562
|
-
{
|
|
563
|
-
serviceItem?.available_seats > 0 && (
|
|
564
|
-
<div className="text-[12.5px] text-[#464647] mt-1 text-center">
|
|
565
|
-
¡Últimos Asientos!
|
|
566
|
-
</div>
|
|
567
|
-
)}
|
|
774
|
+
{getSeatPrice()}
|
|
568
775
|
</div>
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
776
|
+
</div>
|
|
777
|
+
</div>
|
|
778
|
+
|
|
779
|
+
{/* BUTTON */}
|
|
780
|
+
<div>
|
|
781
|
+
<button
|
|
782
|
+
onClick={() => (!isSoldOut ? checkMidnight() : null)}
|
|
783
|
+
disabled={serviceDetailsLoading}
|
|
784
|
+
className={`w-full ${
|
|
785
|
+
serviceDetailsLoading || isSoldOut
|
|
786
|
+
? "py-[12px]"
|
|
787
|
+
: "py-[12px]"
|
|
788
|
+
} text-[13.33px] font-bold text-white rounded-[10px] border-none px-[20px] flex items-center justify-center`}
|
|
789
|
+
style={{
|
|
790
|
+
backgroundColor:
|
|
791
|
+
serviceDetailsLoading || isSoldOut
|
|
792
|
+
? "lightgray"
|
|
793
|
+
: colors.kuposButtonColor,
|
|
794
|
+
cursor:
|
|
795
|
+
serviceDetailsLoading || isSoldOut
|
|
796
|
+
? "not-allowed"
|
|
797
|
+
: "pointer",
|
|
798
|
+
}}
|
|
799
|
+
>
|
|
800
|
+
<span className="min-w-[75px] flex justify-center items-center bold-text uppercase">
|
|
801
|
+
{isSoldOut ? renderIcon("soldOutIcon", "14px") : null}
|
|
802
|
+
|
|
803
|
+
{serviceDetailsLoading ? (
|
|
804
|
+
<span className="loader-circle"></span>
|
|
805
|
+
) : !isSoldOut ? (
|
|
806
|
+
translation?.buyButton
|
|
807
|
+
) : (
|
|
808
|
+
translation?.soldOutButton
|
|
809
|
+
)}
|
|
810
|
+
</span>
|
|
811
|
+
</button>
|
|
579
812
|
</div>
|
|
580
813
|
</div>
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
onToggleExpand={() =>
|
|
592
|
-
setIsExpand &&
|
|
593
|
-
setIsExpand(isItemExpanded ? null : serviceItem.id)
|
|
594
|
-
}
|
|
595
|
-
/>
|
|
596
|
-
</div>
|
|
597
|
-
</div>
|
|
814
|
+
{showLastSeats ? (
|
|
815
|
+
<div className="flex justify-end mr-[11px]">
|
|
816
|
+
{serviceItem?.available_seats < 10 &&
|
|
817
|
+
serviceItem?.available_seats > 0 && (
|
|
818
|
+
<div className="text-[12px] text-[red] mt-1 text-center">
|
|
819
|
+
¡ Últimos Asientos!
|
|
820
|
+
</div>
|
|
821
|
+
)}
|
|
822
|
+
</div>
|
|
823
|
+
) : null}
|
|
598
824
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
825
|
+
{/* <div className="flex items-center mt-[15px] border-t border-[#eee] pt-[10px]">
|
|
826
|
+
<div
|
|
827
|
+
className="grid items-center gap-[12px] w-full"
|
|
828
|
+
style={{
|
|
829
|
+
gridTemplateColumns: "30% 20% 20% 20% auto",
|
|
830
|
+
}}
|
|
831
|
+
>
|
|
832
|
+
{items
|
|
833
|
+
.sort((a, b) =>
|
|
834
|
+
a.key === "amenities"
|
|
835
|
+
? 1
|
|
836
|
+
: b.key === "amenities"
|
|
837
|
+
? -1
|
|
838
|
+
: 0,
|
|
839
|
+
)
|
|
840
|
+
.map((item) => (
|
|
841
|
+
<div key={item.key} className="flex items-center">
|
|
842
|
+
{item.condition === false ? (
|
|
843
|
+
<div style={{ minHeight: "20px", width: "100%" }} />
|
|
844
|
+
) : (
|
|
845
|
+
item.render
|
|
846
|
+
)}
|
|
847
|
+
</div>
|
|
848
|
+
))}
|
|
849
|
+
</div>
|
|
850
|
+
</div> */}
|
|
851
|
+
|
|
852
|
+
<div className="flex items-center mt-[15px] border-t border-[#eee] pt-[10px]">
|
|
853
|
+
{/* 🔹 LEFT SIDE (GRID ITEMS) */}
|
|
854
|
+
<div
|
|
855
|
+
className="grid items-center gap-[2%] flex-1"
|
|
856
|
+
style={{
|
|
857
|
+
gridTemplateColumns: "40% 18% 23% 23%",
|
|
858
|
+
// otherItems
|
|
859
|
+
// .map((i) => i.width)
|
|
860
|
+
// .join(" "),
|
|
861
|
+
}}
|
|
862
|
+
>
|
|
863
|
+
{otherItems.map((item) => (
|
|
864
|
+
<div key={item.key} className="flex items-center ">
|
|
865
|
+
{item.render}
|
|
866
|
+
</div>
|
|
867
|
+
))}
|
|
868
|
+
</div>
|
|
869
|
+
|
|
870
|
+
{/* 🔹 RIGHT SIDE (ALWAYS END) */}
|
|
871
|
+
<div className="flex items-center ml-[12px] shrink-0 w-[130px] justify-end">
|
|
872
|
+
{amenitiesItem?.render}
|
|
873
|
+
</div>
|
|
874
|
+
</div>
|
|
615
875
|
</div>
|
|
616
876
|
</div>
|
|
617
877
|
|
|
@@ -619,63 +879,27 @@ function ServiceItemPB({
|
|
|
619
879
|
{/* Bottom discount banner */}
|
|
620
880
|
{serviceItem?.offer_text && (
|
|
621
881
|
<div
|
|
622
|
-
className=
|
|
882
|
+
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]`}
|
|
623
883
|
style={{
|
|
624
|
-
backgroundColor:
|
|
884
|
+
backgroundColor: isSoldOut
|
|
885
|
+
? colors?.bottomStripColor
|
|
886
|
+
: colors?.bottomStripColor,
|
|
625
887
|
opacity: isSoldOut ? 0.5 : 1,
|
|
626
888
|
}}
|
|
627
889
|
>
|
|
628
|
-
{/* <div className="flex justify-between items-center w-full">
|
|
629
|
-
<div className="flex items-center">
|
|
630
|
-
<LottiePlayer
|
|
631
|
-
animationData={getAnimationIcon("bombAnimation")}
|
|
632
|
-
width="18px"
|
|
633
|
-
height="18px"
|
|
634
|
-
/>
|
|
635
|
-
<span className="bold-text ml-[8px]">
|
|
636
|
-
{" "}
|
|
637
|
-
{serviceItem?.offer_text || ""}
|
|
638
|
-
</span>
|
|
639
|
-
</div>
|
|
640
|
-
<div>
|
|
641
|
-
Termina en
|
|
642
|
-
<span
|
|
643
|
-
className="bold-text text-end"
|
|
644
|
-
ref={startCountdown}
|
|
645
|
-
style={{
|
|
646
|
-
fontVariantNumeric: "tabular-nums",
|
|
647
|
-
display: "inline-block",
|
|
648
|
-
// minWidth: "70px",
|
|
649
|
-
}}
|
|
650
|
-
/>
|
|
651
|
-
</div>
|
|
652
|
-
</div> */}
|
|
653
890
|
<LottiePlayer
|
|
654
|
-
animationData={getAnimationIcon("
|
|
891
|
+
animationData={getAnimationIcon("promoAnim")}
|
|
655
892
|
width="18px"
|
|
656
893
|
height="18px"
|
|
657
894
|
/>
|
|
658
|
-
<
|
|
659
|
-
<span className="bold-text ml-[6px]">
|
|
660
|
-
{serviceItem?.offer_text || ""}
|
|
661
|
-
</span>{" "}
|
|
662
|
-
| Termina en
|
|
663
|
-
<span
|
|
664
|
-
className="bold-text text-end"
|
|
665
|
-
ref={startCountdown}
|
|
666
|
-
style={{
|
|
667
|
-
fontVariantNumeric: "tabular-nums",
|
|
668
|
-
display: "inline-block",
|
|
669
|
-
// minWidth: "70px",
|
|
670
|
-
}}
|
|
671
|
-
/>
|
|
672
|
-
</div>
|
|
895
|
+
<span className="ml-[10px]">{serviceItem?.offer_text}</span>
|
|
673
896
|
</div>
|
|
674
897
|
)}
|
|
898
|
+
|
|
675
899
|
<div className="absolute -top-[11px] left-0 w-full flex items-center justify-end gap-[12px] pr-[15px] z-10 ">
|
|
676
900
|
{showTopLabel && (
|
|
677
901
|
<div
|
|
678
|
-
className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-
|
|
902
|
+
className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-20`}
|
|
679
903
|
style={{
|
|
680
904
|
backgroundColor: isSoldOut
|
|
681
905
|
? "#ddd"
|
|
@@ -715,7 +939,7 @@ function ServiceItemPB({
|
|
|
715
939
|
<div>{"Conexión"}</div>
|
|
716
940
|
</div>
|
|
717
941
|
)}
|
|
718
|
-
{
|
|
942
|
+
{serviceItem?.is_direct_trip && (
|
|
719
943
|
<div
|
|
720
944
|
className={`flex items-center gap-[10px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20 `}
|
|
721
945
|
style={{
|
|
@@ -730,7 +954,7 @@ function ServiceItemPB({
|
|
|
730
954
|
/>
|
|
731
955
|
<div>{translation?.directService}</div>
|
|
732
956
|
</div>
|
|
733
|
-
)}
|
|
957
|
+
)}
|
|
734
958
|
{serviceItem?.train_type_label === "Tren Express (Nuevo)" && (
|
|
735
959
|
<div
|
|
736
960
|
className={`flex items-center gap-[10px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20 `}
|