kupos-ui-components-lib 9.11.6 → 9.11.8

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 (29) hide show
  1. package/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
  2. package/dist/components/ServiceItem/ServiceItemDesktop.js +22 -4
  3. package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
  4. package/dist/components/ServiceItem/ServiceItemMobile.js +1 -1
  5. package/dist/components/ServiceItem/mobileTypes.d.ts +1 -0
  6. package/dist/components/ServiceItem/types.d.ts +7 -0
  7. package/dist/styles.css +6 -0
  8. package/dist/ui/BottomAmenities/BottomAmenities.d.ts +2 -1
  9. package/dist/ui/BottomAmenities/BottomAmenities.js +4 -2
  10. package/dist/ui/DateTimeSection/DateTimeSection.js +4 -4
  11. package/dist/ui/SeatSection/SeatSection.d.ts +7 -1
  12. package/dist/ui/SeatSection/SeatSection.js +48 -14
  13. package/dist/ui/mobileweb/DateTimeSectionMobile.d.ts +2 -1
  14. package/dist/ui/mobileweb/DateTimeSectionMobile.js +13 -7
  15. package/dist/ui/mobileweb/SeatSectionMobile.d.ts +2 -1
  16. package/dist/ui/mobileweb/SeatSectionMobile.js +24 -16
  17. package/dist/utils/CommonService.d.ts +1 -1
  18. package/dist/utils/CommonService.js +5 -1
  19. package/package.json +1 -1
  20. package/src/components/ServiceItem/ServiceItemDesktop.tsx +47 -1
  21. package/src/components/ServiceItem/ServiceItemMobile.tsx +2 -1
  22. package/src/components/ServiceItem/mobileTypes.ts +31 -26
  23. package/src/components/ServiceItem/types.ts +12 -0
  24. package/src/ui/BottomAmenities/BottomAmenities.tsx +5 -1
  25. package/src/ui/DateTimeSection/DateTimeSection.tsx +4 -4
  26. package/src/ui/SeatSection/SeatSection.tsx +95 -23
  27. package/src/ui/mobileweb/DateTimeSectionMobile.tsx +47 -34
  28. package/src/ui/mobileweb/SeatSectionMobile.tsx +29 -13
  29. package/src/utils/CommonService.ts +7 -1
