kupos-ui-components-lib 9.9.2 → 9.9.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.
Files changed (43) hide show
  1. package/dist/KuposUIComponent.d.ts +0 -3
  2. package/dist/components/ServiceItem/PeruServiceItemDesktop.d.ts +1 -1
  3. package/dist/components/ServiceItem/PeruServiceItemDesktop.js +2 -2
  4. package/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
  5. package/dist/components/ServiceItem/ServiceItemDesktop.js +31 -30
  6. package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
  7. package/dist/components/ServiceItem/ServiceItemMobile.js +17 -43
  8. package/dist/components/ServiceItem/mobileTypes.d.ts +2 -48
  9. package/dist/components/ServiceItem/types.d.ts +9 -27
  10. package/dist/styles.css +6 -215
  11. package/dist/ui/ExpendedDropDown/ExpandedDropdown.d.ts +2 -1
  12. package/dist/ui/ExpendedDropDown/ExpandedDropdown.js +5 -3
  13. package/dist/ui/OfferBanner.d.ts +0 -2
  14. package/dist/ui/OfferBanner.js +14 -19
  15. package/dist/ui/SeatSection/SeatSection.d.ts +7 -1
  16. package/dist/ui/SeatSection/SeatSection.js +41 -12
  17. package/dist/ui/mobileweb/DateTimeSectionMobile.d.ts +2 -1
  18. package/dist/ui/mobileweb/DateTimeSectionMobile.js +7 -5
  19. package/dist/ui/mobileweb/ExpandedDropdownMobile.js +1 -1
  20. package/dist/ui/mobileweb/SeatSectionMobile.d.ts +2 -1
  21. package/dist/ui/mobileweb/SeatSectionMobile.js +15 -10
  22. package/dist/utils/CommonService.d.ts +1 -4
  23. package/dist/utils/CommonService.js +6 -19
  24. package/package.json +1 -1
  25. package/src/KuposUIComponent.tsx +0 -3
  26. package/src/components/ServiceItem/PeruServiceItemDesktop.tsx +24 -35
  27. package/src/components/ServiceItem/ServiceItemDesktop.tsx +53 -65
  28. package/src/components/ServiceItem/ServiceItemMobile.tsx +290 -387
  29. package/src/components/ServiceItem/mobileTypes.ts +8 -50
  30. package/src/components/ServiceItem/types.ts +25 -39
  31. package/src/styles.css +0 -15
  32. package/src/ui/ExpendedDropDown/ExpandedDropdown.tsx +5 -3
  33. package/src/ui/OfferBanner.tsx +10 -31
  34. package/src/ui/SeatSection/SeatSection.tsx +86 -21
  35. package/src/ui/mobileweb/DateTimeSectionMobile.tsx +38 -33
  36. package/src/ui/mobileweb/ExpandedDropdownMobile.tsx +1 -1
  37. package/src/ui/mobileweb/SeatSectionMobile.tsx +12 -7
  38. package/src/utils/CommonService.ts +8 -27
  39. package/src/assets/images/anims/service_list/flame_anim.json +0 -1
  40. package/src/assets/images/anims/service_list/thunder_icon.json +0 -1
  41. package/src/assets/images/anims/service_list/users_anim.json +0 -1
  42. package/src/ui/FeaturServiceUiMobile/FeatureServiceUiMobile.tsx +0 -575
  43. package/src/ui/FeatureServiceUI/FeatureServiceUi.tsx +0 -610
