kupos-ui-components-lib 10.4.9 → 10.4.11

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 (35) hide show
  1. package/dist/components/ServiceItem/PeruServiceItemDesktop.js +10 -4
  2. package/dist/components/ServiceItem/PeruServiceItemMobile.d.ts +7 -0
  3. package/dist/components/ServiceItem/PeruServiceItemMobile.js +235 -0
  4. package/dist/components/ServiceItem/ServiceItemDesktop.js +4 -4
  5. package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
  6. package/dist/components/ServiceItem/ServiceItemMobile.js +3 -2
  7. package/dist/components/ServiceItem/mobileTypes.d.ts +3 -0
  8. package/dist/components/ServiceItem/types.d.ts +1 -0
  9. package/dist/styles.css +13 -0
  10. package/dist/ui/PaymentCardMobile/PaymentCardMobile.d.ts +4 -0
  11. package/dist/ui/PaymentCardMobile/PaymentCardMobile.js +531 -0
  12. package/dist/ui/PaymentCardMobile/index.d.ts +1 -0
  13. package/dist/ui/PaymentCardMobile/index.js +1 -0
  14. package/dist/ui/PeruOfferBanner.d.ts +24 -0
  15. package/dist/ui/PeruOfferBanner.js +94 -0
  16. package/dist/ui/SeatSection/PeruSeatSection.d.ts +22 -0
  17. package/dist/ui/SeatSection/PeruSeatSection.js +247 -0
  18. package/dist/ui/SlidingModal/SlidingModal.d.ts +9 -0
  19. package/dist/ui/SlidingModal/SlidingModal.js +100 -0
  20. package/dist/ui/SlidingModal/index.d.ts +2 -0
  21. package/dist/ui/SlidingModal/index.js +1 -0
  22. package/dist/ui/mobileweb/BottomAmenitiesMobile.d.ts +2 -1
  23. package/dist/ui/mobileweb/BottomAmenitiesMobile.js +2 -1
  24. package/dist/ui/mobileweb/SeatSectionMobile.js +15 -1
  25. package/package.json +1 -1
  26. package/src/components/ServiceItem/PeruServiceItemDesktop.tsx +20 -6
  27. package/src/components/ServiceItem/PeruServiceItemMobile.tsx +601 -0
  28. package/src/components/ServiceItem/ServiceItemDesktop.tsx +2 -2
  29. package/src/components/ServiceItem/ServiceItemMobile.tsx +44 -1
  30. package/src/components/ServiceItem/mobileTypes.ts +3 -0
  31. package/src/components/ServiceItem/types.ts +1 -0
  32. package/src/ui/PeruOfferBanner.tsx +298 -0
  33. package/src/ui/SeatSection/PeruSeatSection.tsx +487 -0
  34. package/src/ui/mobileweb/BottomAmenitiesMobile.tsx +11 -0
  35. package/src/ui/mobileweb/SeatSectionMobile.tsx +46 -1
