kupos-ui-components-lib 9.11.2 → 9.11.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.
- package/dist/components/ServiceItem/ServiceItemDesktop.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemDesktop.js +22 -5
- 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 -13
- 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 -2
- 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 +95 -23
- 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,7 +152,15 @@ function ServiceItemPB({
|
|
|
145
152
|
isFlores,
|
|
146
153
|
operatorLabel,
|
|
147
154
|
}: ServiceItemProps & { currencySign?: string }): React.ReactElement {
|
|
148
|
-
|
|
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
|
+
};
|
|
149
164
|
const getAnimationIcon = (icon: string) => {
|
|
150
165
|
const animation = ANIMATION_MAP[icon];
|
|
151
166
|
if (!animation) return null;
|
|
@@ -367,6 +382,17 @@ function ServiceItemPB({
|
|
|
367
382
|
return;
|
|
368
383
|
}
|
|
369
384
|
|
|
385
|
+
if (isTrain) {
|
|
386
|
+
if (!selectedSeatKey) {
|
|
387
|
+
onShowSeatSelectionError?.(serviceItem.id);
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (onTrainButtonClick) {
|
|
391
|
+
onTrainButtonClick();
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
370
396
|
onBookButtonPress();
|
|
371
397
|
};
|
|
372
398
|
|
|
@@ -559,7 +585,9 @@ function ServiceItemPB({
|
|
|
559
585
|
: "",
|
|
560
586
|
}}
|
|
561
587
|
>
|
|
562
|
-
<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
|
+
>
|
|
563
591
|
{/* OPERATOR LOGO */}
|
|
564
592
|
<div className="flex flex-col gap-[5px]">
|
|
565
593
|
<div>
|
|
@@ -621,6 +649,10 @@ function ServiceItemPB({
|
|
|
621
649
|
isPeru={isPeru}
|
|
622
650
|
renderIcon={renderIcon}
|
|
623
651
|
discountSeatPriceColor={colors.discountSeatPriceColor}
|
|
652
|
+
isTrain={isTrain}
|
|
653
|
+
selectedSeatKey={selectedSeatKey}
|
|
654
|
+
onSeatSelect={handleSeatSelect}
|
|
655
|
+
topLabelColor={colors.topLabelColor}
|
|
624
656
|
tooltipColor={colors.tooltipColor}
|
|
625
657
|
/>
|
|
626
658
|
</div>
|
|
@@ -637,6 +669,18 @@ function ServiceItemPB({
|
|
|
637
669
|
soldOutIcon={renderIcon("soldOutIcon", "14px")}
|
|
638
670
|
onClick={checkMidnight}
|
|
639
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
|
+
)}
|
|
640
684
|
{showLastSeats ? (
|
|
641
685
|
<div className="flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]">
|
|
642
686
|
{serviceItem?.available_seats < 10 &&
|
|
@@ -669,6 +713,7 @@ function ServiceItemPB({
|
|
|
669
713
|
setIsExpand(isItemExpanded ? null : serviceItem.id)
|
|
670
714
|
}
|
|
671
715
|
isPeru={isPeru}
|
|
716
|
+
isTrain={isTrain}
|
|
672
717
|
/>
|
|
673
718
|
</div>
|
|
674
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,16 +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);
|
|
110
|
-
console.log("🚀 ~ SeatSection ~ sortedSeatTypes:", sortedSeatTypes);
|
|
128
|
+
const sortedSeatTypes = getSortedSeatTypes(seatTypes, isTrain);
|
|
111
129
|
const numberOfSeats = getNumberOfSeats(seatTypes);
|
|
112
130
|
const isCentered = numberOfSeats < 2 || removeDuplicateSeats;
|
|
113
131
|
|
|
@@ -119,22 +137,68 @@ function SeatSection({
|
|
|
119
137
|
const renderSeatNames = () => {
|
|
120
138
|
const seats = removeDuplicateSeats ? uniqueSeats : sortedSeatTypes;
|
|
121
139
|
|
|
122
|
-
return seats.map((val, key: number) =>
|
|
123
|
-
SEAT_EXCEPTIONS.includes(val.label) ? null : (
|
|
124
|
-
<
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
+
}
|
|
129
158
|
>
|
|
130
|
-
{
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
+
});
|
|
138
202
|
};
|
|
139
203
|
|
|
140
204
|
const renderSeatPrices = () => {
|
|
@@ -151,7 +215,10 @@ function SeatSection({
|
|
|
151
215
|
serviceItem,
|
|
152
216
|
);
|
|
153
217
|
return (
|
|
154
|
-
<span
|
|
218
|
+
<span
|
|
219
|
+
key={key}
|
|
220
|
+
className="flex items-center text-[13.33px] bold-text"
|
|
221
|
+
>
|
|
155
222
|
{formatPrice(discountedPrice)}
|
|
156
223
|
</span>
|
|
157
224
|
);
|
|
@@ -235,6 +302,7 @@ function SeatSection({
|
|
|
235
302
|
}
|
|
236
303
|
return null;
|
|
237
304
|
})();
|
|
305
|
+
console.log("🚀 ~ SeatSection ~ serviceItem:", serviceItem);
|
|
238
306
|
|
|
239
307
|
// Hide the % OFF badge when max_discount is capping the percentage discount
|
|
240
308
|
// (i.e. both percentage and max_discount exist, and the raw % amount exceeds the cap)
|
|
@@ -304,7 +372,9 @@ function SeatSection({
|
|
|
304
372
|
|
|
305
373
|
<span className="text-[13.33px] flex flex-col">
|
|
306
374
|
{operatorServiceName ? (
|
|
307
|
-
<span className="text-[13.33px]">
|
|
375
|
+
<span className="text-[13.33px] whitespace-nowrap">
|
|
376
|
+
{seatLabel}
|
|
377
|
+
</span>
|
|
308
378
|
) : (
|
|
309
379
|
<span className="text-[13.33px]">Desde</span>
|
|
310
380
|
)}
|
|
@@ -527,7 +597,7 @@ function SeatSection({
|
|
|
527
597
|
style={{ textAlign: "center" }}
|
|
528
598
|
>
|
|
529
599
|
<span
|
|
530
|
-
className="text-[13.33px] font-normal leading-[20px] text-[#9f9f9f] relative"
|
|
600
|
+
className="text-[13.33px] font-normal leading-[20px] text-[#9f9f9f] relative whitespace-nowrap"
|
|
531
601
|
style={{
|
|
532
602
|
position: "relative",
|
|
533
603
|
}}
|
|
@@ -589,7 +659,9 @@ function SeatSection({
|
|
|
589
659
|
color: isSoldOut ? "#c0c0c0" : priceColor,
|
|
590
660
|
top: 0,
|
|
591
661
|
bottom: 0,
|
|
592
|
-
left:
|
|
662
|
+
left: isTrain
|
|
663
|
+
? "73%"
|
|
664
|
+
: "clamp(60%, 65% + (100vw - 1300px) * 0.1, 65%)",
|
|
593
665
|
right: 0,
|
|
594
666
|
justifyContent: isCentered ? "center" : "",
|
|
595
667
|
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
|
);
|