kupos-ui-components-lib 9.11.4 → 9.11.6
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/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemDesktop.js +6 -24
- package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemMobile.js +1 -1
- package/dist/components/ServiceItem/mobileTypes.d.ts +0 -1
- package/dist/components/ServiceItem/types.d.ts +0 -7
- package/dist/styles.css +11 -6
- package/dist/ui/BottomAmenities/BottomAmenities.d.ts +1 -2
- package/dist/ui/BottomAmenities/BottomAmenities.js +2 -4
- package/dist/ui/DateTimeSection/DateTimeSection.js +4 -4
- package/dist/ui/FeatureServiceUI/FeatureServiceUi.js +5 -5
- package/dist/ui/SeatSection/SeatSection.d.ts +1 -7
- package/dist/ui/SeatSection/SeatSection.js +15 -47
- package/dist/ui/mobileweb/DateTimeSectionMobile.d.ts +1 -2
- package/dist/ui/mobileweb/DateTimeSectionMobile.js +7 -13
- package/dist/ui/mobileweb/SeatSectionMobile.d.ts +1 -2
- package/dist/ui/mobileweb/SeatSectionMobile.js +16 -23
- package/dist/utils/CommonService.d.ts +1 -1
- package/dist/utils/CommonService.js +2 -6
- package/package.json +1 -1
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +3 -49
- package/src/components/ServiceItem/ServiceItemMobile.tsx +1 -2
- package/src/components/ServiceItem/mobileTypes.ts +26 -31
- package/src/components/ServiceItem/types.ts +0 -12
- package/src/ui/BottomAmenities/BottomAmenities.tsx +1 -5
- package/src/ui/DateTimeSection/DateTimeSection.tsx +4 -4
- package/src/ui/FeatureServiceUI/FeatureServiceUi.tsx +8 -5
- package/src/ui/SeatSection/SeatSection.tsx +26 -94
- package/src/ui/mobileweb/DateTimeSectionMobile.tsx +34 -47
- package/src/ui/mobileweb/SeatSectionMobile.tsx +14 -28
- package/src/utils/CommonService.ts +2 -8
|
@@ -7,8 +7,6 @@ interface SeatType {
|
|
|
7
7
|
label: string;
|
|
8
8
|
fare: number;
|
|
9
9
|
key: any;
|
|
10
|
-
apiSeatType?: string;
|
|
11
|
-
api_seat_type?: string;
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
interface SeatSectionProps {
|
|
@@ -23,15 +21,6 @@ interface SeatSectionProps {
|
|
|
23
21
|
serviceItem?: any;
|
|
24
22
|
renderIcon?: (iconKey: string, size?: string) => React.ReactNode;
|
|
25
23
|
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;
|
|
35
24
|
tooltipColor?: string;
|
|
36
25
|
}
|
|
37
26
|
|
|
@@ -43,8 +32,6 @@ function getAllSeatTypes(seatTypes: SeatType[]) {
|
|
|
43
32
|
let seatTypesWithPrices = seatTypes.filter(Boolean).map((val) => ({
|
|
44
33
|
label: val?.label,
|
|
45
34
|
price: val?.fare,
|
|
46
|
-
key: val?.key,
|
|
47
|
-
apiSeatType: val?.apiSeatType || val?.api_seat_type,
|
|
48
35
|
}));
|
|
49
36
|
|
|
50
37
|
seatTypesWithPrices.sort((a, b) => a.price - b.price);
|
|
@@ -52,7 +39,7 @@ function getAllSeatTypes(seatTypes: SeatType[]) {
|
|
|
52
39
|
return seatTypesWithPrices;
|
|
53
40
|
}
|
|
54
41
|
|
|
55
|
-
function getSortedSeatTypes(seatTypes: SeatType[]
|
|
42
|
+
function getSortedSeatTypes(seatTypes: SeatType[]) {
|
|
56
43
|
if (!seatTypes?.length) {
|
|
57
44
|
return [{ label: "Salon cama", price: 0 }];
|
|
58
45
|
}
|
|
@@ -66,9 +53,7 @@ function getSortedSeatTypes(seatTypes: SeatType[], isTrain: any) {
|
|
|
66
53
|
seatTypesWithPrices[2] = seatTypesWithPrices[premiumIndex];
|
|
67
54
|
}
|
|
68
55
|
|
|
69
|
-
|
|
70
|
-
seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
|
|
71
|
-
}
|
|
56
|
+
seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
|
|
72
57
|
|
|
73
58
|
const seenPrices = new Set<number>();
|
|
74
59
|
seatTypesWithPrices = seatTypesWithPrices.filter((seat) => {
|
|
@@ -113,19 +98,15 @@ function SeatSection({
|
|
|
113
98
|
priceColor,
|
|
114
99
|
currencySign,
|
|
115
100
|
removeDuplicateSeats,
|
|
116
|
-
selectedSeatKey,
|
|
117
|
-
onSeatSelect,
|
|
118
101
|
isPeru,
|
|
119
102
|
serviceItem,
|
|
120
103
|
renderIcon,
|
|
121
104
|
dpSeatColor,
|
|
122
105
|
discountSeatPriceColor,
|
|
123
|
-
isTrain,
|
|
124
|
-
topLabelColor,
|
|
125
106
|
tooltipColor,
|
|
126
107
|
}: SeatSectionProps): React.ReactElement {
|
|
127
108
|
const uniqueSeats = getUniqueSeats(seatTypes);
|
|
128
|
-
const sortedSeatTypes = getSortedSeatTypes(seatTypes
|
|
109
|
+
const sortedSeatTypes = getSortedSeatTypes(seatTypes);
|
|
129
110
|
const numberOfSeats = getNumberOfSeats(seatTypes);
|
|
130
111
|
const isCentered = numberOfSeats < 2 || removeDuplicateSeats;
|
|
131
112
|
|
|
@@ -137,73 +118,28 @@ function SeatSection({
|
|
|
137
118
|
const renderSeatNames = () => {
|
|
138
119
|
const seats = removeDuplicateSeats ? uniqueSeats : sortedSeatTypes;
|
|
139
120
|
|
|
140
|
-
return seats.map((val, key: number) =>
|
|
141
|
-
|
|
142
|
-
<
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
}
|
|
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
|
+
}`}
|
|
158
128
|
>
|
|
159
|
-
{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
});
|
|
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
|
+
);
|
|
202
137
|
};
|
|
203
138
|
|
|
204
139
|
const renderSeatPrices = () => {
|
|
205
140
|
if (isPeru) {
|
|
206
|
-
const isMovilBus =
|
|
141
|
+
const isMovilBus =
|
|
142
|
+
serviceItem?.operator_service_name === "MovilBus" || "Movil Bus";
|
|
207
143
|
|
|
208
144
|
// Multiple unique seat types → show a price row for each (MovilBus only)
|
|
209
145
|
if (isMovilBus && uniqueSeats.length > 1) {
|
|
@@ -302,7 +238,6 @@ function SeatSection({
|
|
|
302
238
|
}
|
|
303
239
|
return null;
|
|
304
240
|
})();
|
|
305
|
-
console.log("🚀 ~ SeatSection ~ serviceItem:", serviceItem);
|
|
306
241
|
|
|
307
242
|
// Hide the % OFF badge when max_discount is capping the percentage discount
|
|
308
243
|
// (i.e. both percentage and max_discount exist, and the raw % amount exceeds the cap)
|
|
@@ -324,7 +259,8 @@ function SeatSection({
|
|
|
324
259
|
|
|
325
260
|
const renderLabels = () => {
|
|
326
261
|
if (isPeru) {
|
|
327
|
-
const isMovilBus =
|
|
262
|
+
const isMovilBus =
|
|
263
|
+
serviceItem?.operator_service_name === "MovilBus" || "Movil Bus";
|
|
328
264
|
|
|
329
265
|
// Multiple unique seat types → show a label row for each (MovilBus only)
|
|
330
266
|
if (isMovilBus && uniqueSeats.length > 1) {
|
|
@@ -355,7 +291,7 @@ function SeatSection({
|
|
|
355
291
|
: null;
|
|
356
292
|
|
|
357
293
|
const operatorServiceName =
|
|
358
|
-
serviceItem?.operator_service_name === "MovilBus";
|
|
294
|
+
serviceItem?.operator_service_name === "MovilBus" || "Movil Bus";
|
|
359
295
|
|
|
360
296
|
return (
|
|
361
297
|
<>
|
|
@@ -372,9 +308,7 @@ function SeatSection({
|
|
|
372
308
|
|
|
373
309
|
<span className="text-[13.33px] flex flex-col">
|
|
374
310
|
{operatorServiceName ? (
|
|
375
|
-
<span className="text-[13.33px]
|
|
376
|
-
{seatLabel}
|
|
377
|
-
</span>
|
|
311
|
+
<span className="text-[13.33px]">{seatLabel}</span>
|
|
378
312
|
) : (
|
|
379
313
|
<span className="text-[13.33px]">Desde</span>
|
|
380
314
|
)}
|
|
@@ -597,7 +531,7 @@ function SeatSection({
|
|
|
597
531
|
style={{ textAlign: "center" }}
|
|
598
532
|
>
|
|
599
533
|
<span
|
|
600
|
-
className="text-[13.33px] font-normal leading-[20px] text-[#9f9f9f] relative
|
|
534
|
+
className="text-[13.33px] font-normal leading-[20px] text-[#9f9f9f] relative"
|
|
601
535
|
style={{
|
|
602
536
|
position: "relative",
|
|
603
537
|
}}
|
|
@@ -659,9 +593,7 @@ function SeatSection({
|
|
|
659
593
|
color: isSoldOut ? "#c0c0c0" : priceColor,
|
|
660
594
|
top: 0,
|
|
661
595
|
bottom: 0,
|
|
662
|
-
left:
|
|
663
|
-
? "73%"
|
|
664
|
-
: "clamp(60%, 65% + (100vw - 1300px) * 0.1, 65%)",
|
|
596
|
+
left: "clamp(60%, 65% + (100vw - 1300px) * 0.1, 65%)",
|
|
665
597
|
right: 0,
|
|
666
598
|
justifyContent: isCentered ? "center" : "",
|
|
667
599
|
gap: "10px",
|
|
@@ -25,7 +25,6 @@ interface DateTimeSectionMobileProps {
|
|
|
25
25
|
tooltipBgColor?: string;
|
|
26
26
|
showLastSeats?: boolean;
|
|
27
27
|
discountSeatPriceColor?: string;
|
|
28
|
-
isTrain?: boolean;
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
const pad = (n: number) => (n < 10 ? "0" + n : String(n));
|
|
@@ -68,47 +67,41 @@ const TimeRow: React.FC<TimeRowProps> = ({
|
|
|
68
67
|
isSoldOut,
|
|
69
68
|
}) => {
|
|
70
69
|
const formattedDate = DateService.getServiceItemDate(date);
|
|
71
|
-
const dotPositionClass = formattedDate.includes("dom")
|
|
72
|
-
|
|
73
|
-
:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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}
|
|
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
|
+
/>
|
|
107
90
|
</div>
|
|
108
|
-
|
|
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>
|
|
109
102
|
</div>
|
|
110
103
|
</div>
|
|
111
|
-
|
|
104
|
+
</div>;
|
|
112
105
|
};
|
|
113
106
|
|
|
114
107
|
function DateTimeSectionMobile({
|
|
@@ -134,7 +127,6 @@ function DateTimeSectionMobile({
|
|
|
134
127
|
tooltipBgColor,
|
|
135
128
|
showLastSeats,
|
|
136
129
|
discountSeatPriceColor,
|
|
137
|
-
isTrain,
|
|
138
130
|
}: DateTimeSectionMobileProps): React.ReactElement {
|
|
139
131
|
const { cleaned: cleanedDepTime, hasAM, hasPM } = getCleanedDepTime(depTime);
|
|
140
132
|
|
|
@@ -161,12 +153,8 @@ function DateTimeSectionMobile({
|
|
|
161
153
|
>
|
|
162
154
|
{/* DATE AND TIME */}
|
|
163
155
|
<div
|
|
164
|
-
className=
|
|
165
|
-
style={{
|
|
166
|
-
justifyContent: isCiva && "center",
|
|
167
|
-
minHeight: isTrain ? undefined : "2.5rem",
|
|
168
|
-
alignSelf: isTrain ? "stretch" : undefined,
|
|
169
|
-
}}
|
|
156
|
+
className="min-h-[2.5rem] flex flex-col justify-between gap-[4px] w-[50%] "
|
|
157
|
+
style={{ justifyContent: isCiva && "center" }}
|
|
170
158
|
>
|
|
171
159
|
<TimeRow
|
|
172
160
|
label={orignLabel}
|
|
@@ -210,7 +198,6 @@ function DateTimeSectionMobile({
|
|
|
210
198
|
tooltipBgColor={tooltipBgColor}
|
|
211
199
|
showLastSeats={showLastSeats}
|
|
212
200
|
discountSeatPriceColor={discountSeatPriceColor}
|
|
213
|
-
isTrain={isTrain}
|
|
214
201
|
/>
|
|
215
202
|
</div>
|
|
216
203
|
);
|
|
@@ -31,7 +31,6 @@ interface SeatSectionMobileProps {
|
|
|
31
31
|
tooltipBgColor?: string;
|
|
32
32
|
showLastSeats?: boolean;
|
|
33
33
|
discountSeatPriceColor?: string;
|
|
34
|
-
isTrain?: boolean;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
interface SeatRowProps {
|
|
@@ -43,7 +42,6 @@ interface SeatRowProps {
|
|
|
43
42
|
seatPriceColor: string;
|
|
44
43
|
hasMultipleTypes: boolean;
|
|
45
44
|
textSize: string;
|
|
46
|
-
isTrain?: boolean;
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
const SeatRow: React.FC<SeatRowProps> = ({
|
|
@@ -55,7 +53,6 @@ const SeatRow: React.FC<SeatRowProps> = ({
|
|
|
55
53
|
seatPriceColor,
|
|
56
54
|
hasMultipleTypes,
|
|
57
55
|
textSize,
|
|
58
|
-
isTrain,
|
|
59
56
|
}) => {
|
|
60
57
|
if (EXCEPTIONS.includes(type.label)) return null;
|
|
61
58
|
|
|
@@ -72,12 +69,7 @@ const SeatRow: React.FC<SeatRowProps> = ({
|
|
|
72
69
|
className={`min-[420]:text-[13px] ${textSize} `}
|
|
73
70
|
style={{ color: labelColor }}
|
|
74
71
|
>
|
|
75
|
-
{
|
|
76
|
-
? commonService.truncateSeatLabel(
|
|
77
|
-
commonService.capitalize(displayLabel),
|
|
78
|
-
8,
|
|
79
|
-
)
|
|
80
|
-
: displayLabel}
|
|
72
|
+
{displayLabel}
|
|
81
73
|
</span>
|
|
82
74
|
<span
|
|
83
75
|
className={`min-[420]:text-[13px] ${textSize} bold-text`}
|
|
@@ -126,7 +118,6 @@ function SeatSectionMobile({
|
|
|
126
118
|
tooltipBgColor,
|
|
127
119
|
showLastSeats,
|
|
128
120
|
discountSeatPriceColor,
|
|
129
|
-
isTrain,
|
|
130
121
|
}: SeatSectionMobileProps): React.ReactElement {
|
|
131
122
|
const hasMultipleTypes = (seatTypesData?.length ?? 0) > 2;
|
|
132
123
|
|
|
@@ -158,7 +149,8 @@ function SeatSectionMobile({
|
|
|
158
149
|
if (lowestFare === null) return null;
|
|
159
150
|
|
|
160
151
|
const priceColor = isSoldOut ? "#bbb" : seatPriceColor;
|
|
161
|
-
const isMovilBus =
|
|
152
|
+
const isMovilBus =
|
|
153
|
+
serviceItem?.operator_service_name === "MovilBus" || "Movil Bus";
|
|
162
154
|
|
|
163
155
|
// Fetch ALL unique seats (no slice limit) for the multi-row MovilBus case
|
|
164
156
|
const uniqueSeats = getUniqueSeats(seatTypesData ?? [], Infinity as number);
|
|
@@ -178,7 +170,7 @@ function SeatSectionMobile({
|
|
|
178
170
|
className="w-[100%] flex flex-row justify-between items-center"
|
|
179
171
|
>
|
|
180
172
|
<span
|
|
181
|
-
className="min-[420]:text-[13px] text-[12px] bold-text
|
|
173
|
+
className="min-[420]:text-[13px] text-[12px] bold-text"
|
|
182
174
|
style={{ color: isSoldOut ? "#bbb" : "#464647" }}
|
|
183
175
|
>
|
|
184
176
|
{commonService.truncateSeatLabel(seat.label)}
|
|
@@ -331,17 +323,15 @@ function SeatSectionMobile({
|
|
|
331
323
|
seatPriceColor={seatPriceColor}
|
|
332
324
|
hasMultipleTypes={hasMultipleTypes}
|
|
333
325
|
textSize="text-[11px]"
|
|
334
|
-
isTrain={isTrain}
|
|
335
326
|
/>
|
|
336
327
|
));
|
|
337
328
|
}
|
|
338
329
|
|
|
339
|
-
|
|
330
|
+
return seatTypesData
|
|
340
331
|
?.filter((item) => getFilteredSeats(item.label))
|
|
341
|
-
?.sort((a, b) => a.fare - b.fare)
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
(type, i) => (
|
|
332
|
+
?.sort((a, b) => a.fare - b.fare)
|
|
333
|
+
?.slice(0, 2)
|
|
334
|
+
?.map((type, i) => (
|
|
345
335
|
<SeatRow
|
|
346
336
|
key={i}
|
|
347
337
|
type={type}
|
|
@@ -352,20 +342,16 @@ function SeatSectionMobile({
|
|
|
352
342
|
seatPriceColor={seatPriceColor}
|
|
353
343
|
hasMultipleTypes={hasMultipleTypes}
|
|
354
344
|
textSize="text-[12px]"
|
|
355
|
-
isTrain={isTrain}
|
|
356
345
|
/>
|
|
357
|
-
)
|
|
358
|
-
);
|
|
346
|
+
));
|
|
359
347
|
};
|
|
360
348
|
|
|
361
349
|
const seats = removeDuplicateSeats
|
|
362
350
|
? getUniqueSeats(seatTypesData, 3)
|
|
363
|
-
:
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
return isTrain ? filtered : filtered?.slice(0, 2);
|
|
368
|
-
})();
|
|
351
|
+
: seatTypesData
|
|
352
|
+
?.filter((item) => getFilteredSeats(item.label))
|
|
353
|
+
?.sort((a, b) => a.fare - b.fare)
|
|
354
|
+
?.slice(0, 2);
|
|
369
355
|
|
|
370
356
|
const discountedSeats = seats?.map((seat) => ({
|
|
371
357
|
...seat,
|
|
@@ -617,7 +603,7 @@ function SeatSectionMobile({
|
|
|
617
603
|
</div>
|
|
618
604
|
) : (
|
|
619
605
|
<div
|
|
620
|
-
className=
|
|
606
|
+
className="flex flex-col justify-between h-[2.5rem] "
|
|
621
607
|
style={{
|
|
622
608
|
gap: isSoldOut ? "0px" : "5px",
|
|
623
609
|
justifyContent: hasMultipleTypes ? "space-between" : "center",
|
|
@@ -39,15 +39,9 @@ const commonService = {
|
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
|
|
42
|
-
truncateSeatLabel: (label: string | number
|
|
42
|
+
truncateSeatLabel: (label: string | number): string => {
|
|
43
43
|
if (typeof label !== "string") return String(label);
|
|
44
44
|
if (label.includes("(")) return label;
|
|
45
|
-
|
|
46
|
-
// If maxLength provided, hard-truncate regardless of word count
|
|
47
|
-
if (maxLength != null && label.length > maxLength) {
|
|
48
|
-
return label.slice(0, maxLength) + "...";
|
|
49
|
-
}
|
|
50
|
-
|
|
51
45
|
const words = label.trim().split(/\s+/);
|
|
52
46
|
|
|
53
47
|
const truncateWord = (word: string) =>
|
|
@@ -419,7 +413,7 @@ const commonService = {
|
|
|
419
413
|
let remaining = Math.max(0, Math.floor(countdownSeconds));
|
|
420
414
|
|
|
421
415
|
const formatTime = (totalSeconds: number) => {
|
|
422
|
-
if (totalSeconds <= 0) return "
|
|
416
|
+
if (totalSeconds <= 0) return "00:00";
|
|
423
417
|
const h = Math.floor(totalSeconds / 3600);
|
|
424
418
|
const m = Math.floor((totalSeconds % 3600) / 60);
|
|
425
419
|
const s = totalSeconds % 60;
|