@@ -131,6 +131,13 @@ function ServiceItemPB({
131
131
  showLoginModal,
132
132
  isLoggedIn,
133
133
  showLoginOption,
134
+ isTrain,
135
+ selectedSeatKey,
136
+ onSeatSelect,
137
+ onTrainButtonClick,
138
+ showSeatSelectionError,
139
+ onShowSeatSelectionError,
140
+ onClearSeatSelectionError,
134
141
  isFeatureDropDownExpand,
135
142
  setIsFeatureDropDownExpand,
136
143
  ticketQuantity,
@@ -145,6 +152,15 @@ function ServiceItemPB({
145
152
  isFlores,
146
153
  operatorLabel,
147
154
  }: ServiceItemProps & { currencySign?: string }): React.ReactElement {
155
+ const handleSeatSelect = (
156
+ key: any,
157
+ price: number,
158
+ seatKey: string,
159
+ apiSeatType?: string,
160
+ ) => {
161
+ onClearSeatSelectionError?.();
162
+ onSeatSelect?.(key, price, seatKey, apiSeatType);
163
+ };
148
164
  const getAnimationIcon = (icon: string) => {
149
165
  const animation = ANIMATION_MAP[icon];
150
166
  if (!animation) return null;
@@ -366,6 +382,17 @@ function ServiceItemPB({
366
382
  return;
367
383
  }
368
384
 
385
+ if (isTrain) {
386
+ if (!selectedSeatKey) {
387
+ onShowSeatSelectionError?.(serviceItem.id);
388
+ return;
389
+ }
390
+ if (onTrainButtonClick) {
391
+ onTrainButtonClick();
392
+ return;
393
+ }
394
+ }
395
+
369
396
  onBookButtonPress();
370
397
  };
371
398
 
@@ -558,7 +585,9 @@ function ServiceItemPB({
558
585
  : "",
559
586
  }}
560
587
  >
561
- <div className="grid text-[#464647] w-full [grid-template-columns:20%_30%_2.5%_24%_15.5%] gap-x-[2%] items-center">
588
+ <div
589
+ className={`grid text-[#464647] w-full ${isTrain ? "[grid-template-columns:16%_30%_2.5%_28%_15.5%]" : "[grid-template-columns:20%_30%_2.5%_24%_15.5%]"} gap-x-[2%] items-center`}
590
+ >
562
591
  {/* OPERATOR LOGO */}
563
592
  <div className="flex flex-col gap-[5px]">
564
593
  <div>
@@ -620,6 +649,10 @@ function ServiceItemPB({
620
649
  isPeru={isPeru}
621
650
  renderIcon={renderIcon}
622
651
  discountSeatPriceColor={colors.discountSeatPriceColor}
652
+ isTrain={isTrain}
653
+ selectedSeatKey={selectedSeatKey}
654
+ onSeatSelect={handleSeatSelect}
655
+ topLabelColor={colors.topLabelColor}
623
656
  tooltipColor={colors.tooltipColor}
624
657
  />
625
658
  </div>
@@ -636,6 +669,18 @@ function ServiceItemPB({
636
669
  soldOutIcon={renderIcon("soldOutIcon", "14px")}
637
670
  onClick={checkMidnight}
638
671
  />
672
+ {showSeatSelectionError === serviceItem.id && isTrain && (
673
+ <div className="flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]">
674
+ <div
675
+ className="text-[9px] text-center whitespace-nowrap"
676
+ style={{
677
+ color: colors.seatPriceColor,
678
+ }}
679
+ >
680
+ Selecciona el tipo de servicio
681
+ </div>
682
+ </div>
683
+ )}
639
684
  {showLastSeats ? (
640
685
  <div className="flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]">
641
686
  {serviceItem?.available_seats < 10 &&
@@ -668,6 +713,7 @@ function ServiceItemPB({
668
713
  setIsExpand(isItemExpanded ? null : serviceItem.id)
669
714
  }
670
715
  isPeru={isPeru}
716
+ isTrain={isTrain}
671
717
  />
672
718
  </div>
673
719
  </div>
@@ -46,6 +46,8 @@ function ServiceItemMobile({
46
46
  removeDuplicateSeats,
47
47
  isLinatal,
48
48
  viewersConfig,
49
+ operatorLabel,
50
+ isTrain,
49
51
  isFeatureDropDownExpand,
50
52
  setIsFeatureDropDownExpand,
51
53
  ticketQuantity,
@@ -61,7 +63,6 @@ function ServiceItemMobile({
61
63
  onTimeDropdownToggle,
62
64
  wowDealData,
63
65
  isFlores,
64
- operatorLabel
65
66
  }: MobileServiceItemProps): React.ReactElement {
66
67
  const isItemExpanded = serviceItem.id === isExpanded;
67
68
  const isPetSeat = (Object.keys(serviceItem?.pet_seat_info) || []).length > 0;
@@ -135,36 +135,36 @@ export interface MobileServiceItemProps {
135
135
  bombAnim?: string;
136
136
  whiteBoardingIcon?: string;
137
137
  downArrow?: string;
138
- personIcon?: string
138
+ personIcon?: string;
139
139
  specialDeparture?: string;
140
140
  fireIcon?: string;
141
141
  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
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;
158
158
  cancelTicketIcon?: string;
159
159
  changeTicketIcon?: string;
160
160
  petFriendlyIcon?: string;
161
- womenSeatIcon?: string
161
+ womenSeatIcon?: string;
162
162
  [key: string]: string | Record<string, string | undefined> | undefined;
163
163
  };
164
164
  useLottieFor?: string[];
165
165
  };
166
166
  onBookButtonPress?: () => void;
167
- onRemateUiButtonClick?: ()=> void;
167
+ onRemateUiButtonClick?: () => void;
168
168
  terminals?: any[];
169
169
  showDropdown?: boolean;
170
170
  setShowDropdown?: (value: boolean) => void;
@@ -208,7 +208,7 @@ export interface MobileServiceItemProps {
208
208
  seatPriceColor?: string;
209
209
  rightGradiantColor?: string;
210
210
  leftGradiantColor?: string;
211
- discountSeatPriceColor?: string
211
+ discountSeatPriceColor?: string;
212
212
  };
213
213
  isCiva?: boolean;
214
214
  currencySign?: string;
@@ -221,23 +221,28 @@ export interface MobileServiceItemProps {
221
221
  showLastSeats?: boolean;
222
222
  removeDuplicateSeats?: boolean;
223
223
  isLinatal?: boolean;
224
- viewersConfig?: {
224
+ viewersConfig?: {
225
225
  min: number;
226
226
  max: number;
227
227
  interval?: number; // ms, default 5000
228
228
  label?: string; // e.g. "personas están viendo este viaje"
229
229
  icon?: string; // optional icon URL
230
230
  };
231
- isFeatureDropDownExpand?: any;
231
+ isTrain?: boolean;
232
+ isFeatureDropDownExpand?: any;
232
233
  setIsFeatureDropDownExpand?: (value: any) => void;
233
234
  ticketQuantity?: number;
234
- onIncreaseTicketQuantity?: (serviceItem: MobileServiceItemProps["serviceItem"]) => void;
235
- onDecreaseTicketQuantity?: (serviceItem: MobileServiceItemProps["serviceItem"]) => void;
235
+ onIncreaseTicketQuantity?: (
236
+ serviceItem: MobileServiceItemProps["serviceItem"],
237
+ ) => void;
238
+ onDecreaseTicketQuantity?: (
239
+ serviceItem: MobileServiceItemProps["serviceItem"],
240
+ ) => void;
236
241
  cityOrigin?: { value: number; label: string };
237
242
  cityDestination?: { value: number; label: string };
238
- isNewUi?: boolean
243
+ isNewUi?: boolean;
239
244
 
240
- selectedTimeSlot?: string;
245
+ selectedTimeSlot?: string;
241
246
  onTimeSlotChange?: (slot: string) => void;
242
247
  isTimeDropdownOpen?: string | number | null;
243
248
  onTimeDropdownToggle?: (id?: string | number | null) => void;
@@ -252,6 +252,18 @@ export interface ServiceItemProps {
252
252
  showLoginModal?: any;
253
253
  isLoggedIn?: any;
254
254
  showLoginOption?: boolean;
255
+ isTrain?: boolean;
256
+ selectedSeatKey?: any;
257
+ onSeatSelect?: (
258
+ key: any,
259
+ price: number,
260
+ seatKey: string,
261
+ apiSeatType?: string,
262
+ ) => void;
263
+ onTrainButtonClick?: any;
264
+ showSeatSelectionError?: string | null;
265
+ onShowSeatSelectionError?: (serviceId: string) => void;
266
+ onClearSeatSelectionError?: () => void;
255
267
  selectedTimeSlot?: string;
256
268
  onTimeSlotChange?: (slot: string) => void;
257
269
  isTimeDropdownOpen?: string | number | null;
@@ -28,6 +28,7 @@ interface BottomAmenitiesProps {
28
28
  downArrowIcon?: React.ReactNode;
29
29
  onToggleExpand: () => void;
30
30
  isPeru?: boolean;
31
+ isTrain?: boolean;
31
32
  }
32
33
 
33
34
  function BottomAmenities({
@@ -42,6 +43,7 @@ function BottomAmenities({
42
43
  downArrowIcon,
43
44
  onToggleExpand,
44
45
  isPeru,
46
+ isTrain,
45
47
  }: BottomAmenitiesProps): React.ReactElement {
46
48
  const hasPetInfo =
47
49
  serviceItem.pet_seat_info &&
@@ -59,7 +61,9 @@ function BottomAmenities({
59
61
  className="grid items-center gap-[2%] flex-1 "
60
62
  style={{
61
63
  // gridTemplateColumns: " 28% 21% 23% 23%",
62
- gridTemplateColumns: "25.3% 17% 23% 23%",
64
+ gridTemplateColumns: isTrain
65
+ ? "20.6% 17% 23% 23%"
66
+ : "25.3% 17% 23% 23%",
63
67
  }}
64
68
  >
65
69
  {otherItems.map((item) => (
@@ -119,7 +119,7 @@ function DateTimeSection({
119
119
  metaData={metaData}
120
120
  colors={colors}
121
121
  >
122
- <span className="cursor-pointer bold-text capitalize">
122
+ <span className="cursor-pointer bold-text capitalize whitespace-nowrap">
123
123
  {DateService.getServiceItemDate(serviceItem.travel_date)}
124
124
  </span>
125
125
  </StageTooltip>
@@ -134,7 +134,7 @@ function DateTimeSection({
134
134
  metaData={metaData}
135
135
  colors={colors}
136
136
  >
137
- <span className="cursor-pointer bold-text capitalize">
137
+ <span className="cursor-pointer bold-text capitalize whitespace-nowrap">
138
138
  {DateService.getServiceItemDate(serviceItem.arrival_date)}
139
139
  </span>
140
140
  </StageTooltip>
@@ -169,7 +169,7 @@ function DateTimeSection({
169
169
  metaData={metaData}
170
170
  colors={colors}
171
171
  >
172
- <div className="font-[900] bold-text">
172
+ <div className="font-[900] bold-text whitespace-nowrap">
173
173
  {isLinatal ? (
174
174
  <>
175
175
  {cleanedDepTime} <span>{hasPM ? "PM" : hasAM ? "AM" : ""}</span>
@@ -193,7 +193,7 @@ function DateTimeSection({
193
193
  metaData={metaData}
194
194
  colors={colors}
195
195
  >
196
- <div className="font-[900] bold-text">
196
+ <div className="font-[900] bold-text whitespace-nowrap">
197
197
  {removeArrivalTime
198
198
  ? "\u00A0"
199
199
  : serviceItem.arr_time
@@ -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
  tooltipColor?: string;
25
36
  }
26
37
 
@@ -32,6 +43,8 @@ function getAllSeatTypes(seatTypes: SeatType[]) {
32
43
  let seatTypesWithPrices = seatTypes.filter(Boolean).map((val) => ({
33
44
  label: val?.label,
34
45
  price: val?.fare,
46
+ key: val?.key,
47
+ apiSeatType: val?.apiSeatType || val?.api_seat_type,
35
48
  }));
36
49
 
37
50
  seatTypesWithPrices.sort((a, b) => a.price - b.price);
@@ -39,7 +52,7 @@ function getAllSeatTypes(seatTypes: SeatType[]) {
39
52
  return seatTypesWithPrices;
40
53
  }
41
54
 
42
- function getSortedSeatTypes(seatTypes: SeatType[]) {
55
+ function getSortedSeatTypes(seatTypes: SeatType[], isTrain: any) {
43
56
  if (!seatTypes?.length) {
44
57
  return [{ label: "Salon cama", price: 0 }];
45
58
  }
@@ -53,7 +66,9 @@ function getSortedSeatTypes(seatTypes: SeatType[]) {
53
66
  seatTypesWithPrices[2] = seatTypesWithPrices[premiumIndex];
54
67
  }
55
68
 
56
- seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
69
+ if (!isTrain) {
70
+ seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
71
+ }
57
72
 
58
73
  const seenPrices = new Set<number>();
59
74
  seatTypesWithPrices = seatTypesWithPrices.filter((seat) => {
@@ -98,15 +113,19 @@ function SeatSection({
98
113
  priceColor,
99
114
  currencySign,
100
115
  removeDuplicateSeats,
116
+ selectedSeatKey,
117
+ onSeatSelect,
101
118
  isPeru,
102
119
  serviceItem,
103
120
  renderIcon,
104
121
  dpSeatColor,
105
122
  discountSeatPriceColor,
123
+ isTrain,
124
+ topLabelColor,
106
125
  tooltipColor,
107
126
  }: SeatSectionProps): React.ReactElement {
108
127
  const uniqueSeats = getUniqueSeats(seatTypes);
109
- const sortedSeatTypes = getSortedSeatTypes(seatTypes);
128
+ const sortedSeatTypes = getSortedSeatTypes(seatTypes, isTrain);
110
129
  const numberOfSeats = getNumberOfSeats(seatTypes);
111
130
  const isCentered = numberOfSeats < 2 || removeDuplicateSeats;
112
131
 
@@ -118,28 +137,75 @@ function SeatSection({
118
137
  const renderSeatNames = () => {
119
138
  const seats = removeDuplicateSeats ? uniqueSeats : sortedSeatTypes;
120
139
 
121
- return seats.map((val, key: number) =>
122
- SEAT_EXCEPTIONS.includes(val.label) ? null : (
123
- <span
124
- key={key}
125
- className={`flex items-center justify-between text-[13.33px] ${
126
- isSoldOut ? "text-[#c0c0c0]" : ""
127
- }`}
140
+ return seats.map((val, key: number) => {
141
+ return SEAT_EXCEPTIONS.includes(val.label) ? null : (
142
+ <div
143
+ className="flex items-center"
144
+ style={isTrain ? { cursor: "pointer" } : undefined}
145
+ onClick={
146
+ isTrain && !isSoldOut
147
+ ? () =>
148
+ val.label === selectedSeatKey
149
+ ? onSeatSelect?.(null, 0, "", "")
150
+ : onSeatSelect?.(
151
+ val.label,
152
+ val.price,
153
+ val.key,
154
+ (val as any).apiSeatType,
155
+ )
156
+ : undefined
157
+ }
128
158
  >
129
- {typeof val.label === "string" || typeof val.label === "number"
130
- ? removeDuplicateSeats && isPeru
131
- ? CommonService.truncateSeatLabel(val.label)
132
- : val.label
133
- : null}
134
- </span>
135
- ),
136
- );
159
+ {isTrain && (
160
+ <div
161
+ style={{
162
+ border: `1px solid ${val.label === selectedSeatKey ? topLabelColor : "#ccc"}`,
163
+ borderRadius: "50%",
164
+ width: "14px",
165
+ height: "14px",
166
+ minWidth: "14px",
167
+ marginRight: "10px",
168
+ display: "flex",
169
+ alignItems: "center",
170
+ justifyContent: "center",
171
+ }}
172
+ >
173
+ {val.label === selectedSeatKey && (
174
+ <div
175
+ style={{
176
+ backgroundColor: topLabelColor,
177
+ borderRadius: "50%",
178
+ width: "7px",
179
+ height: "7px",
180
+ }}
181
+ />
182
+ )}
183
+ </div>
184
+ )}
185
+ <span
186
+ key={key}
187
+ className={`flex items-center justify-between text-[13.33px] whitespace-nowrap ${
188
+ isSoldOut ? "text-[#c0c0c0]" : ""
189
+ }`}
190
+ >
191
+ {typeof val.label === "string" || typeof val.label === "number"
192
+ ? removeDuplicateSeats && isPeru
193
+ ? CommonService.truncateSeatLabel(val.label)
194
+ : isTrain
195
+ ? CommonService.capitalize(String(val.label))
196
+ : val.label
197
+ : null}
198
+ </span>
199
+ </div>
200
+ );
201
+ });
137
202
  };
138
203
 
139
204
  const renderSeatPrices = () => {
140
205
  if (isPeru) {
141
206
  const isMovilBus =
142
- serviceItem?.operator_service_name === "MovilBus" || "Movil Bus";
207
+ serviceItem?.operator_service_name === "MovilBus" ||
208
+ serviceItem?.operator_service_name === "Movil Bus";
143
209
 
144
210
  // Multiple unique seat types → show a price row for each (MovilBus only)
145
211
  if (isMovilBus && uniqueSeats.length > 1) {
@@ -238,6 +304,7 @@ function SeatSection({
238
304
  }
239
305
  return null;
240
306
  })();
307
+ console.log("🚀 ~ SeatSection ~ serviceItem:", serviceItem);
241
308
 
242
309
  // Hide the % OFF badge when max_discount is capping the percentage discount
243
310
  // (i.e. both percentage and max_discount exist, and the raw % amount exceeds the cap)
@@ -260,7 +327,8 @@ function SeatSection({
260
327
  const renderLabels = () => {
261
328
  if (isPeru) {
262
329
  const isMovilBus =
263
- serviceItem?.operator_service_name === "MovilBus" || "Movil Bus";
330
+ serviceItem?.operator_service_name === "MovilBus" ||
331
+ serviceItem?.operator_service_name === "Movil Bus";
264
332
 
265
333
  // Multiple unique seat types → show a label row for each (MovilBus only)
266
334
  if (isMovilBus && uniqueSeats.length > 1) {
@@ -308,7 +376,9 @@ function SeatSection({
308
376
 
309
377
  <span className="text-[13.33px] flex flex-col">
310
378
  {operatorServiceName ? (
311
- <span className="text-[13.33px]">{seatLabel}</span>
379
+ <span className="text-[13.33px] whitespace-nowrap">
380
+ {seatLabel}
381
+ </span>
312
382
  ) : (
313
383
  <span className="text-[13.33px]">Desde</span>
314
384
  )}
@@ -531,7 +601,7 @@ function SeatSection({
531
601
  style={{ textAlign: "center" }}
532
602
  >
533
603
  <span
534
- className="text-[13.33px] font-normal leading-[20px] text-[#9f9f9f] relative"
604
+ className="text-[13.33px] font-normal leading-[20px] text-[#9f9f9f] relative whitespace-nowrap"
535
605
  style={{
536
606
  position: "relative",
537
607
  }}
@@ -593,7 +663,9 @@ function SeatSection({
593
663
  color: isSoldOut ? "#c0c0c0" : priceColor,
594
664
  top: 0,
595
665
  bottom: 0,
596
- left: "clamp(60%, 65% + (100vw - 1300px) * 0.1, 65%)",
666
+ left: isTrain
667
+ ? "73%"
668
+ : "clamp(60%, 65% + (100vw - 1300px) * 0.1, 65%)",
597
669
  right: 0,
598
670
  justifyContent: isCentered ? "center" : "",
599
671
  gap: "10px",
@@ -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,47 @@ 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
- />
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 whitespace-nowrap">
102
+ {formattedDate}
103
+ </span>
104
+ <div className={`absolute left-[50%] ${dotPositionClass}`}>•</div>
105
+ <div className="font-[900] relative black-text whitespace-nowrap">
106
+ {timeContent}
90
107
  </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>
108
+ </div>
102
109
  </div>
103
110
  </div>
104
- </div>;
111
+ );
105
112
  };
106
113
 
107
114
  function DateTimeSectionMobile({
@@ -127,6 +134,7 @@ function DateTimeSectionMobile({
127
134
  tooltipBgColor,
128
135
  showLastSeats,
129
136
  discountSeatPriceColor,
137
+ isTrain,
130
138
  }: DateTimeSectionMobileProps): React.ReactElement {
131
139
  const { cleaned: cleanedDepTime, hasAM, hasPM } = getCleanedDepTime(depTime);
132
140
 
@@ -153,8 +161,12 @@ function DateTimeSectionMobile({
153
161
  >
154
162
  {/* DATE AND TIME */}
155
163
  <div
156
- className="min-h-[2.5rem] flex flex-col justify-between gap-[4px] w-[50%] "
157
- style={{ justifyContent: isCiva && "center" }}
164
+ className={`flex flex-col gap-[4px] w-[50%] ${isTrain ? "justify-center" : "justify-between"}`}
165
+ style={{
166
+ justifyContent: isCiva && "center",
167
+ minHeight: isTrain ? undefined : "2.5rem",
168
+ alignSelf: isTrain ? "stretch" : undefined,
169
+ }}
158
170
  >
159
171
  <TimeRow
160
172
  label={orignLabel}
@@ -198,6 +210,7 @@ function DateTimeSectionMobile({
198
210
  tooltipBgColor={tooltipBgColor}
199
211
  showLastSeats={showLastSeats}
200
212
  discountSeatPriceColor={discountSeatPriceColor}
213
+ isTrain={isTrain}
201
214
  />
202
215
  </div>
203
216
  );