kupos-ui-components-lib 9.0.6 → 9.0.7
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/assets/images/anims/service_list/priority_stage.json +1 -1
- package/dist/components/ServiceItem/RatingHover.js +31 -31
- package/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemDesktop.js +263 -125
- package/dist/components/ServiceItem/ServiceItemMobile.js +291 -44
- package/dist/components/ServiceItem/mobileTypes.d.ts +0 -3
- package/dist/components/ServiceItem/types.d.ts +0 -7
- package/dist/styles.css +17 -66
- package/dist/ui/AmenitiesBlock.js +36 -25
- package/dist/ui/DurationBlock.js +2 -2
- package/dist/ui/FlexibleBlock.js +4 -2
- package/dist/ui/PetBlock.js +3 -1
- package/dist/ui/RatingBlock.js +2 -6
- package/package.json +1 -1
- package/src/assets/images/anims/service_list/directo.json +1 -1
- package/src/assets/images/anims/service_list/priority_stage.json +1 -1
- package/src/components/ServiceItem/RatingHover.tsx +51 -51
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +466 -222
- package/src/components/ServiceItem/ServiceItemMobile.tsx +501 -120
- package/src/components/ServiceItem/mobileTypes.ts +0 -3
- package/src/components/ServiceItem/types.ts +0 -7
- package/src/ui/AmenitiesBlock.tsx +15 -34
- package/src/ui/DurationBlock.tsx +2 -2
- package/src/ui/FlexibleBlock.tsx +3 -3
- package/src/ui/PetBlock.tsx +2 -2
- package/src/ui/RatingBlock.tsx +4 -16
- package/src/assets/images/anims/service_list/bomb.json +0 -1
- package/src/ui/BottomAmenities/BottomAmenities.tsx +0 -109
- package/src/ui/ExpendedDropDown/ExpandedDropdown.tsx +0 -85
- package/src/ui/KuposButton/KuposButton.tsx +0 -48
- package/src/ui/SeatSection/SeatSection.tsx +0 -187
- package/src/ui/TopAmenities/TopAmenities.tsx +0 -82
- package/src/ui/mobileweb/BottomAmenitiesMobile.tsx +0 -168
- package/src/ui/mobileweb/DateTimeSectionMobile.tsx +0 -192
- package/src/ui/mobileweb/SeatSectionMobile.tsx +0 -256
- package/src/ui/mobileweb/TopAmenitieMobile.tsx +0 -82
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
2
|
import { ServiceItemProps } from "./types";
|
|
3
3
|
import DateService from "../../utils/DateService";
|
|
4
4
|
import CommonService from "../../utils/CommonService";
|
|
5
|
+
import RatingHover from "./RatingHover";
|
|
5
6
|
import ModalEventManager from "../../utils/ModalEventManager";
|
|
6
7
|
import InternationalServicePopupBody from "../InternationalServicePopupBody";
|
|
7
8
|
import LottiePlayer from "../../assets/LottiePlayer";
|
|
8
9
|
import PeruServiceItemDesktop from "./PeruServiceItemDesktop";
|
|
9
|
-
import ExpandedDropdown from "../../ui/ExpendedDropDown/ExpandedDropdown";
|
|
10
10
|
import promoAnimation from "../../assets/images/anims/service_list/promocion.json";
|
|
11
11
|
import flexibleAnimation from "../../assets/images/anims/service_list/flexible.json";
|
|
12
12
|
import locationAnimation from "../../assets/images/anims/service_list/location.json";
|
|
@@ -18,13 +18,22 @@ import pullmanFlexibleAnimation from "../../assets/images/anims/service_list/pul
|
|
|
18
18
|
import pullmanPetFriendlyAnimation from "../../assets/images/anims/service_list/pullmanPetFriendly.json";
|
|
19
19
|
import pullmanLocationAnimation from "../../assets/images/anims/service_list/pullmanLocation.json";
|
|
20
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";
|
|
21
23
|
|
|
22
24
|
import opsitesFlexibleAnimation from "../../assets/images/anims/service_list/opsitesFlexible.json";
|
|
23
25
|
import opsitesPetFriendlyAnimation from "../../assets/images/anims/service_list/opsitesPetFriendly.json";
|
|
24
26
|
import opsitesLocationAnimation from "../../assets/images/anims/service_list/opsitesLocation.json";
|
|
25
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";
|
|
26
30
|
|
|
27
|
-
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";
|
|
28
37
|
|
|
29
38
|
import RatingBlock from "../../ui/RatingBlock";
|
|
30
39
|
import DurationBlock from "../../ui/DurationBlock";
|
|
@@ -32,61 +41,9 @@ import PetBlock from "../../ui/PetBlock";
|
|
|
32
41
|
import FlexibleBlock from "../../ui/FlexibleBlock";
|
|
33
42
|
import AmenitiesBlock from "../../ui/AmenitiesBlock";
|
|
34
43
|
import StageTooltip from "../../ui/StagesTooltip";
|
|
35
|
-
import KuposButton from "../../ui/KuposButton/KuposButton";
|
|
36
|
-
import TopAmenities from "../../ui/TopAmenities/TopAmenities";
|
|
37
|
-
import BottomAmenities from "../../ui/BottomAmenities/BottomAmenities";
|
|
38
|
-
import SeatSection from "../../ui/SeatSection/SeatSection";
|
|
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
|
-
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
47
|
function ServiceItemPB({
|
|
91
48
|
serviceItem,
|
|
92
49
|
onBookButtonPress,
|
|
@@ -114,12 +71,49 @@ function ServiceItemPB({
|
|
|
114
71
|
t = (key: string) => key,
|
|
115
72
|
siteType,
|
|
116
73
|
isAllinBus,
|
|
117
|
-
isExpand,
|
|
118
|
-
setIsExpand,
|
|
119
|
-
coachKey,
|
|
120
74
|
}: ServiceItemProps & { currencySign?: string }): React.ReactElement {
|
|
75
|
+
console.log("🚀 ~ ServiceItemPB ~ serviceItem:", serviceItem);
|
|
76
|
+
const animationMap: Record<string, Record<string, any>> = {
|
|
77
|
+
promoAnim: {
|
|
78
|
+
kupos: promoAnimation,
|
|
79
|
+
pullman: pullmanPromoAnimation,
|
|
80
|
+
opsites: opsitesPromoAnimation,
|
|
81
|
+
linatal: linatalPromoAnimation,
|
|
82
|
+
},
|
|
83
|
+
locationAnim: {
|
|
84
|
+
kupos: locationAnimation,
|
|
85
|
+
pullman: pullmanLocationAnimation,
|
|
86
|
+
opsites: opsitesLocationAnimation,
|
|
87
|
+
linatal: linatalLocationAnimation,
|
|
88
|
+
},
|
|
89
|
+
directoAnim: {
|
|
90
|
+
kupos: directoAnimation,
|
|
91
|
+
pullman: pullmanDirectoAnimation,
|
|
92
|
+
opsites: opsitesDirectoAnimation,
|
|
93
|
+
linatal: linatalDirectoAnimation,
|
|
94
|
+
},
|
|
95
|
+
petFriendlyAnim: {
|
|
96
|
+
kupos: petFriendlyAnimation,
|
|
97
|
+
pullman: pullmanPetFriendlyAnimation,
|
|
98
|
+
opsites: opsitesPetFriendlyAnimation,
|
|
99
|
+
linatal: linatalPetFriendlyAnimation,
|
|
100
|
+
},
|
|
101
|
+
priorityStageAnim: {
|
|
102
|
+
kupos: priorityStageAnimation,
|
|
103
|
+
pullman: pullmanPriorityStageAnimation,
|
|
104
|
+
opsites: opsitesPriorityStageAnimation,
|
|
105
|
+
linatal: linatalPriorityStageAnimation,
|
|
106
|
+
},
|
|
107
|
+
flexibleIcon: {
|
|
108
|
+
kupos: flexibleAnimation,
|
|
109
|
+
pullman: pullmanFlexibleAnimation,
|
|
110
|
+
opsites: opsitesFlexibleAnimation,
|
|
111
|
+
linatal: linatalFlexibleAnimation,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
121
115
|
const getAnimationIcon = (icon: string) => {
|
|
122
|
-
const animation =
|
|
116
|
+
const animation = animationMap[icon];
|
|
123
117
|
if (!animation) return null;
|
|
124
118
|
return animation[siteType] ?? animation.kupos;
|
|
125
119
|
};
|
|
@@ -158,7 +152,9 @@ function ServiceItemPB({
|
|
|
158
152
|
style={{
|
|
159
153
|
filter: color === "white" ? "brightness(0) invert(1)" : "",
|
|
160
154
|
}}
|
|
161
|
-
className=
|
|
155
|
+
className={`object-contain ${
|
|
156
|
+
moreAnemities ? "w-[16px] h-[16px]" : "w-[16px] h-[16px]"
|
|
157
|
+
}`}
|
|
162
158
|
/>
|
|
163
159
|
);
|
|
164
160
|
};
|
|
@@ -176,11 +172,6 @@ function ServiceItemPB({
|
|
|
176
172
|
|
|
177
173
|
let isSoldOut = serviceItem.available_seats <= 0;
|
|
178
174
|
|
|
179
|
-
const showPromo = Math.random() > 0.5;
|
|
180
|
-
|
|
181
|
-
const isItemExpanded = serviceItem.id === isExpand || isExpand === true;
|
|
182
|
-
const grayscaleClass = isSoldOut ? "grayscale" : "";
|
|
183
|
-
|
|
184
175
|
const renderIcon = (iconKey: string, size: string = "14px") => {
|
|
185
176
|
const iconValue = serviceItem.icons?.[iconKey];
|
|
186
177
|
if (iconValue) {
|
|
@@ -189,7 +180,7 @@ function ServiceItemPB({
|
|
|
189
180
|
<img
|
|
190
181
|
src={iconValue}
|
|
191
182
|
alt={iconKey}
|
|
192
|
-
className={`${`w-[${size}] h-[${size}]`} `}
|
|
183
|
+
className={`${`w-[${size}] h-[${size}]`} mr-[5px]`}
|
|
193
184
|
/>
|
|
194
185
|
);
|
|
195
186
|
}
|
|
@@ -197,8 +188,136 @@ function ServiceItemPB({
|
|
|
197
188
|
return null;
|
|
198
189
|
};
|
|
199
190
|
|
|
191
|
+
const getAllSeatTypes = () => {
|
|
192
|
+
if (!serviceItem?.seat_types?.length) {
|
|
193
|
+
return [{ label: "Salon cama", price: 0 }];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
let seatTypesWithPrices = serviceItem.seat_types
|
|
197
|
+
.filter((item) => getFilteredSeats(item))
|
|
198
|
+
.map((val) => ({
|
|
199
|
+
label: val?.label,
|
|
200
|
+
price: val?.fare,
|
|
201
|
+
}));
|
|
202
|
+
|
|
203
|
+
seatTypesWithPrices.sort((a, b) => a.price - b.price);
|
|
204
|
+
|
|
205
|
+
return seatTypesWithPrices;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const getSortedSeatTypes = () => {
|
|
209
|
+
if (!serviceItem?.seat_types?.length) {
|
|
210
|
+
return [{ label: "Salon cama", price: 0 }];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
let seatTypesWithPrices = getAllSeatTypes();
|
|
214
|
+
const premiumIndex = seatTypesWithPrices.findIndex(
|
|
215
|
+
(item) => item.label === "Premium",
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
if (premiumIndex >= 3) {
|
|
219
|
+
seatTypesWithPrices[2] = seatTypesWithPrices[premiumIndex];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
|
|
223
|
+
|
|
224
|
+
return seatTypesWithPrices;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const getUniqueSeats = () => {
|
|
228
|
+
const allSeatTypes = getAllSeatTypes();
|
|
229
|
+
const seatMap = new Map();
|
|
230
|
+
|
|
231
|
+
allSeatTypes.forEach((seat) => {
|
|
232
|
+
if (SEAT_EXCEPTIONS.includes(seat.label)) return;
|
|
233
|
+
|
|
234
|
+
// Only check if the label already exists in the map, don't compare prices
|
|
235
|
+
if (!seatMap.has(seat.label)) {
|
|
236
|
+
seatMap.set(seat.label, seat);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
return Array.from(seatMap.values());
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const getNumberOfSeats = () => {
|
|
244
|
+
return serviceItem.seat_types.filter(
|
|
245
|
+
(val) => !SEAT_EXCEPTIONS.includes(val.label),
|
|
246
|
+
).length;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const getSeatNames = () => {
|
|
250
|
+
const uniqueSeats = getUniqueSeats();
|
|
251
|
+
const sortedSeatTypes = getSortedSeatTypes();
|
|
252
|
+
|
|
253
|
+
if (removeDuplicateSeats) {
|
|
254
|
+
return uniqueSeats.map((val, key: number) =>
|
|
255
|
+
SEAT_EXCEPTIONS.includes(val.label) ? null : (
|
|
256
|
+
<span
|
|
257
|
+
key={key}
|
|
258
|
+
className={`flex items-center justify-between text-[13.33px] ${
|
|
259
|
+
isSoldOut ? "text-[#c0c0c0]" : ""
|
|
260
|
+
}`}
|
|
261
|
+
>
|
|
262
|
+
{typeof val.label === "string" || typeof val.label === "number"
|
|
263
|
+
? isPeru
|
|
264
|
+
? CommonService.truncateSeatLabel(val.label)
|
|
265
|
+
: val.label
|
|
266
|
+
: null}
|
|
267
|
+
</span>
|
|
268
|
+
),
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
return sortedSeatTypes.map((val, key: number) =>
|
|
272
|
+
SEAT_EXCEPTIONS.includes(val.label) ? null : (
|
|
273
|
+
<span
|
|
274
|
+
key={key}
|
|
275
|
+
className={`flex items-center justify-between text-[13.33px] ${
|
|
276
|
+
isSoldOut ? "text-[#c0c0c0]" : ""
|
|
277
|
+
}`}
|
|
278
|
+
>
|
|
279
|
+
{typeof val.label === "string" || typeof val.label === "number"
|
|
280
|
+
? val.label
|
|
281
|
+
: null}
|
|
282
|
+
</span>
|
|
283
|
+
),
|
|
284
|
+
);
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const getSeatPrice = () => {
|
|
288
|
+
const sortedSeatTypes = getSortedSeatTypes();
|
|
289
|
+
const uniqueSeats = getUniqueSeats();
|
|
290
|
+
if (removeDuplicateSeats) {
|
|
291
|
+
return uniqueSeats.map((val, key) => (
|
|
292
|
+
<span key={key}>
|
|
293
|
+
{serviceItem?.available_seats <= 0
|
|
294
|
+
? CommonService.currency(0, currencySign)
|
|
295
|
+
: CommonService.currency(val.price, currencySign)}
|
|
296
|
+
</span>
|
|
297
|
+
));
|
|
298
|
+
}
|
|
299
|
+
return sortedSeatTypes.map((val, key: number) => {
|
|
300
|
+
return SEAT_EXCEPTIONS.includes(val.label) ? null : (
|
|
301
|
+
<span key={key} className="flex items-center text-[13.33px] bold-text">
|
|
302
|
+
{typeof val.price === "string"
|
|
303
|
+
? serviceItem?.available_seats <= 0
|
|
304
|
+
? CommonService.currency(0, currencySign)
|
|
305
|
+
: CommonService.currency(val.price, currencySign)
|
|
306
|
+
: typeof val.price === "number"
|
|
307
|
+
? serviceItem?.available_seats <= 0
|
|
308
|
+
? CommonService.currency(0, currencySign)
|
|
309
|
+
: CommonService.currency(val.price, currencySign)
|
|
310
|
+
: null}
|
|
311
|
+
</span>
|
|
312
|
+
);
|
|
313
|
+
});
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
const getFilteredSeats = (item) => {
|
|
317
|
+
return item;
|
|
318
|
+
};
|
|
319
|
+
|
|
200
320
|
const checkMidnight = () => {
|
|
201
|
-
setIsExpand(null);
|
|
202
321
|
if (
|
|
203
322
|
cityOrigin?.label &&
|
|
204
323
|
cityDestination?.label &&
|
|
@@ -277,37 +396,56 @@ function ServiceItemPB({
|
|
|
277
396
|
),
|
|
278
397
|
});
|
|
279
398
|
return;
|
|
399
|
+
} else {
|
|
400
|
+
onBookButtonPress();
|
|
280
401
|
}
|
|
281
|
-
|
|
282
|
-
onBookButtonPress();
|
|
283
402
|
};
|
|
284
403
|
|
|
285
404
|
const depTime = serviceItem.dep_time || "";
|
|
405
|
+
|
|
406
|
+
// Extract hours and minutes and check for AM/PM
|
|
286
407
|
const hasAM = depTime.includes("AM");
|
|
287
408
|
const hasPM = depTime.includes("PM");
|
|
288
|
-
const
|
|
409
|
+
const [timePart] = depTime.split(/AM|PM/).map((part) => part.trim());
|
|
410
|
+
const [hour, minute] = timePart.split(":").map(Number);
|
|
411
|
+
|
|
412
|
+
// Convert to 24-hour format
|
|
413
|
+
let cleanedDepTime;
|
|
414
|
+
if (hasAM) {
|
|
415
|
+
cleanedDepTime =
|
|
416
|
+
hour === 12
|
|
417
|
+
? `00:${minute < 10 ? "0" + minute : minute}`
|
|
418
|
+
: `${hour < 10 ? "0" + hour : hour}:${
|
|
419
|
+
minute < 10 ? "0" + minute : minute
|
|
420
|
+
}`;
|
|
421
|
+
} else if (hasPM) {
|
|
422
|
+
cleanedDepTime =
|
|
423
|
+
hour === 12
|
|
424
|
+
? `${hour}:${minute < 10 ? "0" + minute : minute}`
|
|
425
|
+
: `${hour + 12}:${minute < 10 ? "0" + minute : minute}`;
|
|
426
|
+
} else {
|
|
427
|
+
cleanedDepTime = timePart;
|
|
428
|
+
}
|
|
289
429
|
|
|
290
430
|
const items = [
|
|
291
431
|
{
|
|
292
|
-
key: "
|
|
293
|
-
width: "
|
|
294
|
-
condition: true,
|
|
432
|
+
key: "rating",
|
|
433
|
+
width: "30%",
|
|
295
434
|
render: (
|
|
296
|
-
<
|
|
435
|
+
<RatingBlock
|
|
436
|
+
showRating={showRating}
|
|
297
437
|
serviceItem={serviceItem}
|
|
298
|
-
metaData={metaData}
|
|
299
438
|
isSoldOut={isSoldOut}
|
|
300
439
|
colors={colors}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
getAmenityName={CommonService.getAmenityName}
|
|
304
|
-
SvgAmenities={SvgAmenities}
|
|
440
|
+
t={t}
|
|
441
|
+
translation={translation}
|
|
305
442
|
/>
|
|
306
443
|
),
|
|
307
444
|
},
|
|
445
|
+
|
|
308
446
|
{
|
|
309
447
|
key: "duration",
|
|
310
|
-
width: "
|
|
448
|
+
width: "20%",
|
|
311
449
|
condition: serviceItem.duration,
|
|
312
450
|
render: (
|
|
313
451
|
<DurationBlock
|
|
@@ -320,22 +458,6 @@ function ServiceItemPB({
|
|
|
320
458
|
),
|
|
321
459
|
},
|
|
322
460
|
|
|
323
|
-
{
|
|
324
|
-
key: "directo",
|
|
325
|
-
width: "12%",
|
|
326
|
-
condition: serviceItem?.is_direct_trip,
|
|
327
|
-
render: (
|
|
328
|
-
<div className="flex items-center gap-[10px] text-[12.5px] z-10 mt-[6px]">
|
|
329
|
-
<LottiePlayer
|
|
330
|
-
animationData={getAnimationIcon("directoAnim")}
|
|
331
|
-
width="14px"
|
|
332
|
-
height="14px"
|
|
333
|
-
/>
|
|
334
|
-
<div>{translation?.directService}</div>
|
|
335
|
-
</div>
|
|
336
|
-
),
|
|
337
|
-
},
|
|
338
|
-
|
|
339
461
|
{
|
|
340
462
|
key: "pet",
|
|
341
463
|
width: "20%",
|
|
@@ -366,10 +488,28 @@ function ServiceItemPB({
|
|
|
366
488
|
/>
|
|
367
489
|
),
|
|
368
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
|
+
},
|
|
369
508
|
];
|
|
370
509
|
|
|
510
|
+
const amenitiesItem = items.find((i) => i.key === "amenities");
|
|
371
511
|
const otherItems = items.filter(
|
|
372
|
-
(i) => i.key !== "
|
|
512
|
+
(i) => i.key !== "amenities" && i.condition !== false,
|
|
373
513
|
);
|
|
374
514
|
|
|
375
515
|
return (
|
|
@@ -406,77 +546,40 @@ function ServiceItemPB({
|
|
|
406
546
|
<div
|
|
407
547
|
className={`relative ${
|
|
408
548
|
serviceItem.offer_text ? "mb-[55px]" : "mb-[10px]"
|
|
409
|
-
}
|
|
549
|
+
} ${
|
|
550
|
+
serviceItem?.is_direct_trip ||
|
|
551
|
+
serviceItem?.train_type_label === "Tren Express (Nuevo)" ||
|
|
552
|
+
showTopLabel
|
|
553
|
+
? "mt-[24px]"
|
|
554
|
+
: "mt-[20px]"
|
|
555
|
+
} `}
|
|
410
556
|
>
|
|
411
|
-
<TopAmenities
|
|
412
|
-
showPromo={showPromo}
|
|
413
|
-
showTopLabel={showTopLabel}
|
|
414
|
-
isSoldOut={isSoldOut}
|
|
415
|
-
priceColor={colors.priceColor}
|
|
416
|
-
buttonColor={colors.kuposButtonColor}
|
|
417
|
-
boardingIcon={renderIcon("whiteBoardingIcon", "14px")}
|
|
418
|
-
getAnimationIcon={getAnimationIcon}
|
|
419
|
-
/>
|
|
420
557
|
<div
|
|
421
|
-
className=
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
// showPromo
|
|
425
|
-
// ? `1px solid ${colors.priceColor}`
|
|
426
|
-
// : "1px solid #ccc",
|
|
427
|
-
borderRadius:
|
|
428
|
-
// showPromo || showTopLabel ?
|
|
429
|
-
"10px 0 10px 10px",
|
|
430
|
-
// : "10px",
|
|
431
|
-
}}
|
|
558
|
+
className={
|
|
559
|
+
"bg-white rounded-[20px] shadow-service mx-auto relative"
|
|
560
|
+
}
|
|
432
561
|
>
|
|
433
|
-
<div
|
|
434
|
-
// className="p-[15px] pt-[20px]"
|
|
435
|
-
className=" pt-[20px]"
|
|
436
|
-
style={{
|
|
437
|
-
padding: coachKey
|
|
438
|
-
? "15px 15px 20px 15px"
|
|
439
|
-
: "20px 15px 11px 15px",
|
|
440
|
-
}}
|
|
441
|
-
>
|
|
562
|
+
<div className="p-[15px] pt-[20px]">
|
|
442
563
|
<div
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
// 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" : "" }}
|
|
446
566
|
>
|
|
447
567
|
{/* OPERATOR LOGO */}
|
|
448
|
-
<div
|
|
449
|
-
|
|
450
|
-
display: "flex",
|
|
451
|
-
flexDirection: "column",
|
|
452
|
-
gap: "5px",
|
|
453
|
-
}}
|
|
454
|
-
>
|
|
455
|
-
<div
|
|
456
|
-
// className="flex items-center justify-center m-[auto]"
|
|
457
|
-
className=""
|
|
458
|
-
>
|
|
568
|
+
<div className="flex items-center justify-center m-[auto]">
|
|
569
|
+
<div className=" ">
|
|
459
570
|
<img
|
|
460
571
|
src={serviceItem.operator_details[0]}
|
|
461
572
|
alt="service logo"
|
|
462
|
-
className={`h-auto
|
|
573
|
+
className={` h-auto object-contain ${
|
|
463
574
|
isSoldOut ? "grayscale" : ""
|
|
464
575
|
}`}
|
|
465
576
|
/>
|
|
466
|
-
{isCiva ? (
|
|
467
|
-
<div className="text-[13.33px] black-text ml-2">
|
|
468
|
-
{serviceItem.operator_details[2]}
|
|
469
|
-
</div>
|
|
470
|
-
) : null}
|
|
471
577
|
</div>
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
t={t}
|
|
478
|
-
translation={translation}
|
|
479
|
-
/>
|
|
578
|
+
{isCiva ? (
|
|
579
|
+
<div className="text-[13.33px] black-text ml-2">
|
|
580
|
+
{serviceItem.operator_details[2]}
|
|
581
|
+
</div>
|
|
582
|
+
) : null}
|
|
480
583
|
</div>
|
|
481
584
|
|
|
482
585
|
{/* DATE AND TIME - Grid Layout */}
|
|
@@ -500,7 +603,7 @@ function ServiceItemPB({
|
|
|
500
603
|
<img
|
|
501
604
|
src={serviceItem.icons?.origin}
|
|
502
605
|
alt="origin"
|
|
503
|
-
className={`w-[
|
|
606
|
+
className={`w-[18px] h-auto mr-[8px] ${
|
|
504
607
|
isSoldOut ? "grayscale" : ""
|
|
505
608
|
}`}
|
|
506
609
|
/>
|
|
@@ -517,7 +620,7 @@ function ServiceItemPB({
|
|
|
517
620
|
<div className="h-[20px] flex items-center">
|
|
518
621
|
<img
|
|
519
622
|
src={serviceItem.icons?.destination}
|
|
520
|
-
className={`w-[
|
|
623
|
+
className={`w-[18px] h-auto mr-[8px] ${
|
|
521
624
|
isSoldOut ? "grayscale" : ""
|
|
522
625
|
}`}
|
|
523
626
|
style={{ opacity: isSoldOut ? 0.5 : 1 }}
|
|
@@ -636,87 +739,151 @@ function ServiceItemPB({
|
|
|
636
739
|
></div>
|
|
637
740
|
{/* SEATS */}
|
|
638
741
|
<div className="content-center">
|
|
639
|
-
<
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
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
|
+
>
|
|
752
|
+
<div
|
|
753
|
+
className="flex flex-col justify-between"
|
|
754
|
+
style={{ gap: "10px" }}
|
|
755
|
+
>
|
|
756
|
+
{getSeatNames()}
|
|
757
|
+
</div>
|
|
654
758
|
<div
|
|
655
|
-
className="flex justify-
|
|
759
|
+
className="flex flex-col justify-between absolute inset-y-0 right-0 left-1/2 h-full"
|
|
656
760
|
style={{
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
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",
|
|
662
772
|
}}
|
|
663
773
|
>
|
|
664
|
-
{
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
774
|
+
{getSeatPrice()}
|
|
775
|
+
</div>
|
|
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>
|
|
812
|
+
</div>
|
|
813
|
+
</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}
|
|
824
|
+
|
|
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
|
|
669
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}
|
|
670
866
|
</div>
|
|
671
|
-
)
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
soldOutLabel={translation?.soldOutButton}
|
|
678
|
-
soldOutIcon={renderIcon("soldOutIcon", "14px")}
|
|
679
|
-
onClick={checkMidnight}
|
|
680
|
-
/>
|
|
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}
|
|
681
873
|
</div>
|
|
682
874
|
</div>
|
|
683
|
-
<BottomAmenities
|
|
684
|
-
otherItems={otherItems}
|
|
685
|
-
serviceItem={serviceItem}
|
|
686
|
-
grayscaleClass={grayscaleClass}
|
|
687
|
-
isSoldOut={isSoldOut}
|
|
688
|
-
isItemExpanded={isItemExpanded}
|
|
689
|
-
colors={colors}
|
|
690
|
-
translation={translation}
|
|
691
|
-
getAnimationIcon={getAnimationIcon}
|
|
692
|
-
downArrowIcon={renderIcon("downArrow", "10px")}
|
|
693
|
-
onToggleExpand={() =>
|
|
694
|
-
setIsExpand &&
|
|
695
|
-
setIsExpand(isItemExpanded ? null : serviceItem.id)
|
|
696
|
-
}
|
|
697
|
-
/>
|
|
698
875
|
</div>
|
|
699
876
|
</div>
|
|
700
877
|
|
|
701
|
-
{/* 🔹 EXPANDABLE DROPDOWN (below the card) */}
|
|
702
|
-
{isItemExpanded && (
|
|
703
|
-
<ExpandedDropdown
|
|
704
|
-
serviceItem={serviceItem}
|
|
705
|
-
showPromo={showPromo}
|
|
706
|
-
colors={colors}
|
|
707
|
-
grayscaleClass={grayscaleClass}
|
|
708
|
-
translation={translation}
|
|
709
|
-
getAnimationIcon={getAnimationIcon}
|
|
710
|
-
/>
|
|
711
|
-
)}
|
|
712
|
-
|
|
713
878
|
{children}
|
|
714
879
|
{/* Bottom discount banner */}
|
|
715
880
|
{serviceItem?.offer_text && (
|
|
716
881
|
<div
|
|
717
|
-
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]`}
|
|
718
883
|
style={{
|
|
719
|
-
backgroundColor:
|
|
884
|
+
backgroundColor: isSoldOut
|
|
885
|
+
? colors?.bottomStripColor
|
|
886
|
+
: colors?.bottomStripColor,
|
|
720
887
|
opacity: isSoldOut ? 0.5 : 1,
|
|
721
888
|
}}
|
|
722
889
|
>
|
|
@@ -728,6 +895,83 @@ function ServiceItemPB({
|
|
|
728
895
|
<span className="ml-[10px]">{serviceItem?.offer_text}</span>
|
|
729
896
|
</div>
|
|
730
897
|
)}
|
|
898
|
+
|
|
899
|
+
<div className="absolute -top-[11px] left-0 w-full flex items-center justify-end gap-[12px] pr-[15px] z-10 ">
|
|
900
|
+
{showTopLabel && (
|
|
901
|
+
<div
|
|
902
|
+
className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-20`}
|
|
903
|
+
style={{
|
|
904
|
+
backgroundColor: isSoldOut
|
|
905
|
+
? "#ddd"
|
|
906
|
+
: colors.ratingBottomColor,
|
|
907
|
+
}}
|
|
908
|
+
>
|
|
909
|
+
<div className={isSoldOut ? "grayscale" : ""}>
|
|
910
|
+
<LottiePlayer
|
|
911
|
+
// animationData={serviceItem.icons.priorityStageAnim}
|
|
912
|
+
animationData={getAnimationIcon("priorityStageAnim")}
|
|
913
|
+
width="14px"
|
|
914
|
+
height="14px"
|
|
915
|
+
/>
|
|
916
|
+
</div>
|
|
917
|
+
<div
|
|
918
|
+
className={
|
|
919
|
+
isSoldOut ? "text-white" : `text-[${colors.topLabelColor}]`
|
|
920
|
+
}
|
|
921
|
+
>
|
|
922
|
+
{showTopLabel}
|
|
923
|
+
</div>
|
|
924
|
+
</div>
|
|
925
|
+
)}
|
|
926
|
+
{serviceItem?.is_transpordo && (
|
|
927
|
+
<div
|
|
928
|
+
className={`flex items-center gap-[10px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20`}
|
|
929
|
+
style={{
|
|
930
|
+
backgroundColor: isSoldOut ? "#ddd" : colors.tooltipColor,
|
|
931
|
+
}}
|
|
932
|
+
>
|
|
933
|
+
<LottiePlayer
|
|
934
|
+
animationData={serviceItem.icons.connectingServiceIcon}
|
|
935
|
+
// animationData={getAnimationIcon(connectingServiceIcon)}
|
|
936
|
+
width="14px"
|
|
937
|
+
height="14px"
|
|
938
|
+
/>
|
|
939
|
+
<div>{"Conexión"}</div>
|
|
940
|
+
</div>
|
|
941
|
+
)}
|
|
942
|
+
{serviceItem?.is_direct_trip && (
|
|
943
|
+
<div
|
|
944
|
+
className={`flex items-center gap-[10px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20 `}
|
|
945
|
+
style={{
|
|
946
|
+
backgroundColor: isSoldOut ? "#ddd" : colors.tooltipColor,
|
|
947
|
+
}}
|
|
948
|
+
>
|
|
949
|
+
<LottiePlayer
|
|
950
|
+
// animationData={serviceItem.icons.directoAnim}
|
|
951
|
+
animationData={getAnimationIcon("directoAnim")}
|
|
952
|
+
width="14px"
|
|
953
|
+
height="14px"
|
|
954
|
+
/>
|
|
955
|
+
<div>{translation?.directService}</div>
|
|
956
|
+
</div>
|
|
957
|
+
)}
|
|
958
|
+
{serviceItem?.train_type_label === "Tren Express (Nuevo)" && (
|
|
959
|
+
<div
|
|
960
|
+
className={`flex items-center gap-[10px] py-[4px] text-white px-[14px] rounded-[38px] text-[12.5px] z-20 `}
|
|
961
|
+
style={{
|
|
962
|
+
backgroundColor: isSoldOut ? "#ddd" : colors.tooltipColor,
|
|
963
|
+
}}
|
|
964
|
+
>
|
|
965
|
+
<LottiePlayer
|
|
966
|
+
// animationData={serviceItem.icons.directoAnim}
|
|
967
|
+
animationData={getAnimationIcon("directoAnim")}
|
|
968
|
+
width="14px"
|
|
969
|
+
height="14px"
|
|
970
|
+
/>
|
|
971
|
+
<div>{"Tren Express"}</div>
|
|
972
|
+
</div>
|
|
973
|
+
)}
|
|
974
|
+
</div>
|
|
731
975
|
</div>
|
|
732
976
|
)}
|
|
733
977
|
</>
|