@@ -0,0 +1,601 @@
1
+ import React from "react";
2
+ import LottiePlayer from "../../assets/LottiePlayer";
3
+ import DateService from "../../utils/DateService";
4
+ import { MobileServiceItemProps } from "./mobileTypes";
5
+ import commonService from "../../utils/CommonService";
6
+ import TopAmenitieMobile from "../../ui/mobileweb/TopAmenitieMobile";
7
+ import BottomAmenitiesMobile from "../../ui/mobileweb/BottomAmenitiesMobile";
8
+ import SeatSectionMobile from "../../ui/mobileweb/SeatSectionMobile";
9
+ import DateTimeSectionMobile from "../../ui/mobileweb/DateTimeSectionMobile";
10
+ import ExpandedDropdownMobile from "../../ui/mobileweb/ExpandedDropdownMobile";
11
+ import ServiceBadgesMobile from "../../ui/mobileweb/ServiceBadgesMobile";
12
+ import FeatureServiceUiMobile from "../../ui/FeaturServiceUiMobile/FeatureServiceUiMobile";
13
+
14
+ const SEAT_EXCEPTIONS = ["Asiento mascota"];
15
+
16
+ const exceptions = [
17
+ "gy",
18
+ ".gy",
19
+ "GY",
20
+ ".GY",
21
+ "Gy",
22
+ ".Gy",
23
+ "BLANCO",
24
+ "blanco",
25
+ "asiento_mascota",
26
+ ];
27
+
28
+ interface PeruServiceItemMobileProps extends Omit<MobileServiceItemProps, 'isNewUi'> {
29
+ isNewUiEnabled?: boolean;
30
+ }
31
+
32
+ function PeruServiceItemMobile({
33
+ serviceItem,
34
+ onBookButtonPress,
35
+ colors,
36
+ busStage,
37
+ orignLabel,
38
+ destinationLabel,
39
+ amenitiesData,
40
+ setShowDropdown,
41
+ showDropdown,
42
+ isExpanded,
43
+ setIsExpanded,
44
+ setAmenetiesAtomValue,
45
+ isCiva,
46
+ currencySign,
47
+ isPeru,
48
+ showRating,
49
+ showLastSeats,
50
+ removeDuplicateSeats,
51
+ isLinatal,
52
+ viewersConfig,
53
+ operatorLabel,
54
+ isTrain,
55
+ isFeatureDropDownExpand,
56
+ setIsFeatureDropDownExpand,
57
+ ticketQuantity,
58
+ onIncreaseTicketQuantity,
59
+ onDecreaseTicketQuantity,
60
+ cityOrigin,
61
+ cityDestination,
62
+ isNewUiEnabled,
63
+ onRemateUiButtonClick,
64
+ selectedTimeSlot,
65
+ onTimeSlotChange,
66
+ isTimeDropdownOpen,
67
+ onTimeDropdownToggle,
68
+ wowDealData,
69
+ isFlores,
70
+ isAllinBus,
71
+ }: PeruServiceItemMobileProps): React.ReactElement {
72
+ const isItemExpanded = serviceItem.id === isExpanded;
73
+ const isPetSeat = (Object.keys(serviceItem?.pet_seat_info ?? {}) || []).length > 0;
74
+ let isSoldOut = serviceItem.available_seats <= 0;
75
+
76
+ const seats = removeDuplicateSeats
77
+ ? serviceItem.seat_types?.filter(
78
+ (seat, index, self) =>
79
+ index === self.findIndex((s) => s.label === seat.label),
80
+ ) || []
81
+ : serviceItem.seat_types || [];
82
+
83
+ const discountedSeats = seats.map((seat) => ({
84
+ ...seat,
85
+ ...commonService.calculateDiscountedPrice(seat.fare, serviceItem as any),
86
+ }));
87
+
88
+ const hasDiscount = discountedSeats.some(
89
+ (seat) => seat.originalPrice !== seat.discountedPrice,
90
+ );
91
+
92
+ const isLongOfferText = (serviceItem?.offer_text?.length || 0) > 35;
93
+ const hasDpEnabled = serviceItem?.is_dp_enabled === true;
94
+
95
+ const isDiscountBelow20 = (serviceItem as any)?.discount_value > 0 && (serviceItem as any)?.discount_value < 20;
96
+ const hasOfferText = Boolean(serviceItem?.offer_text) && !isDiscountBelow20;
97
+ const offerGradient = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"} 0%, ${colors.leftGradiantColor || "#ff8842"} 100%)`;
98
+ const offerGradientWithOpacity = `linear-gradient(90deg, ${colors.rightGradiantColor || "#ff5964"}80 0%, ${colors.leftGradiantColor || "#ff8842"}80 100%)`;
99
+ const serviceCardStyle: React.CSSProperties =
100
+ (isNewUiEnabled || (serviceItem?.is_dp_enabled && serviceItem?.dp_discount_percents))
101
+ ? {
102
+ borderColor: isSoldOut ? "#ccc" : "transparent",
103
+ borderStyle: "solid",
104
+ borderWidth: isSoldOut ? "1px" : "3px 3px 0 3px",
105
+ borderRadius: "18px",
106
+ background: `linear-gradient(#fff, #fff) padding-box, ${isSoldOut ? offerGradientWithOpacity : offerGradient} border-box`,
107
+ }
108
+ : {};
109
+
110
+ const labelId =
111
+ typeof serviceItem.boarding_stages === "string"
112
+ ? serviceItem.boarding_stages.split("|")[0]
113
+ : "";
114
+
115
+ const showTopLabel =
116
+ busStage &&
117
+ busStage[labelId] &&
118
+ busStage[labelId].split("|")[1] === "true" &&
119
+ busStage[labelId].split("|")[0];
120
+
121
+ const getServiceStars = (serviceItem: any) => {
122
+ try {
123
+ return serviceItem.operator_details && serviceItem.operator_details[1]
124
+ ? serviceItem.operator_details[1].toFixed(1)
125
+ : "0.0";
126
+ } catch (e) {
127
+ return "";
128
+ }
129
+ };
130
+
131
+ const amenities = () => {
132
+ const raw = serviceItem?.operator_details?.[3];
133
+ const list = Array.isArray(raw)
134
+ ? raw
135
+ : typeof raw === "string"
136
+ ? raw.split("|").filter(Boolean)
137
+ : [];
138
+
139
+ const nodes = list.slice(0, 2).map((am, i) => (
140
+ <img
141
+ key={i}
142
+ className="amenity"
143
+ height={12}
144
+ width={12}
145
+ src={commonService.getAmenitiesImage(
146
+ amenitiesData?.[am]?.toLowerCase(),
147
+ serviceItem,
148
+ )}
149
+ alt="icon"
150
+ />
151
+ ));
152
+
153
+ return nodes;
154
+ };
155
+
156
+ const renderIcon = (iconKey: string, size: string = "14px", styles?: any) => {
157
+ const iconValue = serviceItem.icons?.[iconKey];
158
+ if (iconValue) {
159
+ if (typeof iconValue === "string") {
160
+ return (
161
+ <img
162
+ src={iconValue}
163
+ alt={iconKey}
164
+ className={`${`w-[${size}] h-[${size}]`} mr-[5px]`}
165
+ style={{
166
+ filter: isSoldOut ? "grayscale" : "",
167
+ ...(styles || {}),
168
+ }}
169
+ />
170
+ );
171
+ }
172
+ }
173
+ return null;
174
+ };
175
+
176
+ let isConexion = false;
177
+
178
+ if (serviceItem?.is_transpordo) {
179
+ isConexion = true;
180
+ }
181
+
182
+ const extractStage = (
183
+ stageArr: Record<string, string[]>[],
184
+ index: number,
185
+ ) => {
186
+ const stageObj = stageArr[index];
187
+ const key = Object.keys(stageObj)[0];
188
+ return stageObj[key][0].split(", ")[0];
189
+ };
190
+
191
+ const boardingName = serviceItem.stage_details_arr?.length
192
+ ? extractStage(serviceItem.stage_details_arr, 0)
193
+ : null;
194
+
195
+ const dropoffName = serviceItem.stage_details_arr?.length
196
+ ? extractStage(serviceItem.stage_details_arr, 1)
197
+ : null;
198
+
199
+ return (
200
+ <div
201
+ className={`relative ${!hasOfferText || !serviceItem?.is_dp_enabled ? "mb-[14px]" : showTopLabel || serviceItem?.is_direct_trip ? "mb-[20px]" : "mb-[12px]"} ${
202
+ serviceItem?.is_direct_trip ||
203
+ isConexion ||
204
+ serviceItem?.train_type_label === "Tren Express (Nuevo)" ||
205
+ showTopLabel ||
206
+ boardingName
207
+ ? "mt-[20px]"
208
+ : "mt-[10px]"
209
+ } `}
210
+ style={{ zIndex: 1 }}
211
+ >
212
+ <div
213
+ className={`z-1 ${
214
+ (isNewUiEnabled ||
215
+ (serviceItem?.is_dp_enabled && serviceItem?.dp_discount_percents)) &&
216
+ !isSoldOut
217
+ ? "rounded-[18px]"
218
+ : "rounded-[10px] border border-[#ccc]"
219
+ }`}
220
+ style={{ ...serviceCardStyle, backgroundColor: "#fff" }}
221
+ >
222
+ <div
223
+ style={{
224
+ padding: "12px 12px 8px 12px",
225
+ marginTop:
226
+ serviceItem?.is_direct_trip && (showTopLabel || isConexion)
227
+ ? " 10px"
228
+ : "",
229
+ }}
230
+ >
231
+ {/* Header with operator info and favorite */}
232
+ <div className="flex justify-between items-center mb-[10px]">
233
+ <div
234
+ className="flex items-center justify-center gap-x-4"
235
+ style={{
236
+ marginBottom:
237
+ serviceItem?.offer_text || hasDiscount ? "10px" : "",
238
+ }}
239
+ >
240
+ <div
241
+ className={`w-[115px] ${isFlores ? "" : "overflow-y-hidden"} h-[30px]`}
242
+ >
243
+ <img
244
+ src={serviceItem.operator_details[0]}
245
+ alt="service logo"
246
+ className={`w-[100px] h-auto object-contain ${
247
+ isSoldOut ? "grayscale" : ""
248
+ }`}
249
+ />
250
+ </div>
251
+ {isCiva ? (
252
+ <div className="black-text min-[420]:text-[12px] text-[12px]">
253
+ {serviceItem?.operator_details[2]}
254
+ </div>
255
+ ) : showRating ? (
256
+ <div className="flex min-[420]:text-[13px] text-[12px] h-[22px] items-center">
257
+ <div className="flex items-center">
258
+ <div className="flex items-center">
259
+ <img
260
+ src={serviceItem.icons.rating}
261
+ alt="origin"
262
+ className={`w-[12px] h-[12px] mr-[4px] object-contain ${
263
+ isSoldOut ? "grayscale" : ""
264
+ }`}
265
+ />
266
+ <span style={{ lineHeight: "normal" }}>
267
+ {getServiceStars(serviceItem)}
268
+ </span>
269
+ </div>
270
+
271
+ <div
272
+ className="flex items-center cursor-pointer "
273
+ style={{
274
+ color: isSoldOut ? "#bbb" : "text-[#464647]",
275
+ }}
276
+ >
277
+ <span className="ml-[3px] min-[420]:text-[13px] text-[12px] text-ellipsis overflow-hidden whitespace-nowrap max-w-[120px]">
278
+ {serviceItem.operator_details[2]}
279
+ </span>
280
+ </div>
281
+ </div>
282
+ </div>
283
+ ) : null}
284
+ </div>
285
+ </div>
286
+
287
+ <DateTimeSectionMobile
288
+ onBookButtonPress={onBookButtonPress}
289
+ isCiva={isCiva}
290
+ isSoldOut={isSoldOut}
291
+ isLinatal={isLinatal}
292
+ isPeru={isPeru}
293
+ orignLabel={orignLabel}
294
+ destinationLabel={destinationLabel}
295
+ originIcon={serviceItem.icons?.origin}
296
+ destinationIcon={serviceItem.icons?.destination}
297
+ travelDate={serviceItem.travel_date}
298
+ arrivalDate={serviceItem.arrival_date}
299
+ depTime={serviceItem.dep_time}
300
+ arrTime={serviceItem.arr_time}
301
+ seatTypes={serviceItem.seat_types}
302
+ seatPriceColor={colors.seatPriceColor}
303
+ tooltipBgColor={colors.tooltipBgColor}
304
+ currencySign={currencySign}
305
+ availableSeats={serviceItem.available_seats}
306
+ removeDuplicateSeats={removeDuplicateSeats}
307
+ serviceItem={serviceItem}
308
+ showLastSeats={showLastSeats}
309
+ discountSeatPriceColor={colors.discountSeatPriceColor}
310
+ isTrain={isTrain}
311
+ />
312
+
313
+ {hasDiscount && (
314
+ <div className="flex justify-end">
315
+ {isSoldOut ? (
316
+ <span className="col-span-2 min-[420]:text-[13px] text-right text-[12px] text-[#ccc]">
317
+ Agotado
318
+ </span>
319
+ ) : null}
320
+ </div>
321
+ )}
322
+
323
+ {showLastSeats ? (
324
+ <div className="flex justify-end ">
325
+ {serviceItem?.available_seats < 10 &&
326
+ serviceItem?.available_seats > 0 && (
327
+ <div
328
+ className="text-[10px] text-center"
329
+ style={{
330
+ color: colors.tooltipBgColor,
331
+ }}
332
+ >
333
+ ¡Últimos Asientos!
334
+ </div>
335
+ )}
336
+ </div>
337
+ ) : null}
338
+
339
+ <div className="bg-[#E6E6E6] mt-[10px] mb-[8px] h-[1px]"></div>
340
+
341
+ <BottomAmenitiesMobile
342
+ isSoldOut={isSoldOut}
343
+ amenitiesNodes={amenities()}
344
+ hoursIcon={renderIcon("hours", "14px")}
345
+ duration={serviceItem.duration?.toString()}
346
+ isDirectTrip={serviceItem?.is_direct_trip}
347
+ directoColor={colors.directoColor}
348
+ directoAnim={serviceItem.icons?.directoAnim}
349
+ isChangeTicket={serviceItem.is_change_ticket}
350
+ isPetSeat={isPetSeat}
351
+ petSeatInfo={serviceItem.pet_seat_info}
352
+ petFriendlyAnim={serviceItem.icons?.petFriendlyAnim}
353
+ flexibleAnim={serviceItem.icons?.flexibleAnim}
354
+ isTrackingEnabled={serviceItem?.is_tracking_enabled}
355
+ locationAnim={serviceItem.icons?.locationAnim}
356
+ downArrowIcon={serviceItem.icons?.downArrow}
357
+ showDropdown={isItemExpanded}
358
+ setShowDropdown={() =>
359
+ setIsExpanded && setIsExpanded(isItemExpanded ? null : serviceItem.id)
360
+ }
361
+ onDropdownToggle={() => {
362
+ setIsExpanded && setIsExpanded(isItemExpanded ? null : serviceItem.id);
363
+ }}
364
+ isPeru={isPeru}
365
+ femaleAnim={serviceItem.icons?.femaleAnim}
366
+ ladiesBookedSeats={serviceItem.ladies_booked_seats}
367
+ isDpEnabled={serviceItem.is_dp_enabled}
368
+ isTrain={isTrain}
369
+ seatCategoryText={
370
+ serviceItem.api_type === 78 && serviceItem.number
371
+ ? serviceItem.number
372
+ : undefined
373
+ }
374
+ />
375
+ </div>
376
+
377
+ <ServiceBadgesMobile
378
+ showTopLabel={showTopLabel}
379
+ isSoldOut={isSoldOut}
380
+ colors={colors}
381
+ renderIcon={renderIcon}
382
+ serviceItem={serviceItem}
383
+ isConexion={isConexion}
384
+ isAllinBus={isAllinBus}
385
+ boardingName={boardingName ?? undefined}
386
+ />
387
+ </div>
388
+
389
+ {/* 🔹 EXPANDABLE DROPDOWN (below the card) - Simple offer text when new UI is disabled */}
390
+ {hasOfferText &&
391
+ !isNewUiEnabled &&
392
+ !isSoldOut &&
393
+ !serviceItem?.is_dp_enabled && (
394
+ <div
395
+ className="px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]"
396
+ style={{
397
+ background: colors?.bottomStripColor,
398
+ borderRadius: "0 0 14px 14px",
399
+ zIndex: -1,
400
+ }}
401
+ >
402
+ <div
403
+ className="flex flex-col gap-[8px] text-[12px] min-[420px]:text-[12px] text-[#464647]"
404
+ style={{ lineHeight: 1.6 }}
405
+ >
406
+ <div className="flex justify-between items-center">
407
+ <div
408
+ className={`flex ${(serviceItem?.offer_text || "").length > 10 ? "items-start" : "items-center"}`}
409
+ >
410
+ <div className={isLongOfferText ? "mt-[2px]" : ""}>
411
+ <LottiePlayer
412
+ animationData={serviceItem.icons?.promoAnim}
413
+ width="14px"
414
+ height="14px"
415
+ />
416
+ </div>
417
+ <div
418
+ className={`ml-[4px] flex-1 outline-none ${isLongOfferText ? "mt-[2px]" : ""}`}
419
+ style={{
420
+ color: "#fff",
421
+ lineHeight: 1.4,
422
+ }}
423
+ >
424
+ <span className="whitespace-nowrap min-[380px]:text-[12px]">
425
+ {serviceItem?.offer_text}
426
+ </span>
427
+ </div>
428
+ </div>
429
+ </div>
430
+ </div>
431
+ </div>
432
+ )}
433
+
434
+ {/* 🔹 EXPANDABLE DROPDOWN (below the card) - Countdown/registro when new UI is enabled */}
435
+ {(isNewUiEnabled || (serviceItem?.is_dp_enabled && serviceItem?.dp_discount_percents)) && !isSoldOut && (
436
+ <div
437
+ className="px-[12px] pt-[22px] pb-[8px] relative -z-9 -mt-[15px]"
438
+ style={{
439
+ background: isSoldOut
440
+ ? offerGradientWithOpacity
441
+ : offerGradient,
442
+ borderRadius: "0 0 14px 14px",
443
+ zIndex: -1,
444
+ }}
445
+ >
446
+ <div
447
+ className="flex flex-col gap-[8px] text-[12px] min-[420px]:text-[12px] text-[#464647]"
448
+ style={{ lineHeight: 1.6 }}
449
+ >
450
+ <div className="flex justify-between items-center">
451
+ {serviceItem?.is_dp_enabled &&
452
+ Object.keys(serviceItem?.dp_discount_percents ?? {})
453
+ .length === 0 &&
454
+ (serviceItem?.dp_discounted_seats ?? []).length === 0 ? (
455
+ <div className="flex items-center gap-[6px]">
456
+ <LottiePlayer
457
+ animationData={serviceItem.icons?.starAnimation}
458
+ width="14px"
459
+ height="14px"
460
+ />
461
+
462
+ <span className="text-[#fff]">Más elegido</span>
463
+ </div>
464
+ ) : (
465
+ <div
466
+ className={`flex ${(serviceItem?.offer_text || "").length > 10 ? "items-start" : "items-center"}`}
467
+ >
468
+ <div className={isLongOfferText ? "mt-[2px]" : ""}>
469
+ {serviceItem.icons?.bombAnim && (
470
+ <LottiePlayer
471
+ animationData={serviceItem.icons.bombAnim}
472
+ width="14px"
473
+ height="14px"
474
+ />
475
+ )}
476
+ </div>
477
+ <div
478
+ className={`ml-[4px] flex-1 outline-none ${isLongOfferText ? "mt-[2px]" : ""}`}
479
+ style={{
480
+ color: "#fff",
481
+ lineHeight: 1.4,
482
+ }}
483
+ >
484
+ {!isNewUiEnabled && serviceItem?.offer_text ? (
485
+ <span className="whitespace-nowrap min-[380px]:text-[12px]">
486
+ {serviceItem?.offer_text}
487
+ </span>
488
+ ) : (
489
+ <span className="whitespace-nowrap min-[380px]:text-[12px]">
490
+ Termina en&nbsp;
491
+ <span
492
+ className="bold-text"
493
+ ref={(node) =>
494
+ commonService.startCountdown(node, 599)
495
+ }
496
+ style={{
497
+ fontVariantNumeric: "tabular-nums",
498
+ display: "inline-block",
499
+ }}
500
+ />
501
+ </span>
502
+ )}
503
+ </div>
504
+ </div>
505
+ )}
506
+ <div
507
+ className="flex flex-col items-end"
508
+ style={{
509
+ color: "#fff",
510
+ }}
511
+ >
512
+ <div className="flex items-center">
513
+ <div className="mr-[4px]">
514
+ <LottiePlayer
515
+ animationData={serviceItem.icons?.dotAnimation}
516
+ width="12px"
517
+ height="12px"
518
+ />
519
+ </div>
520
+ <span className="flex-1" style={{ lineHeight: 1.4 }}>
521
+ <span
522
+ className="bold-text"
523
+ ref={(node) =>
524
+ commonService.startViewerCount(node, viewersConfig)
525
+ }
526
+ style={{ fontVariantNumeric: "tabular-nums" }}
527
+ />{" "}
528
+ <span> viendo</span> |{" "}
529
+ <span className="whitespace-nowrap">
530
+ <span
531
+ className="bold-text"
532
+ ref={(node) =>
533
+ commonService.startComprandoCount(node, 4, 16)
534
+ }
535
+ style={{ fontVariantNumeric: "tabular-nums" }}
536
+ />{" "}
537
+ comprando
538
+ </span>
539
+ </span>
540
+ </div>
541
+ </div>
542
+ </div>
543
+ </div>
544
+ </div>
545
+ )}
546
+ <div
547
+ style={{
548
+ display: "grid",
549
+ gridTemplateRows: isItemExpanded ? "1fr" : "0fr",
550
+ opacity: isItemExpanded ? 1 : 0,
551
+ transition:
552
+ "grid-template-rows 0.3s ease-in-out, opacity 0.25s ease-in-out",
553
+ position: "relative",
554
+ zIndex:
555
+ hasOfferText ||
556
+ (serviceItem?.is_dp_enabled && serviceItem?.dp_discount_percents) ||
557
+ isNewUiEnabled
558
+ ? -2
559
+ : -1,
560
+ }}
561
+ >
562
+ <div
563
+ style={{
564
+ overflow: "hidden",
565
+ minHeight: 0,
566
+ position:
567
+ hasOfferText ||
568
+ isNewUiEnabled ||
569
+ serviceItem?.is_dp_enabled
570
+ ? "relative"
571
+ : undefined,
572
+ zIndex:
573
+ serviceItem?.offer_text ||
574
+ isNewUiEnabled ||
575
+ (serviceItem?.is_dp_enabled && serviceItem?.dp_discount_percents)
576
+ ? -3
577
+ : undefined,
578
+ marginTop: hasOfferText ? "-15px" : "-10px",
579
+ }}
580
+ >
581
+ <ExpandedDropdownMobile
582
+ serviceItem={serviceItem}
583
+ isPeru={isPeru}
584
+ petSeatInfo={serviceItem.pet_seat_info}
585
+ petFriendlyAnim={serviceItem.icons?.petFriendlyAnim}
586
+ isSoldOut={isSoldOut}
587
+ isChangeTicket={serviceItem.is_change_ticket === true}
588
+ ladiesBookedSeats={serviceItem.ladies_booked_seats}
589
+ isDpEnabled={serviceItem.is_dp_enabled}
590
+ femaleAnim={serviceItem.icons?.femaleAnim}
591
+ flexibleAnim={serviceItem.icons?.flexibleAnim}
592
+ renderIcon={renderIcon}
593
+ operatorLabel={operatorLabel}
594
+ />
595
+ </div>
596
+ </div>
597
+ </div>
598
+ );
599
+ }
600
+
601
+ export default PeruServiceItemMobile;
@@ -225,7 +225,7 @@ function ServiceItemPB({
225
225
  (serviceItem as any)?.discount_value > 0 &&
226
226
  (serviceItem as any)?.discount_value < 20;
227
227
  const hasOfferText = Boolean(serviceItem?.offer_text) && !isDiscountBelow20;
228
- // const isNewUiEnabled = serviceItem?.discounts?.[0]?.new_ui_enabled === true;
228
+ const isNewUiEnabledPeru = serviceItem?.discounts?.[0]?.new_ui_enabled === true;
229
229
  const isNewUiEnabled = serviceItem?.new_ui_enabled === true;
230
230
 
231
231
  const seats = removeDuplicateSeats
@@ -508,7 +508,7 @@ function ServiceItemPB({
508
508
  setIsExpand={setIsExpand}
509
509
  coachKey={coachKey}
510
510
  isFlores={isFlores}
511
- isNewUiEnabled={isNewUiEnabled}
511
+ isNewUiEnabled={isNewUiEnabledPeru}
512
512
  showLoginOption={showLoginOption}
513
513
  />
514
514
  ) : isNewUi && !isTrain ? (
@@ -10,6 +10,7 @@ import DateTimeSectionMobile from "../../ui/mobileweb/DateTimeSectionMobile";
10
10
  import ExpandedDropdownMobile from "../../ui/mobileweb/ExpandedDropdownMobile";
11
11
  import ServiceBadgesMobile from "../../ui/mobileweb/ServiceBadgesMobile";
12
12
  import FeatureServiceUiMobile from "../../ui/FeaturServiceUiMobile/FeatureServiceUiMobile";
13
+ import PeruServiceItemMobile from "./PeruServiceItemMobile";
13
14
 
14
15
  const SEAT_EXCEPTIONS = ["Asiento mascota"];
15
16
 
@@ -64,6 +65,7 @@ function ServiceItemMobile({
64
65
  wowDealData,
65
66
  isFlores,
66
67
  isAllinBus,
68
+ isPeruSite,
67
69
  }: MobileServiceItemProps): React.ReactElement {
68
70
  const isItemExpanded = serviceItem.id === isExpanded;
69
71
  const isPetSeat = (Object.keys(serviceItem?.pet_seat_info) || []).length > 0;
@@ -196,7 +198,48 @@ function ServiceItemMobile({
196
198
 
197
199
  return (
198
200
  <>
199
- {isNewUi && !isTrain ? (
201
+ {isPeruSite ? (
202
+ <PeruServiceItemMobile
203
+ serviceItem={serviceItem}
204
+ onBookButtonPress={onBookButtonPress}
205
+ colors={colors}
206
+ busStage={busStage}
207
+ orignLabel={orignLabel}
208
+ destinationLabel={destinationLabel}
209
+ amenitiesData={amenitiesData}
210
+ setShowDropdown={setShowDropdown}
211
+ showDropdown={showDropdown}
212
+ isExpanded={isExpanded}
213
+ setIsExpanded={setIsExpanded}
214
+ setAmenetiesAtomValue={setAmenetiesAtomValue}
215
+ isCiva={isCiva}
216
+ currencySign={currencySign}
217
+ isPeru={isPeru}
218
+ showRating={showRating}
219
+ showLastSeats={showLastSeats}
220
+ removeDuplicateSeats={removeDuplicateSeats}
221
+ isLinatal={isLinatal}
222
+ viewersConfig={viewersConfig}
223
+ operatorLabel={operatorLabel}
224
+ isTrain={isTrain}
225
+ isFeatureDropDownExpand={isFeatureDropDownExpand}
226
+ setIsFeatureDropDownExpand={setIsFeatureDropDownExpand}
227
+ ticketQuantity={ticketQuantity}
228
+ onIncreaseTicketQuantity={onIncreaseTicketQuantity}
229
+ onDecreaseTicketQuantity={onDecreaseTicketQuantity}
230
+ cityOrigin={cityOrigin}
231
+ cityDestination={cityDestination}
232
+ isNewUiEnabled={isNewUiEnabled}
233
+ onRemateUiButtonClick={onRemateUiButtonClick}
234
+ selectedTimeSlot={selectedTimeSlot}
235
+ onTimeSlotChange={onTimeSlotChange}
236
+ isTimeDropdownOpen={isTimeDropdownOpen}
237
+ onTimeDropdownToggle={onTimeDropdownToggle}
238
+ wowDealData={wowDealData}
239
+ isFlores={isFlores}
240
+ isAllinBus={isAllinBus}
241
+ />
242
+ ) : isNewUi && !isTrain ? (
200
243
  <FeatureServiceUiMobile
201
244
  serviceItem={serviceItem}
202
245
  showTopLabel={showTopLabel}
@@ -50,6 +50,8 @@ export interface MobileServiceItemProps {
50
50
  discount_value?: number;
51
51
  ui_type?: number;
52
52
  max_discount?: number;
53
+ api_type?: number;
54
+ number?: string;
53
55
  discounts?: Array<{
54
56
  id?: number;
55
57
  name?: string;
@@ -253,4 +255,5 @@ export interface MobileServiceItemProps {
253
255
  isFlores?: boolean;
254
256
  operatorLabel?: string;
255
257
  isAllinBus?: any;
258
+ isPeruSite?: boolean;
256
259
  }