@@ -46,20 +46,6 @@ export interface MobileServiceItemProps {
46
46
  dp_discount_percents?: Record<string, number>;
47
47
  dp_discounted_seats?: string[];
48
48
  dep_validation_text?: string;
49
- discount_type?: string;
50
- discount_value?: number;
51
- max_discount?: number;
52
- discounts?: Array<{
53
- id?: number;
54
- name?: string;
55
- send_discount_to_api?: boolean;
56
- new_ui_enabled?: boolean;
57
- discount?: number;
58
- seatwise_breakdown?: any;
59
- seat_wise_discounts?: any;
60
- total_amount?: number;
61
- promotional_text?: string;
62
- }>;
63
49
  metaData?: {};
64
50
  is_tracking_enabled?: boolean;
65
51
  show_top_label?: boolean;
@@ -135,36 +121,21 @@ export interface MobileServiceItemProps {
135
121
  bombAnim?: string;
136
122
  whiteBoardingIcon?: string;
137
123
  downArrow?: string;
138
- personIcon?: string
124
+ personIcon?: string;
139
125
  specialDeparture?: string;
140
126
  fireIcon?: string;
141
127
  directoIcon?: string;
142
- whiteFireIcon?: string
143
- femaleAnim?:string
144
- thunderAnim?: string
145
- personsAnim?: string
146
- whiteOrigin?: string,
147
- whiteDestination?: string,
148
- userIcon?: string,
149
-
150
- sheildIcon?: string,
151
- busIcon?: string,
152
- whiteDownArrow?: string,
153
- empressaIcon?: string,
154
- flexibleIcon?: string,
155
- listoIcon?: string,
156
- precioIcon?: string,
157
- confirmarIcon?: string
128
+ whiteFireIcon?: string;
129
+ femaleAnim?: string;
158
130
  cancelTicketIcon?: string;
159
131
  changeTicketIcon?: string;
160
132
  petFriendlyIcon?: string;
161
- womenSeatIcon?: string
133
+ womenSeatIcon?: string;
162
134
  [key: string]: string | Record<string, string | undefined> | undefined;
163
135
  };
164
136
  useLottieFor?: string[];
165
137
  };
166
138
  onBookButtonPress?: () => void;
167
- onRemateUiButtonClick?: ()=> void;
168
139
  terminals?: any[];
169
140
  showDropdown?: boolean;
170
141
  setShowDropdown?: (value: boolean) => void;
@@ -208,7 +179,7 @@ export interface MobileServiceItemProps {
208
179
  seatPriceColor?: string;
209
180
  rightGradiantColor?: string;
210
181
  leftGradiantColor?: string;
211
- discountSeatPriceColor?: string
182
+ discountSeatPriceColor?: string;
212
183
  };
213
184
  isCiva?: boolean;
214
185
  currencySign?: string;
