kupos-ui-components-lib 9.11.7 → 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.
- package/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemDesktop.js +22 -4
- 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/SeatSection/SeatSection.d.ts +7 -1
- package/dist/ui/SeatSection/SeatSection.js +44 -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 +47 -1
- 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/SeatSection/SeatSection.tsx +91 -21
- package/src/ui/mobileweb/DateTimeSectionMobile.tsx +47 -34
- package/src/ui/mobileweb/SeatSectionMobile.tsx +27 -12
- 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
|
|
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
|
-
|
|
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
|
|
@@ -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 = () => {
|
|
@@ -239,6 +304,7 @@ function SeatSection({
|
|
|
239
304
|
}
|
|
240
305
|
return null;
|
|
241
306
|
})();
|
|
307
|
+
console.log("🚀 ~ SeatSection ~ serviceItem:", serviceItem);
|
|
242
308
|
|
|
243
309
|
// Hide the % OFF badge when max_discount is capping the percentage discount
|
|
244
310
|
// (i.e. both percentage and max_discount exist, and the raw % amount exceeds the cap)
|
|
@@ -310,7 +376,9 @@ function SeatSection({
|
|
|
310
376
|
|
|
311
377
|
<span className="text-[13.33px] flex flex-col">
|
|
312
378
|
{operatorServiceName ? (
|
|
313
|
-
<span className="text-[13.33px]">
|
|
379
|
+
<span className="text-[13.33px] whitespace-nowrap">
|
|
380
|
+
{seatLabel}
|
|
381
|
+
</span>
|
|
314
382
|
) : (
|
|
315
383
|
<span className="text-[13.33px]">Desde</span>
|
|
316
384
|
)}
|
|
@@ -533,7 +601,7 @@ function SeatSection({
|
|
|
533
601
|
style={{ textAlign: "center" }}
|
|
534
602
|
>
|
|
535
603
|
<span
|
|
536
|
-
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"
|
|
537
605
|
style={{
|
|
538
606
|
position: "relative",
|
|
539
607
|
}}
|
|
@@ -595,7 +663,9 @@ function SeatSection({
|
|
|
595
663
|
color: isSoldOut ? "#c0c0c0" : priceColor,
|
|
596
664
|
top: 0,
|
|
597
665
|
bottom: 0,
|
|
598
|
-
left:
|
|
666
|
+
left: isTrain
|
|
667
|
+
? "73%"
|
|
668
|
+
: "clamp(60%, 65% + (100vw - 1300px) * 0.1, 65%)",
|
|
599
669
|
right: 0,
|
|
600
670
|
justifyContent: isCentered ? "center" : "",
|
|
601
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")
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
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=
|
|
157
|
-
style={{
|
|
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
|
);
|