kupos-ui-components-lib 9.11.7 → 9.11.9
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 +25 -7
- package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemMobile.js +1 -1
- package/dist/components/ServiceItem/mobileTypes.d.ts +1 -0
- package/dist/components/ServiceItem/types.d.ts +7 -0
- package/dist/styles.css +6 -0
- package/dist/ui/BottomAmenities/BottomAmenities.d.ts +2 -1
- package/dist/ui/BottomAmenities/BottomAmenities.js +4 -2
- package/dist/ui/DateTimeSection/DateTimeSection.js +4 -4
- package/dist/ui/OfferBanner.d.ts +1 -0
- package/dist/ui/OfferBanner.js +6 -2
- package/dist/ui/SeatSection/SeatSection.d.ts +7 -1
- package/dist/ui/SeatSection/SeatSection.js +43 -12
- package/dist/ui/mobileweb/DateTimeSectionMobile.d.ts +2 -1
- package/dist/ui/mobileweb/DateTimeSectionMobile.js +13 -7
- package/dist/ui/mobileweb/SeatSectionMobile.d.ts +2 -1
- package/dist/ui/mobileweb/SeatSectionMobile.js +22 -15
- package/dist/utils/CommonService.d.ts +1 -1
- package/dist/utils/CommonService.js +5 -1
- package/package.json +1 -1
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +51 -5
- package/src/components/ServiceItem/ServiceItemMobile.tsx +2 -1
- package/src/components/ServiceItem/mobileTypes.ts +31 -26
- package/src/components/ServiceItem/types.ts +12 -0
- package/src/ui/BottomAmenities/BottomAmenities.tsx +5 -1
- package/src/ui/DateTimeSection/DateTimeSection.tsx +4 -4
- package/src/ui/OfferBanner.tsx +7 -1
- package/src/ui/SeatSection/SeatSection.tsx +90 -21
- package/src/ui/mobileweb/DateTimeSectionMobile.tsx +47 -34
- package/src/ui/mobileweb/SeatSectionMobile.tsx +27 -12
- package/src/utils/CommonService.ts +7 -1
|
@@ -34,11 +34,15 @@ const commonService = {
|
|
|
34
34
|
return "";
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
|
-
truncateSeatLabel: (label) => {
|
|
37
|
+
truncateSeatLabel: (label, maxLength) => {
|
|
38
38
|
if (typeof label !== "string")
|
|
39
39
|
return String(label);
|
|
40
40
|
if (label.includes("("))
|
|
41
41
|
return label;
|
|
42
|
+
// If maxLength provided, hard-truncate regardless of word count
|
|
43
|
+
if (maxLength != null && label.length > maxLength) {
|
|
44
|
+
return label.slice(0, maxLength) + "...";
|
|
45
|
+
}
|
|
42
46
|
const words = label.trim().split(/\s+/);
|
|
43
47
|
const truncateWord = (word) => word.length > 5 ? word.slice(0, 3) + "..." : word;
|
|
44
48
|
if (words.length === 1)
|
package/package.json
CHANGED
|
@@ -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
|
|
|
@@ -530,6 +557,7 @@ function ServiceItemPB({
|
|
|
530
557
|
showLoginOption={showLoginOption}
|
|
531
558
|
isNewUiEnabled={isNewUiEnabled}
|
|
532
559
|
colors={colors}
|
|
560
|
+
isLinatal={isLinatal}
|
|
533
561
|
/>
|
|
534
562
|
)}
|
|
535
563
|
<div
|
|
@@ -558,7 +586,9 @@ function ServiceItemPB({
|
|
|
558
586
|
: "",
|
|
559
587
|
}}
|
|
560
588
|
>
|
|
561
|
-
<div
|
|
589
|
+
<div
|
|
590
|
+
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`}
|
|
591
|
+
>
|
|
562
592
|
{/* OPERATOR LOGO */}
|
|
563
593
|
<div className="flex flex-col gap-[5px]">
|
|
564
594
|
<div>
|
|
@@ -620,6 +650,10 @@ function ServiceItemPB({
|
|
|
620
650
|
isPeru={isPeru}
|
|
621
651
|
renderIcon={renderIcon}
|
|
622
652
|
discountSeatPriceColor={colors.discountSeatPriceColor}
|
|
653
|
+
isTrain={isTrain}
|
|
654
|
+
selectedSeatKey={selectedSeatKey}
|
|
655
|
+
onSeatSelect={handleSeatSelect}
|
|
656
|
+
topLabelColor={colors.topLabelColor}
|
|
623
657
|
tooltipColor={colors.tooltipColor}
|
|
624
658
|
/>
|
|
625
659
|
</div>
|
|
@@ -636,6 +670,18 @@ function ServiceItemPB({
|
|
|
636
670
|
soldOutIcon={renderIcon("soldOutIcon", "14px")}
|
|
637
671
|
onClick={checkMidnight}
|
|
638
672
|
/>
|
|
673
|
+
{showSeatSelectionError === serviceItem.id && isTrain && (
|
|
674
|
+
<div className="flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]">
|
|
675
|
+
<div
|
|
676
|
+
className="text-[9px] text-center whitespace-nowrap"
|
|
677
|
+
style={{
|
|
678
|
+
color: colors.seatPriceColor,
|
|
679
|
+
}}
|
|
680
|
+
>
|
|
681
|
+
Selecciona el tipo de servicio
|
|
682
|
+
</div>
|
|
683
|
+
</div>
|
|
684
|
+
)}
|
|
639
685
|
{showLastSeats ? (
|
|
640
686
|
<div className="flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]">
|
|
641
687
|
{serviceItem?.available_seats < 10 &&
|
|
@@ -668,6 +714,7 @@ function ServiceItemPB({
|
|
|
668
714
|
setIsExpand(isItemExpanded ? null : serviceItem.id)
|
|
669
715
|
}
|
|
670
716
|
isPeru={isPeru}
|
|
717
|
+
isTrain={isTrain}
|
|
671
718
|
/>
|
|
672
719
|
</div>
|
|
673
720
|
</div>
|
|
@@ -681,7 +728,7 @@ function ServiceItemPB({
|
|
|
681
728
|
transition:
|
|
682
729
|
"grid-template-rows 0.3s ease-in-out, opacity 0.25s ease-in-out",
|
|
683
730
|
position: "relative",
|
|
684
|
-
zIndex:
|
|
731
|
+
zIndex: hasDiscount || hasDpEnabled ? 0 : -1,
|
|
685
732
|
marginTop: isItemExpanded ? "" : "-10px",
|
|
686
733
|
}}
|
|
687
734
|
>
|
|
@@ -689,9 +736,8 @@ function ServiceItemPB({
|
|
|
689
736
|
style={{
|
|
690
737
|
overflow: "hidden",
|
|
691
738
|
minHeight: 0,
|
|
692
|
-
marginTop:
|
|
693
|
-
|
|
694
|
-
...(hasOfferText || hasDpEnabled
|
|
739
|
+
marginTop: hasDpEnabled || hasDiscount ? "" : "-10px",
|
|
740
|
+
...(hasDpEnabled || hasDiscount
|
|
695
741
|
? {
|
|
696
742
|
borderLeft: isSoldOut
|
|
697
743
|
? ""
|
|
@@ -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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
|
|
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
|
-
|
|
231
|
+
isTrain?: boolean;
|
|
232
|
+
isFeatureDropDownExpand?: any;
|
|
232
233
|
setIsFeatureDropDownExpand?: (value: any) => void;
|
|
233
234
|
ticketQuantity?: number;
|
|
234
|
-
onIncreaseTicketQuantity?: (
|
|
235
|
-
|
|
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
|
-
|
|
243
|
+
isNewUi?: boolean;
|
|
239
244
|
|
|
240
|
-
|
|
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:
|
|
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
|
package/src/ui/OfferBanner.tsx
CHANGED
|
@@ -29,6 +29,7 @@ interface OfferBannerProps {
|
|
|
29
29
|
showLoginOption?: boolean;
|
|
30
30
|
isNewUiEnabled?: boolean;
|
|
31
31
|
colors: OfferBannerColors;
|
|
32
|
+
isLinatal?: boolean;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
@@ -206,6 +207,7 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
|
|
|
206
207
|
showLoginOption,
|
|
207
208
|
isNewUiEnabled,
|
|
208
209
|
colors,
|
|
210
|
+
isLinatal,
|
|
209
211
|
}) => {
|
|
210
212
|
const isLegacyOffer =
|
|
211
213
|
!!serviceItem?.offer_text && !isNewUiEnabled && !serviceItem?.is_dp_enabled;
|
|
@@ -250,7 +252,11 @@ const OfferBanner: React.FC<OfferBannerProps> = ({
|
|
|
250
252
|
return (
|
|
251
253
|
<div
|
|
252
254
|
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]"
|
|
253
|
-
style={{
|
|
255
|
+
style={{
|
|
256
|
+
background,
|
|
257
|
+
opacity: isSoldOut ? 0.5 : 1,
|
|
258
|
+
zIndex: isLinatal ? "-1" : "",
|
|
259
|
+
}}
|
|
254
260
|
>
|
|
255
261
|
<div className="flex justify-between items-center w-full">
|
|
256
262
|
<div className="flex items-center">{renderLeftContent()}</div>
|
|
@@ -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
|
-
|
|
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,22 +137,68 @@ 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
|
-
<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
{
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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 = () => {
|
|
@@ -310,7 +375,9 @@ function SeatSection({
|
|
|
310
375
|
|
|
311
376
|
<span className="text-[13.33px] flex flex-col">
|
|
312
377
|
{operatorServiceName ? (
|
|
313
|
-
<span className="text-[13.33px]">
|
|
378
|
+
<span className="text-[13.33px] whitespace-nowrap">
|
|
379
|
+
{seatLabel}
|
|
380
|
+
</span>
|
|
314
381
|
) : (
|
|
315
382
|
<span className="text-[13.33px]">Desde</span>
|
|
316
383
|
)}
|
|
@@ -533,7 +600,7 @@ function SeatSection({
|
|
|
533
600
|
style={{ textAlign: "center" }}
|
|
534
601
|
>
|
|
535
602
|
<span
|
|
536
|
-
className="text-[13.33px] font-normal leading-[20px] text-[#9f9f9f] relative"
|
|
603
|
+
className="text-[13.33px] font-normal leading-[20px] text-[#9f9f9f] relative whitespace-nowrap"
|
|
537
604
|
style={{
|
|
538
605
|
position: "relative",
|
|
539
606
|
}}
|
|
@@ -595,7 +662,9 @@ function SeatSection({
|
|
|
595
662
|
color: isSoldOut ? "#c0c0c0" : priceColor,
|
|
596
663
|
top: 0,
|
|
597
664
|
bottom: 0,
|
|
598
|
-
left:
|
|
665
|
+
left: isTrain
|
|
666
|
+
? "73%"
|
|
667
|
+
: "clamp(60%, 65% + (100vw - 1300px) * 0.1, 65%)",
|
|
599
668
|
right: 0,
|
|
600
669
|
justifyContent: isCentered ? "center" : "",
|
|
601
670
|
gap: "10px",
|