@@ -221,26 +192,13 @@ export interface MobileServiceItemProps {
221
192
  showLastSeats?: boolean;
222
193
  removeDuplicateSeats?: boolean;
223
194
  isLinatal?: boolean;
224
- viewersConfig?: {
195
+ viewersConfig?: {
225
196
  min: number;
226
197
  max: number;
227
198
  interval?: number; // ms, default 5000
228
199
  label?: string; // e.g. "personas están viendo este viaje"
229
200
  icon?: string; // optional icon URL
230
201
  };
231
- isFeatureDropDownExpand?: any;
232
- setIsFeatureDropDownExpand?: (value: any) => void;
233
- ticketQuantity?: number;
234
- onIncreaseTicketQuantity?: (serviceItem: MobileServiceItemProps["serviceItem"]) => void;
235
- onDecreaseTicketQuantity?: (serviceItem: MobileServiceItemProps["serviceItem"]) => void;
236
- cityOrigin?: { value: number; label: string };
237
- cityDestination?: { value: number; label: string };
238
- isNewUi?: boolean
239
-
240
- selectedTimeSlot?: string;
241
- onTimeSlotChange?: (slot: string) => void;
242
- isTimeDropdownOpen?: string | number | null;
243
- onTimeDropdownToggle?: (id?: string | number | null) => void;
244
- wowDealData?: any;
245
- isFlores?: boolean;
202
+ operatorLabel?: string;
203
+ isTrain?: boolean;
246
204
  }
@@ -47,9 +47,6 @@ export interface ServiceItemProps {
47
47
  discount_type?: string;
48
48
  discount_value?: number;
49
49
  max_discount?: number;
50
- discounts?: Array<{
51
- new_ui_enabled?: boolean;
52
- }>;
53
50
  is_transpordo?: boolean;
54
51
  is_train_type?: boolean;
55
52
  operator_service_name?: string;
@@ -128,31 +125,18 @@ export interface ServiceItemProps {
128
125
  seatFallBackIcon: string;
129
126
  headPhoneIcon?: string;
130
127
  allowCancellationIcon?: string;
131
- whiteBoardingIcon?: string
132
- bombJson?:string
133
- downArrow?:string
134
- personIcon?: string
135
- whiteFireIcon?: string
136
- fireIcon?: string
128
+ whiteBoardingIcon?: string;
129
+ bombJson?: string;
130
+ downArrow?: string;
131
+ personIcon?: string;
132
+ whiteFireIcon?: string;
133
+ fireIcon?: string;
137
134
 
138
- whiteOrigin?: string,
139
- whiteDestination?: string,
140
- userIcon?: string,
141
-
142
- sheildIcon?: string,
143
- busIcon?: string,
144
- whiteDownArrow?: string,
145
- empressaIcon?: string,
146
- flexibleIcon?: string,
147
- listoIcon?: string,
148
- precioIcon?: string,
149
- confirmarIcon?: string
150
135
  [key: string]: string | Record<string, string | undefined> | undefined;
151
136
  };
152
137
  useLottieFor?: string[];
153
138
  };
154
139
  onBookButtonPress?: () => void;
155
- onRemateUiButtonClick?: ()=>void;
156
140
  terminals?: any[];
157
141
  t?: (key: string) => string;
158
142
  serviceDetailsLoading?: boolean;
@@ -177,7 +161,7 @@ export interface ServiceItemProps {
177
161
  seatPriceColor?: string;
178
162
  rightGradiantColor?: string;
179
163
  leftGradiantColor?: string;
180
- discountSeatPriceColor?: string
164
+ discountSeatPriceColor?: string;
181
165
  };
182
166
  cityOrigin?: { value: number; label: string };
183
167
  cityDestination?: { value: number; label: string };
@@ -231,12 +215,7 @@ export interface ServiceItemProps {
231
215
  isAllinBus?: boolean;
232
216
  isExpand?: any;
233
217
  setIsExpand?: (value: any) => void;
234
- isFeatureDropDownExpand?: any;
235
- setIsFeatureDropDownExpand?: (value: any) => void;
236
- ticketQuantity?: number;
237
- onIncreaseTicketQuantity?: (serviceItem: ServiceItemProps["serviceItem"]) => void;
238
- onDecreaseTicketQuantity?: (serviceItem: ServiceItemProps["serviceItem"]) => void;
239
- coachKey?: number
218
+ coachKey?: number;
240
219
  viewersConfig?: {
241
220
  min: number;
242
221
  max: number;
@@ -244,14 +223,21 @@ export interface ServiceItemProps {
244
223
  label?: string; // e.g. "personas están viendo este viaje"
245
224
  icon?: string; // optional icon URL
246
225
  };
247
- isNewUi?: boolean
248
- showLoginModal?: any
249
- isLoggedIn?: any
250
- showLoginOption?: boolean
251
- selectedTimeSlot?: string;
252
- onTimeSlotChange?: (slot: string) => void;
253
- isTimeDropdownOpen?: string | number | null;
254
- onTimeDropdownToggle?: (id?: string | number | null) => void;
255
- wowDealData?: any;
256
- isNewUiEnabled?: boolean;
226
+ showLoginModal?: any;
227
+ isLoggedIn?: any;
228
+ showLoginOption?: boolean;
229
+ isTrain?: boolean;
230
+ selectedSeatKey?: any;
231
+ onSeatSelect?: (
232
+ key: any,
233
+ price: number,
234
+ seatKey: string,
235
+ apiSeatType?: string,
236
+ ) => void;
237
+ onTrainButtonClick?: any;
238
+ showSeatSelectionError?: string | null;
239
+ onShowSeatSelectionError?: (serviceId: string) => void;
240
+ onClearSeatSelectionError?: () => void;
241
+ isFlores?: boolean;
242
+ operatorLabel?: string;
257
243
  }
package/src/styles.css CHANGED
@@ -93,21 +93,6 @@
93
93
  display: none;
94
94
  }
95
95
 
96
- /* Time slot dropdown */
97
- .kupos-time-dd > summary {
98
- list-style: none;
99
- }
100
- .kupos-time-dd > summary::-webkit-details-marker {
101
- display: none;
102
- }
103
- .kupos-time-chevron {
104
- transition: transform 200ms ease;
105
- flex-shrink: 0;
106
- }
107
- .kupos-time-dd[open] .kupos-time-chevron {
108
- transform: rotate(180deg);
109
- }
110
-
111
96
  .hide-scrollbar {
112
97
  -ms-overflow-style: none;
113
98
  scrollbar-width: none;
@@ -16,6 +16,7 @@ interface ExpandedDropdownProps {
16
16
  ladiesBookedSeats?: string;
17
17
  isDpEnabled?: boolean;
18
18
  renderIcon?: any;
19
+ operatorLabel?: string;
19
20
  }
20
21
 
21
22
  function ExpandedDropdown({
@@ -28,6 +29,7 @@ function ExpandedDropdown({
28
29
  ladiesBookedSeats,
29
30
  isDpEnabled,
30
31
  renderIcon,
32
+ operatorLabel,
31
33
  }: ExpandedDropdownProps): React.ReactElement {
32
34
  const hasPetInfo =
33
35
  serviceItem.pet_seat_info &&
@@ -58,12 +60,12 @@ function ExpandedDropdown({
58
60
  </span> */}
59
61
  <span>
60
62
  <span className="bold-text">Pasaje flexible:</span> Tu pasaje
61
- puede ser cambiado de manera online{" "}
63
+ puede ser cambiado sin costo{" "}
62
64
  <span className="bold-text">
63
65
  hasta {serviceItem?.change_ticket_hours || 6} horas antes
64
66
  </span>{" "}
65
- de la salida del bus. El monto será reembolsado a tu billetera
66
- kupospay.
67
+ de la salida del bus. El monto será reembolsado a tu billetera{" "}
68
+ {operatorLabel ?? "kupospay"}.
67
69
  </span>
68
70
  </div>
69
71
  ) : (
@@ -18,9 +18,7 @@ interface OfferBannerProps {
18
18
  showLoginModal: any;
19
19
  viewersConfig: ServiceItemProps["viewersConfig"];
20
20
  getAnimationIcon: (name: string) => any;
21
- showLoginOption?: boolean
22
- isNewUiEnabled?: boolean;
23
- colors: any;
21
+ showLoginOption?: boolean;
24
22
  }
25
23
 
26
24
  const OfferBanner: React.FC<OfferBannerProps> = ({
@@ -33,14 +31,12 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
33
31
  viewersConfig,
34
32
  getAnimationIcon,
35
33
  showLoginOption,
36
- isNewUiEnabled,
37
- colors,
38
34
  }) => {
39
35
  return (
40
36
  <div
41
- className="text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[44px] pt-[50px] rounded-b-[14px] text-[14px] mt-[10px]"
37
+ className="text-white p-[10px_15px] text-left w-full flex items-center absolute -bottom-[36px] pt-[50px] rounded-b-[14px] text-[14px]"
42
38
  style={{
43
- background: serviceItem?.offer_text && !isNewUiEnabled ? colors?.bottomStripColor : offerGradient,
39
+ background: offerGradient,
44
40
  opacity: isSoldOut ? 0.5 : 1,
45
41
  // zIndex: 0,
46
42
  }}
@@ -61,7 +57,6 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
61
57
  <span>Servicio popular entre los usuarios</span>
62
58
  </div>
63
59
  ) : (
64
- (isNewUiEnabled && serviceItem?.offer_text) ? (
65
60
  <div className="flex items-center">
66
61
  <LottiePlayer
67
62
  animationData={getAnimationIcon("bombAnimation")}
@@ -78,14 +73,18 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
78
73
  {(serviceItem?.offer_text || "").length > 30
79
74
  ? (serviceItem?.offer_text || "").slice(0, 30) + "..."
80
75
  : serviceItem?.offer_text || ""}{" "}
81
- {isLoggedIn && showLoginOption ? null : (
76
+ {isLoggedIn && showLoginOption ? null : Object.keys(
77
+ serviceItem?.dp_discount_percents ?? {},
78
+ ).length > 0 ||
79
+ (serviceItem?.dp_discounted_seats ?? []).length >
80
+ 0 ? null : (
82
81
  <span onClick={showLoginModal} className="cursor-pointer">
83
82
  - registro
84
83
  </span>
85
84
  )}{" "}
86
85
  &nbsp;
87
86
  </span>{" "}
88
- {serviceItem?.offer_text ? "|" : ""}
87
+ {serviceItem?.offer_text ? "| " : ""}
89
88
  Termina en&nbsp;
90
89
  <span
91
90
  className="bold-text text-end"
@@ -96,28 +95,9 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
96
95
  }}
97
96
  />
98
97
  </div>
99
- </div>)
100
- : (serviceItem?.offer_text && !isNewUiEnabled) && (
101
- <div className="flex items-center">
102
- <LottiePlayer
103
- animationData={getAnimationIcon("promoAnim")}
104
- width="18px"
105
- height="18px"
106
- />
107
- <div className="flex items-center mt-[2px]">
108
- <span
109
- className="bold-text"
110
- style={{
111
- marginLeft: serviceItem?.offer_text ? "6px" : "3px",
112
- }}
113
- >
114
- {(serviceItem?.offer_text || "")}
115
- </span>{" "}
116
- </div>
117
- </div>)
98
+ </div>
118
99
  )}
119
100
  </div>
120
- {(isNewUiEnabled || serviceItem?.is_dp_enabled) && (
121
101
  <div className="flex items-center">
122
102
  {/* {renderIcon("personIcon", "16px")} */}
123
103
  <LottiePlayer
@@ -155,7 +135,6 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
155
135
  </span>
156
136
  </span>
157
137
  </div>
158
- )}
159
138
  </div>
160
139
  </div>
161
140
  );
@@ -7,6 +7,8 @@ interface SeatType {
7
7
  label: string;
8
8
  fare: number;
9
9
  key: any;
10
+ apiSeatType?: string;
11
+ api_seat_type?: string;
10
12
  }
11
13
 
12
14
  interface SeatSectionProps {
@@ -21,6 +23,15 @@ interface SeatSectionProps {
21
23
  serviceItem?: any;
22
24
  renderIcon?: (iconKey: string, size?: string) => React.ReactNode;
23
25
  discountSeatPriceColor?: string;
26
+ isTrain?: boolean;
27
+ selectedSeatKey?: any;
28
+ onSeatSelect?: (
29
+ key: any,
30
+ price: number,
31
+ seatKey: string,
32
+ apiSeatType?: string,
33
+ ) => void;
34
+ topLabelColor?: string;
24
35
  }
25
36
 
26
37
  function getAllSeatTypes(seatTypes: SeatType[]) {
@@ -31,6 +42,8 @@ function getAllSeatTypes(seatTypes: SeatType[]) {
31
42
  let seatTypesWithPrices = seatTypes.filter(Boolean).map((val) => ({
32
43
  label: val?.label,
33
44
  price: val?.fare,
45
+ key: val?.key,
46
+ apiSeatType: val?.apiSeatType || val?.api_seat_type,
34
47
  }));
35
48
 
36
49
  seatTypesWithPrices.sort((a, b) => a.price - b.price);
@@ -38,7 +51,7 @@ function getAllSeatTypes(seatTypes: SeatType[]) {
38
51
  return seatTypesWithPrices;
39
52
  }
40
53
 
41
- function getSortedSeatTypes(seatTypes: SeatType[]) {
54
+ function getSortedSeatTypes(seatTypes: SeatType[], isTrain: any) {
42
55
  if (!seatTypes?.length) {
43
56
  return [{ label: "Salon cama", price: 0 }];
44
57
  }
@@ -52,7 +65,9 @@ function getSortedSeatTypes(seatTypes: SeatType[]) {
52
65
  seatTypesWithPrices[2] = seatTypesWithPrices[premiumIndex];
53
66
  }
54
67
 
55
- seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
68
+ if (!isTrain) {
69
+ seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
70
+ }
56
71
 
57
72
  const seenPrices = new Set<number>();
58
73
  seatTypesWithPrices = seatTypesWithPrices.filter((seat) => {
@@ -97,14 +112,18 @@ function SeatSection({
97
112
  priceColor,
98
113
  currencySign,
99
114
  removeDuplicateSeats,
115
+ selectedSeatKey,
116
+ onSeatSelect,
100
117
  isPeru,
101
118
  serviceItem,
102
119
  renderIcon,
103
120
  dpSeatColor,
104
121
  discountSeatPriceColor,
122
+ isTrain,
123
+ topLabelColor,
105
124
  }: SeatSectionProps): React.ReactElement {
106
125
  const uniqueSeats = getUniqueSeats(seatTypes);
107
- const sortedSeatTypes = getSortedSeatTypes(seatTypes);
126
+ const sortedSeatTypes = getSortedSeatTypes(seatTypes, isTrain);
108
127
  const numberOfSeats = getNumberOfSeats(seatTypes);
109
128
  const isCentered = numberOfSeats < 2 || removeDuplicateSeats;
110
129
 
@@ -116,22 +135,68 @@ function SeatSection({
116
135
  const renderSeatNames = () => {
117
136
  const seats = removeDuplicateSeats ? uniqueSeats : sortedSeatTypes;
118
137
 
119
- return seats.map((val, key: number) =>
120
- SEAT_EXCEPTIONS.includes(val.label) ? null : (
121
- <span
122
- key={key}
123
- className={`flex items-center justify-between text-[13.33px] ${
124
- isSoldOut ? "text-[#c0c0c0]" : ""
125
- }`}
138
+ return seats.map((val, key: number) => {
139
+ return SEAT_EXCEPTIONS.includes(val.label) ? null : (
140
+ <div
141
+ className="flex items-center"
142
+ style={isTrain ? { cursor: "pointer" } : undefined}
143
+ onClick={
144
+ isTrain && !isSoldOut
145
+ ? () =>
146
+ val.label === selectedSeatKey
147
+ ? onSeatSelect?.(null, 0, "", "")
148
+ : onSeatSelect?.(
149
+ val.label,
150
+ val.price,
151
+ val.key,
152
+ (val as any).apiSeatType,
153
+ )
154
+ : undefined
155
+ }
126
156
  >
127
- {typeof val.label === "string" || typeof val.label === "number"
128
- ? removeDuplicateSeats && isPeru
129
- ? CommonService.truncateSeatLabel(val.label)
130
- : val.label
131
- : null}
132
- </span>
133
- ),
134
- );
157
+ {isTrain && (
158
+ <div
159
+ style={{
160
+ border: `1px solid ${val.label === selectedSeatKey ? topLabelColor : "#ccc"}`,
161
+ borderRadius: "50%",
162
+ width: "14px",
163
+ height: "14px",
164
+ minWidth: "14px",
165
+ marginRight: "10px",
166
+ display: "flex",
167
+ alignItems: "center",
168
+ justifyContent: "center",
169
+ }}
170
+ >
171
+ {val.label === selectedSeatKey && (
172
+ <div
173
+ style={{
174
+ backgroundColor: topLabelColor,
175
+ borderRadius: "50%",
176
+ width: "7px",
177
+ height: "7px",
178
+ }}
179
+ />
180
+ )}
181
+ </div>
182
+ )}
183
+ <span
184
+ key={key}
185
+ className={`flex items-center justify-between text-[13.33px] ${
186
+ isSoldOut ? "text-[#c0c0c0]" : ""
187
+ }`}
188
+ >
189
+ {typeof val.label === "string" || typeof val.label === "number"
190
+ ? removeDuplicateSeats && isPeru
191
+ ? CommonService.truncateSeatLabel(val.label)
192
+ : isTrain
193
+ ? CommonService.truncateSeatLabel(val.label, 8)
194
+ : val.label
195
+ : null}
196
+ </span>
197
+ </div>
198
+ );
199
+ });
135
200
  };
136
201
 
137
202
  const renderSeatPrices = () => {
@@ -277,7 +342,7 @@ function SeatSection({
277
342
  {!isNaN(Number(dpDiscountPercent)) &&
278
343
  Number(dpDiscountPercent) > 0 && (
279
344
  <span
280
- className={`rounded-[100px] ${discountSeatPriceColor} bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white`}
345
+ className="rounded-[100px] bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white"
281
346
  style={{
282
347
  animation: "pulse-zoom 2s ease-in-out infinite",
283
348
  whiteSpace: "nowrap",
@@ -319,7 +384,7 @@ function SeatSection({
319
384
  >
320
385
  <div
321
386
  className="absolute"
322
- style={{ left: isPeru ? "-1px" : "-19px", bottom: "1px" }}
387
+ style={{ left: isPeru ? "-19px" : "-19px", bottom: "1px" }}
323
388
  >
324
389
  {renderIcon("fireIcon", "16px")}
325
390
  </div>
@@ -476,7 +541,7 @@ function SeatSection({
476
541
  <div
477
542
  className="absolute"
478
543
  style={{
479
- left: isPeru ? "-1px" : "-18px",
544
+ left: isPeru ? "-18px" : "-18px",
480
545
  bottom: "1px",
481
546
  }}
482
547
  >
@@ -25,6 +25,7 @@ interface DateTimeSectionMobileProps {
25
25
  tooltipBgColor?: string;
26
26
  showLastSeats?: boolean;
27
27
  discountSeatPriceColor?: string;
28
+ isTrain?: boolean;
28
29
  }
29
30
 
30
31
  const pad = (n: number) => (n < 10 ? "0" + n : String(n));
@@ -67,41 +68,43 @@ const TimeRow: React.FC<TimeRowProps> = ({
67
68
  isSoldOut,
68
69
  }) => {
69
70
  const formattedDate = DateService.getServiceItemDate(date);
70
- const dotPositionClass = formattedDate.includes("dom") ? "max-[399px]:left-[53%]" : "";
71
- return <div
72
- className={`flex items-center min-[420]:text-[13px] text-[12px] justify-between ${
73
- isSoldOut ? "text-[#c0c0c0]" : ""
74
- }`}
75
- >
76
- <div className="flex items-center" style={{ flex: 1 }}>
77
- <div>
78
- {" "}
79
- {label ? (
80
- <div className="w-[60px]">{label}</div>
81
- ) : (
82
- <div className="w-[12px] h-auto mr-[5px]">
83
- <img
84
- src={icon}
85
- alt={alt}
86
- className={`w-[12px] h-auto mr-[5px] ${
87
- isSoldOut ? "grayscale" : ""
88
- }`}
89
- />
90
- </div>
91
- )}
92
- </div>
93
- <div
94
- className="flex items-center relative capitalize justify-between"
95
- style={{ flex: 1 }}
96
- >
97
- <span className="cursor-pointer black-text">
98
- {formattedDate}
99
- </span>
100
- <div className={`absolute left-[50%] ${dotPositionClass}`}>•</div>
101
- <div className="font-[900] relative black-text">{timeContent}</div>
71
+ const dotPositionClass = formattedDate.includes("dom")
72
+ ? "max-[399px]:left-[53%]"
73
+ : "";
74
+ return (
75
+ <div
76
+ className={`flex items-center min-[420]:text-[13px] text-[12px] justify-between ${
77
+ isSoldOut ? "text-[#c0c0c0]" : ""
78
+ }`}
79
+ >
80
+ <div className="flex items-center" style={{ flex: 1 }}>
81
+ <div>
82
+ {" "}
83
+ {label ? (
84
+ <div className="w-[60px]">{label}</div>
85
+ ) : (
86
+ <div className="w-[12px] h-auto mr-[5px]">
87
+ <img
88
+ src={icon}
89
+ alt={alt}
90
+ className={`w-[12px] h-auto mr-[5px] ${
91
+ isSoldOut ? "grayscale" : ""
92
+ }`}
93
+ />
94
+ </div>
95
+ )}
96
+ </div>
97
+ <div
98
+ className="flex items-center relative capitalize justify-between"
99
+ style={{ flex: 1 }}
100
+ >
101
+ <span className="cursor-pointer black-text">{formattedDate}</span>
102
+ <div className={`absolute left-[50%] ${dotPositionClass}`}>•</div>
103
+ <div className="font-[900] relative black-text">{timeContent}</div>
104
+ </div>
102
105
  </div>
103
106
  </div>
104
- </div>;
107
+ );
105
108
  };
106
109
 
107
110
  function DateTimeSectionMobile({
@@ -127,6 +130,7 @@ function DateTimeSectionMobile({
127
130
  tooltipBgColor,
128
131
  showLastSeats,
129
132
  discountSeatPriceColor,
133
+ isTrain,
130
134
  }: DateTimeSectionMobileProps): React.ReactElement {
131
135
  const { cleaned: cleanedDepTime, hasAM, hasPM } = getCleanedDepTime(depTime);
132
136
 
@@ -198,6 +202,7 @@ function DateTimeSectionMobile({
198
202
  tooltipBgColor={tooltipBgColor}
199
203
  showLastSeats={showLastSeats}
200
204
  discountSeatPriceColor={discountSeatPriceColor}
205
+ isTrain={isTrain}
201
206
  />
202
207
  </div>
203
208
  );
@@ -56,7 +56,7 @@ function ExpandedDropdownMobile({
56
56
 
57
57
  <span>
58
58
  <span className="bold-text">Pasaje flexible:</span> Tu pasaje
59
- puede ser cambiado de manera online{" "}
59
+ puede ser cambiado sin costo{" "}
60
60
  <span className="bold-text">
61
61
  hasta {serviceItem?.change_ticket_hours || 6} horas antes
62
62
  </span>{" "}