kupos-ui-components-lib 9.8.7 → 9.8.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 +20 -2
- package/dist/components/ServiceItem/ServiceItemMobile.d.ts +1 -1
- package/dist/components/ServiceItem/ServiceItemMobile.js +2 -2
- package/dist/components/ServiceItem/mobileTypes.d.ts +1 -0
- package/dist/components/ServiceItem/types.d.ts +7 -0
- package/dist/styles.css +3 -0
- package/dist/ui/SeatSection/SeatSection.d.ts +7 -1
- package/dist/ui/SeatSection/SeatSection.js +39 -9
- package/dist/ui/mobileweb/ExpandedDropdownMobile.d.ts +2 -1
- package/dist/ui/mobileweb/ExpandedDropdownMobile.js +4 -2
- package/package.json +1 -1
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +43 -0
- package/src/components/ServiceItem/ServiceItemMobile.tsx +2 -0
- package/src/components/ServiceItem/mobileTypes.ts +8 -7
- package/src/components/ServiceItem/types.ts +12 -0
- package/src/ui/SeatSection/SeatSection.tsx +83 -18
- package/src/ui/mobileweb/ExpandedDropdownMobile.tsx +3 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ServiceItemProps } from "./types";
|
|
3
|
-
declare function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isPeruSites, showAvailableSeats, isSeatIcon, isLinatal, isPeru, t, siteType, isAllinBus, isExpand, setIsExpand, coachKey, viewersConfig, showLoginModal, isLoggedIn, showLoginOption, isFlores, operatorLabel, }: ServiceItemProps & {
|
|
3
|
+
declare function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isPeruSites, showAvailableSeats, isSeatIcon, isLinatal, isPeru, t, siteType, isAllinBus, isExpand, setIsExpand, coachKey, viewersConfig, showLoginModal, isLoggedIn, showLoginOption, isTrain, selectedSeatKey, onSeatSelect, onTrainButtonClick, showSeatSelectionError, onShowSeatSelectionError, onClearSeatSelectionError, isFlores, operatorLabel, }: ServiceItemProps & {
|
|
4
4
|
currencySign?: string;
|
|
5
5
|
}): React.ReactElement;
|
|
6
6
|
export default ServiceItemPB;
|
|
@@ -74,8 +74,12 @@ const ANIMATION_MAP = {
|
|
|
74
74
|
kupos: femaleAnimation,
|
|
75
75
|
},
|
|
76
76
|
};
|
|
77
|
-
function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isPeruSites, showAvailableSeats, isSeatIcon, isLinatal, isPeru, t = (key) => key, siteType, isAllinBus, isExpand, setIsExpand, coachKey, viewersConfig, showLoginModal, isLoggedIn, showLoginOption, isFlores, operatorLabel, }) {
|
|
77
|
+
function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, children, busStage, serviceDetailsLoading, cityOrigin, cityDestination, translation, orignLabel, destinationLabel, currencySign, isCiva, showRating, showLastSeats, removeArrivalTime, removeDuplicateSeats, isPeruSites, showAvailableSeats, isSeatIcon, isLinatal, isPeru, t = (key) => key, siteType, isAllinBus, isExpand, setIsExpand, coachKey, viewersConfig, showLoginModal, isLoggedIn, showLoginOption, isTrain, selectedSeatKey, onSeatSelect, onTrainButtonClick, showSeatSelectionError, onShowSeatSelectionError, onClearSeatSelectionError, isFlores, operatorLabel, }) {
|
|
78
78
|
var _a;
|
|
79
|
+
const handleSeatSelect = (key, price, seatKey, apiSeatType) => {
|
|
80
|
+
onClearSeatSelectionError === null || onClearSeatSelectionError === void 0 ? void 0 : onClearSeatSelectionError();
|
|
81
|
+
onSeatSelect === null || onSeatSelect === void 0 ? void 0 : onSeatSelect(key, price, seatKey, apiSeatType);
|
|
82
|
+
};
|
|
79
83
|
const getAnimationIcon = (icon) => {
|
|
80
84
|
var _a;
|
|
81
85
|
const animation = ANIMATION_MAP[icon];
|
|
@@ -213,6 +217,16 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
|
|
|
213
217
|
});
|
|
214
218
|
return;
|
|
215
219
|
}
|
|
220
|
+
if (isTrain) {
|
|
221
|
+
if (!selectedSeatKey) {
|
|
222
|
+
onShowSeatSelectionError === null || onShowSeatSelectionError === void 0 ? void 0 : onShowSeatSelectionError(serviceItem.id);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (onTrainButtonClick) {
|
|
226
|
+
onTrainButtonClick();
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
216
230
|
onBookButtonPress();
|
|
217
231
|
};
|
|
218
232
|
const items = [
|
|
@@ -275,9 +289,13 @@ function ServiceItemPB({ serviceItem, onBookButtonPress, colors, metaData, child
|
|
|
275
289
|
backgroundColor: "#ccc",
|
|
276
290
|
} }),
|
|
277
291
|
React.createElement("div", { className: "content-center" },
|
|
278
|
-
React.createElement(SeatSection, { seatTypes: serviceItem.seat_types, serviceItem: serviceItem, availableSeats: serviceItem.available_seats, isSoldOut: isSoldOut, priceColor: colors.priceColor, dpSeatColor: colors.seatPriceColor, currencySign: currencySign, removeDuplicateSeats: removeDuplicateSeats, isPeru: isPeru, renderIcon: renderIcon, discountSeatPriceColor: colors.discountSeatPriceColor })),
|
|
292
|
+
React.createElement(SeatSection, { seatTypes: serviceItem.seat_types, serviceItem: serviceItem, availableSeats: serviceItem.available_seats, isSoldOut: isSoldOut, priceColor: colors.priceColor, dpSeatColor: colors.seatPriceColor, currencySign: currencySign, removeDuplicateSeats: removeDuplicateSeats, isPeru: isPeru, renderIcon: renderIcon, discountSeatPriceColor: colors.discountSeatPriceColor, isTrain: isTrain, selectedSeatKey: selectedSeatKey, onSeatSelect: handleSeatSelect, topLabelColor: colors.topLabelColor })),
|
|
279
293
|
React.createElement("div", { className: "relative" },
|
|
280
294
|
React.createElement(KuposButton, { isSoldOut: isSoldOut, isLoading: serviceDetailsLoading, buttonColor: colors.kuposButtonColor, buyLabel: translation === null || translation === void 0 ? void 0 : translation.buyButton, soldOutLabel: translation === null || translation === void 0 ? void 0 : translation.soldOutButton, soldOutIcon: renderIcon("soldOutIcon", "14px"), onClick: checkMidnight }),
|
|
295
|
+
showSeatSelectionError === serviceItem.id && isTrain && (React.createElement("div", { className: "flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]" },
|
|
296
|
+
React.createElement("div", { className: "text-[9px] text-center whitespace-nowrap", style: {
|
|
297
|
+
color: colors.seatPriceColor,
|
|
298
|
+
} }, "Selecciona el tipo de servicio"))),
|
|
281
299
|
showLastSeats ? (React.createElement("div", { className: "flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]" }, (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) < 10 &&
|
|
282
300
|
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.available_seats) > 0 && (React.createElement("div", { className: "text-[12px] mt-1 text-center", style: {
|
|
283
301
|
color: colors.seatPriceColor,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { MobileServiceItemProps } from "./mobileTypes";
|
|
3
|
-
declare function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig, }: MobileServiceItemProps): React.ReactElement;
|
|
3
|
+
declare function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig, operatorLabel, }: MobileServiceItemProps): React.ReactElement;
|
|
4
4
|
export default ServiceItemMobile;
|
|
@@ -17,7 +17,7 @@ const exceptions = [
|
|
|
17
17
|
"blanco",
|
|
18
18
|
"asiento_mascota",
|
|
19
19
|
];
|
|
20
|
-
function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig, }) {
|
|
20
|
+
function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, orignLabel, destinationLabel, amenitiesData, setShowDropdown, showDropdown, isExpanded, setIsExpanded, setAmenetiesAtomValue, isCiva, currencySign, isPeru, showRating, showLastSeats, removeDuplicateSeats, isLinatal, viewersConfig, operatorLabel, }) {
|
|
21
21
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
22
22
|
const isItemExpanded = serviceItem.id === isExpanded;
|
|
23
23
|
const isPetSeat = (Object.keys(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.pet_seat_info) || []).length > 0;
|
|
@@ -180,6 +180,6 @@ function ServiceItemMobile({ serviceItem, onBookButtonPress, colors, busStage, o
|
|
|
180
180
|
zIndex: (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) ? -3 : undefined,
|
|
181
181
|
marginTop: (serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.offer_text) ? "-15px" : "-10px",
|
|
182
182
|
} },
|
|
183
|
-
React.createElement(ExpandedDropdownMobile, { serviceItem: serviceItem, isPeru: isPeru, petSeatInfo: serviceItem.pet_seat_info, petFriendlyAnim: serviceItem.icons.petFriendlyAnim, isSoldOut: isSoldOut, isChangeTicket: serviceItem.is_change_ticket === true, ladiesBookedSeats: serviceItem.ladies_booked_seats, isDpEnabled: serviceItem.is_dp_enabled, femaleAnim: serviceItem.icons.femaleAnim, flexibleAnim: serviceItem.icons.flexibleAnim, renderIcon: renderIcon })))));
|
|
183
|
+
React.createElement(ExpandedDropdownMobile, { serviceItem: serviceItem, isPeru: isPeru, petSeatInfo: serviceItem.pet_seat_info, petFriendlyAnim: serviceItem.icons.petFriendlyAnim, isSoldOut: isSoldOut, isChangeTicket: serviceItem.is_change_ticket === true, ladiesBookedSeats: serviceItem.ladies_booked_seats, isDpEnabled: serviceItem.is_dp_enabled, femaleAnim: serviceItem.icons.femaleAnim, flexibleAnim: serviceItem.icons.flexibleAnim, renderIcon: renderIcon, operatorLabel: operatorLabel })))));
|
|
184
184
|
}
|
|
185
185
|
export default ServiceItemMobile;
|
|
@@ -224,6 +224,13 @@ export interface ServiceItemProps {
|
|
|
224
224
|
showLoginModal?: any;
|
|
225
225
|
isLoggedIn?: any;
|
|
226
226
|
showLoginOption?: boolean;
|
|
227
|
+
isTrain?: boolean;
|
|
228
|
+
selectedSeatKey?: any;
|
|
229
|
+
onSeatSelect?: (key: any, price: number, seatKey: string, apiSeatType?: string) => void;
|
|
230
|
+
onTrainButtonClick?: any;
|
|
231
|
+
showSeatSelectionError?: string | null;
|
|
232
|
+
onShowSeatSelectionError?: (serviceId: string) => void;
|
|
233
|
+
onClearSeatSelectionError?: () => void;
|
|
227
234
|
isFlores?: boolean;
|
|
228
235
|
operatorLabel?: string;
|
|
229
236
|
}
|
package/dist/styles.css
CHANGED
|
@@ -3,6 +3,8 @@ interface SeatType {
|
|
|
3
3
|
label: string;
|
|
4
4
|
fare: number;
|
|
5
5
|
key: any;
|
|
6
|
+
apiSeatType?: string;
|
|
7
|
+
api_seat_type?: string;
|
|
6
8
|
}
|
|
7
9
|
interface SeatSectionProps {
|
|
8
10
|
seatTypes: SeatType[];
|
|
@@ -16,6 +18,10 @@ interface SeatSectionProps {
|
|
|
16
18
|
serviceItem?: any;
|
|
17
19
|
renderIcon?: (iconKey: string, size?: string) => React.ReactNode;
|
|
18
20
|
discountSeatPriceColor?: string;
|
|
21
|
+
isTrain?: boolean;
|
|
22
|
+
selectedSeatKey?: any;
|
|
23
|
+
onSeatSelect?: (key: any, price: number, seatKey: string, apiSeatType?: string) => void;
|
|
24
|
+
topLabelColor?: string;
|
|
19
25
|
}
|
|
20
|
-
declare function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, isPeru, serviceItem, renderIcon, dpSeatColor, discountSeatPriceColor, }: SeatSectionProps): React.ReactElement;
|
|
26
|
+
declare function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, selectedSeatKey, onSeatSelect, isPeru, serviceItem, renderIcon, dpSeatColor, discountSeatPriceColor, isTrain, topLabelColor, }: SeatSectionProps): React.ReactElement;
|
|
21
27
|
export default SeatSection;
|
|
@@ -8,11 +8,13 @@ function getAllSeatTypes(seatTypes) {
|
|
|
8
8
|
let seatTypesWithPrices = seatTypes.filter(Boolean).map((val) => ({
|
|
9
9
|
label: val === null || val === void 0 ? void 0 : val.label,
|
|
10
10
|
price: val === null || val === void 0 ? void 0 : val.fare,
|
|
11
|
+
key: val === null || val === void 0 ? void 0 : val.key,
|
|
12
|
+
apiSeatType: (val === null || val === void 0 ? void 0 : val.apiSeatType) || (val === null || val === void 0 ? void 0 : val.api_seat_type),
|
|
11
13
|
}));
|
|
12
14
|
seatTypesWithPrices.sort((a, b) => a.price - b.price);
|
|
13
15
|
return seatTypesWithPrices;
|
|
14
16
|
}
|
|
15
|
-
function getSortedSeatTypes(seatTypes) {
|
|
17
|
+
function getSortedSeatTypes(seatTypes, isTrain) {
|
|
16
18
|
if (!(seatTypes === null || seatTypes === void 0 ? void 0 : seatTypes.length)) {
|
|
17
19
|
return [{ label: "Salon cama", price: 0 }];
|
|
18
20
|
}
|
|
@@ -21,7 +23,12 @@ function getSortedSeatTypes(seatTypes) {
|
|
|
21
23
|
if (premiumIndex >= 3) {
|
|
22
24
|
seatTypesWithPrices[2] = seatTypesWithPrices[premiumIndex];
|
|
23
25
|
}
|
|
24
|
-
|
|
26
|
+
if (isTrain) {
|
|
27
|
+
seatTypesWithPrices = seatTypesWithPrices.slice(0, 4);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
|
|
31
|
+
}
|
|
25
32
|
const seenPrices = new Set();
|
|
26
33
|
seatTypesWithPrices = seatTypesWithPrices.filter((seat) => {
|
|
27
34
|
if (seenPrices.has(seat.price))
|
|
@@ -54,10 +61,10 @@ function getUniqueSeats(seatTypes) {
|
|
|
54
61
|
function getNumberOfSeats(seatTypes) {
|
|
55
62
|
return seatTypes.filter((val) => !SEAT_EXCEPTIONS.includes(val.label)).length;
|
|
56
63
|
}
|
|
57
|
-
function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, isPeru, serviceItem, renderIcon, dpSeatColor, discountSeatPriceColor, }) {
|
|
64
|
+
function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currencySign, removeDuplicateSeats, selectedSeatKey, onSeatSelect, isPeru, serviceItem, renderIcon, dpSeatColor, discountSeatPriceColor, isTrain, topLabelColor, }) {
|
|
58
65
|
var _a;
|
|
59
66
|
const uniqueSeats = getUniqueSeats(seatTypes);
|
|
60
|
-
const sortedSeatTypes = getSortedSeatTypes(seatTypes);
|
|
67
|
+
const sortedSeatTypes = getSortedSeatTypes(seatTypes, isTrain);
|
|
61
68
|
const numberOfSeats = getNumberOfSeats(seatTypes);
|
|
62
69
|
const isCentered = numberOfSeats < 2 || removeDuplicateSeats;
|
|
63
70
|
const formatPrice = (price) => availableSeats <= 0
|
|
@@ -65,11 +72,34 @@ function SeatSection({ seatTypes, availableSeats, isSoldOut, priceColor, currenc
|
|
|
65
72
|
: CommonService.currency(price, currencySign);
|
|
66
73
|
const renderSeatNames = () => {
|
|
67
74
|
const seats = removeDuplicateSeats ? uniqueSeats : sortedSeatTypes;
|
|
68
|
-
return seats.map((val, key) =>
|
|
69
|
-
?
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
return seats.map((val, key) => {
|
|
76
|
+
return SEAT_EXCEPTIONS.includes(val.label) ? null : (React.createElement("div", { className: "flex items-center", style: isTrain ? { cursor: "pointer" } : undefined, onClick: isTrain && !isSoldOut
|
|
77
|
+
? () => val.label === selectedSeatKey
|
|
78
|
+
? onSeatSelect === null || onSeatSelect === void 0 ? void 0 : onSeatSelect(null, 0, "", "")
|
|
79
|
+
: onSeatSelect === null || onSeatSelect === void 0 ? void 0 : onSeatSelect(val.label, val.price, val.key, val.apiSeatType)
|
|
80
|
+
: undefined },
|
|
81
|
+
isTrain && (React.createElement("div", { style: {
|
|
82
|
+
border: `1px solid ${val.label === selectedSeatKey ? topLabelColor : "#ccc"}`,
|
|
83
|
+
borderRadius: "50%",
|
|
84
|
+
width: "14px",
|
|
85
|
+
height: "14px",
|
|
86
|
+
minWidth: "14px",
|
|
87
|
+
marginRight: "10px",
|
|
88
|
+
display: "flex",
|
|
89
|
+
alignItems: "center",
|
|
90
|
+
justifyContent: "center",
|
|
91
|
+
} }, val.label === selectedSeatKey && (React.createElement("div", { style: {
|
|
92
|
+
backgroundColor: topLabelColor,
|
|
93
|
+
borderRadius: "50%",
|
|
94
|
+
width: "7px",
|
|
95
|
+
height: "7px",
|
|
96
|
+
} })))),
|
|
97
|
+
React.createElement("span", { key: key, className: `flex items-center justify-between text-[13.33px] ${isSoldOut ? "text-[#c0c0c0]" : ""}` }, typeof val.label === "string" || typeof val.label === "number"
|
|
98
|
+
? removeDuplicateSeats && isPeru
|
|
99
|
+
? CommonService.truncateSeatLabel(val.label)
|
|
100
|
+
: val.label
|
|
101
|
+
: null)));
|
|
102
|
+
});
|
|
73
103
|
};
|
|
74
104
|
const renderSeatPrices = () => {
|
|
75
105
|
if (isPeru) {
|
|
@@ -16,6 +16,7 @@ interface ExpandedDropdownMobileProps {
|
|
|
16
16
|
femaleAnim?: any;
|
|
17
17
|
flexibleAnim?: any;
|
|
18
18
|
renderIcon?: any;
|
|
19
|
+
operatorLabel?: string;
|
|
19
20
|
}
|
|
20
|
-
declare function ExpandedDropdownMobile({ serviceItem, isPeru, petSeatInfo, petFriendlyAnim, isSoldOut, isChangeTicket, ladiesBookedSeats, isDpEnabled, femaleAnim, flexibleAnim, renderIcon, }: ExpandedDropdownMobileProps): React.ReactElement;
|
|
21
|
+
declare function ExpandedDropdownMobile({ serviceItem, isPeru, petSeatInfo, petFriendlyAnim, isSoldOut, isChangeTicket, ladiesBookedSeats, isDpEnabled, femaleAnim, flexibleAnim, renderIcon, operatorLabel, }: ExpandedDropdownMobileProps): React.ReactElement;
|
|
21
22
|
export default ExpandedDropdownMobile;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
function ExpandedDropdownMobile({ serviceItem, isPeru, petSeatInfo, petFriendlyAnim, isSoldOut, isChangeTicket = false, ladiesBookedSeats, isDpEnabled, femaleAnim, flexibleAnim, renderIcon, }) {
|
|
2
|
+
function ExpandedDropdownMobile({ serviceItem, isPeru, petSeatInfo, petFriendlyAnim, isSoldOut, isChangeTicket = false, ladiesBookedSeats, isDpEnabled, femaleAnim, flexibleAnim, renderIcon, operatorLabel, }) {
|
|
3
3
|
return (React.createElement("div", { className: "px-[12px] pt-[22px] pb-[12px] relative -z-9", style: {
|
|
4
4
|
backgroundColor: "#ffefef",
|
|
5
5
|
borderRadius: "0 0 14px 14px",
|
|
@@ -17,7 +17,9 @@ function ExpandedDropdownMobile({ serviceItem, isPeru, petSeatInfo, petFriendlyA
|
|
|
17
17
|
(serviceItem === null || serviceItem === void 0 ? void 0 : serviceItem.change_ticket_hours) || 6,
|
|
18
18
|
" horas antes"),
|
|
19
19
|
" ",
|
|
20
|
-
"de la salida del bus. El monto ser\u00E1 reembolsado a tu billetera
|
|
20
|
+
"de la salida del bus. El monto ser\u00E1 reembolsado a tu billetera",
|
|
21
|
+
operatorLabel || "kupospay",
|
|
22
|
+
"."))) : (React.createElement("div", { className: "flex gap-[8px] " },
|
|
21
23
|
React.createElement("span", { className: "mt-[3px]" }, renderIcon("changeTicketIcon", "14px")),
|
|
22
24
|
React.createElement("span", null,
|
|
23
25
|
React.createElement("span", null,
|
package/package.json
CHANGED
|
@@ -116,9 +116,25 @@ function ServiceItemPB({
|
|
|
116
116
|
showLoginModal,
|
|
117
117
|
isLoggedIn,
|
|
118
118
|
showLoginOption,
|
|
119
|
+
isTrain,
|
|
120
|
+
selectedSeatKey,
|
|
121
|
+
onSeatSelect,
|
|
122
|
+
onTrainButtonClick,
|
|
123
|
+
showSeatSelectionError,
|
|
124
|
+
onShowSeatSelectionError,
|
|
125
|
+
onClearSeatSelectionError,
|
|
119
126
|
isFlores,
|
|
120
127
|
operatorLabel,
|
|
121
128
|
}: ServiceItemProps & { currencySign?: string }): React.ReactElement {
|
|
129
|
+
const handleSeatSelect = (
|
|
130
|
+
key: any,
|
|
131
|
+
price: number,
|
|
132
|
+
seatKey: string,
|
|
133
|
+
apiSeatType?: string,
|
|
134
|
+
) => {
|
|
135
|
+
onClearSeatSelectionError?.();
|
|
136
|
+
onSeatSelect?.(key, price, seatKey, apiSeatType);
|
|
137
|
+
};
|
|
122
138
|
const getAnimationIcon = (icon: string) => {
|
|
123
139
|
const animation = ANIMATION_MAP[icon];
|
|
124
140
|
if (!animation) return null;
|
|
@@ -315,6 +331,17 @@ function ServiceItemPB({
|
|
|
315
331
|
return;
|
|
316
332
|
}
|
|
317
333
|
|
|
334
|
+
if (isTrain) {
|
|
335
|
+
if (!selectedSeatKey) {
|
|
336
|
+
onShowSeatSelectionError?.(serviceItem.id);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
if (onTrainButtonClick) {
|
|
340
|
+
onTrainButtonClick();
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
318
345
|
onBookButtonPress();
|
|
319
346
|
};
|
|
320
347
|
|
|
@@ -528,6 +555,10 @@ function ServiceItemPB({
|
|
|
528
555
|
isPeru={isPeru}
|
|
529
556
|
renderIcon={renderIcon}
|
|
530
557
|
discountSeatPriceColor={colors.discountSeatPriceColor}
|
|
558
|
+
isTrain={isTrain}
|
|
559
|
+
selectedSeatKey={selectedSeatKey}
|
|
560
|
+
onSeatSelect={handleSeatSelect}
|
|
561
|
+
topLabelColor={colors.topLabelColor}
|
|
531
562
|
/>
|
|
532
563
|
</div>
|
|
533
564
|
|
|
@@ -543,6 +574,18 @@ function ServiceItemPB({
|
|
|
543
574
|
soldOutIcon={renderIcon("soldOutIcon", "14px")}
|
|
544
575
|
onClick={checkMidnight}
|
|
545
576
|
/>
|
|
577
|
+
{showSeatSelectionError === serviceItem.id && isTrain && (
|
|
578
|
+
<div className="flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]">
|
|
579
|
+
<div
|
|
580
|
+
className="text-[9px] text-center whitespace-nowrap"
|
|
581
|
+
style={{
|
|
582
|
+
color: colors.seatPriceColor,
|
|
583
|
+
}}
|
|
584
|
+
>
|
|
585
|
+
Selecciona el tipo de servicio
|
|
586
|
+
</div>
|
|
587
|
+
</div>
|
|
588
|
+
)}
|
|
546
589
|
{showLastSeats ? (
|
|
547
590
|
<div className="flex justify-center mr-[11px] w-[100%] right-[0px] absolute left-[0] top-[40px]">
|
|
548
591
|
{serviceItem?.available_seats < 10 &&
|
|
@@ -45,6 +45,7 @@ function ServiceItemMobile({
|
|
|
45
45
|
removeDuplicateSeats,
|
|
46
46
|
isLinatal,
|
|
47
47
|
viewersConfig,
|
|
48
|
+
operatorLabel,
|
|
48
49
|
}: MobileServiceItemProps): React.ReactElement {
|
|
49
50
|
const isItemExpanded = serviceItem.id === isExpanded;
|
|
50
51
|
const isPetSeat = (Object.keys(serviceItem?.pet_seat_info) || []).length > 0;
|
|
@@ -459,6 +460,7 @@ function ServiceItemMobile({
|
|
|
459
460
|
femaleAnim={serviceItem.icons.femaleAnim}
|
|
460
461
|
flexibleAnim={serviceItem.icons.flexibleAnim}
|
|
461
462
|
renderIcon={renderIcon}
|
|
463
|
+
operatorLabel={operatorLabel}
|
|
462
464
|
/>
|
|
463
465
|
</div>
|
|
464
466
|
</div>
|
|
@@ -121,16 +121,16 @@ export interface MobileServiceItemProps {
|
|
|
121
121
|
bombAnim?: string;
|
|
122
122
|
whiteBoardingIcon?: string;
|
|
123
123
|
downArrow?: string;
|
|
124
|
-
personIcon?: string
|
|
124
|
+
personIcon?: string;
|
|
125
125
|
specialDeparture?: string;
|
|
126
126
|
fireIcon?: string;
|
|
127
127
|
directoIcon?: string;
|
|
128
|
-
whiteFireIcon?: string
|
|
129
|
-
femaleAnim?:string
|
|
130
|
-
|
|
128
|
+
whiteFireIcon?: string;
|
|
129
|
+
femaleAnim?: string;
|
|
130
|
+
cancelTicketIcon?: string;
|
|
131
131
|
changeTicketIcon?: string;
|
|
132
132
|
petFriendlyIcon?: string;
|
|
133
|
-
womenSeatIcon?: string
|
|
133
|
+
womenSeatIcon?: string;
|
|
134
134
|
[key: string]: string | Record<string, string | undefined> | undefined;
|
|
135
135
|
};
|
|
136
136
|
useLottieFor?: string[];
|
|
@@ -179,7 +179,7 @@ export interface MobileServiceItemProps {
|
|
|
179
179
|
seatPriceColor?: string;
|
|
180
180
|
rightGradiantColor?: string;
|
|
181
181
|
leftGradiantColor?: string;
|
|
182
|
-
discountSeatPriceColor?: string
|
|
182
|
+
discountSeatPriceColor?: string;
|
|
183
183
|
};
|
|
184
184
|
isCiva?: boolean;
|
|
185
185
|
currencySign?: string;
|
|
@@ -192,11 +192,12 @@ export interface MobileServiceItemProps {
|
|
|
192
192
|
showLastSeats?: boolean;
|
|
193
193
|
removeDuplicateSeats?: boolean;
|
|
194
194
|
isLinatal?: boolean;
|
|
195
|
-
|
|
195
|
+
viewersConfig?: {
|
|
196
196
|
min: number;
|
|
197
197
|
max: number;
|
|
198
198
|
interval?: number; // ms, default 5000
|
|
199
199
|
label?: string; // e.g. "personas están viendo este viaje"
|
|
200
200
|
icon?: string; // optional icon URL
|
|
201
201
|
};
|
|
202
|
+
operatorLabel?: string;
|
|
202
203
|
}
|
|
@@ -226,6 +226,18 @@ export interface ServiceItemProps {
|
|
|
226
226
|
showLoginModal?: any;
|
|
227
227
|
isLoggedIn?: any;
|
|
228
228
|
showLoginOption?: boolean;
|
|
229
|
+
isTrain?: boolean;
|
|
230
|
+
selectedSeatKey?: any;
|
|
231
|
+
onSeatSelect?: (
|
|
232
|
+
key: any,
|
|
233
|
+
price: number,
|
|
234
|
+
seatKey: string,
|
|
235
|
+
apiSeatType?: string,
|
|
236
|
+
) => void;
|
|
237
|
+
onTrainButtonClick?: any;
|
|
238
|
+
showSeatSelectionError?: string | null;
|
|
239
|
+
onShowSeatSelectionError?: (serviceId: string) => void;
|
|
240
|
+
onClearSeatSelectionError?: () => void;
|
|
229
241
|
isFlores?: boolean;
|
|
230
242
|
operatorLabel?: string;
|
|
231
243
|
}
|
|
@@ -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
|
}
|
|
25
36
|
|
|
26
37
|
function getAllSeatTypes(seatTypes: SeatType[]) {
|
|
@@ -31,6 +42,8 @@ function getAllSeatTypes(seatTypes: SeatType[]) {
|
|
|
31
42
|
let seatTypesWithPrices = seatTypes.filter(Boolean).map((val) => ({
|
|
32
43
|
label: val?.label,
|
|
33
44
|
price: val?.fare,
|
|
45
|
+
key: val?.key,
|
|
46
|
+
apiSeatType: val?.apiSeatType || val?.api_seat_type,
|
|
34
47
|
}));
|
|
35
48
|
|
|
36
49
|
seatTypesWithPrices.sort((a, b) => a.price - b.price);
|
|
@@ -38,7 +51,7 @@ function getAllSeatTypes(seatTypes: SeatType[]) {
|
|
|
38
51
|
return seatTypesWithPrices;
|
|
39
52
|
}
|
|
40
53
|
|
|
41
|
-
function getSortedSeatTypes(seatTypes: SeatType[]) {
|
|
54
|
+
function getSortedSeatTypes(seatTypes: SeatType[], isTrain: any) {
|
|
42
55
|
if (!seatTypes?.length) {
|
|
43
56
|
return [{ label: "Salon cama", price: 0 }];
|
|
44
57
|
}
|
|
@@ -52,7 +65,11 @@ function getSortedSeatTypes(seatTypes: SeatType[]) {
|
|
|
52
65
|
seatTypesWithPrices[2] = seatTypesWithPrices[premiumIndex];
|
|
53
66
|
}
|
|
54
67
|
|
|
55
|
-
|
|
68
|
+
if (isTrain) {
|
|
69
|
+
seatTypesWithPrices = seatTypesWithPrices.slice(0, 4);
|
|
70
|
+
} else {
|
|
71
|
+
seatTypesWithPrices = seatTypesWithPrices.slice(0, 2);
|
|
72
|
+
}
|
|
56
73
|
|
|
57
74
|
const seenPrices = new Set<number>();
|
|
58
75
|
seatTypesWithPrices = seatTypesWithPrices.filter((seat) => {
|
|
@@ -97,14 +114,18 @@ function SeatSection({
|
|
|
97
114
|
priceColor,
|
|
98
115
|
currencySign,
|
|
99
116
|
removeDuplicateSeats,
|
|
117
|
+
selectedSeatKey,
|
|
118
|
+
onSeatSelect,
|
|
100
119
|
isPeru,
|
|
101
120
|
serviceItem,
|
|
102
121
|
renderIcon,
|
|
103
122
|
dpSeatColor,
|
|
104
123
|
discountSeatPriceColor,
|
|
124
|
+
isTrain,
|
|
125
|
+
topLabelColor,
|
|
105
126
|
}: SeatSectionProps): React.ReactElement {
|
|
106
127
|
const uniqueSeats = getUniqueSeats(seatTypes);
|
|
107
|
-
const sortedSeatTypes = getSortedSeatTypes(seatTypes);
|
|
128
|
+
const sortedSeatTypes = getSortedSeatTypes(seatTypes, isTrain);
|
|
108
129
|
const numberOfSeats = getNumberOfSeats(seatTypes);
|
|
109
130
|
const isCentered = numberOfSeats < 2 || removeDuplicateSeats;
|
|
110
131
|
|
|
@@ -116,22 +137,66 @@ function SeatSection({
|
|
|
116
137
|
const renderSeatNames = () => {
|
|
117
138
|
const seats = removeDuplicateSeats ? uniqueSeats : sortedSeatTypes;
|
|
118
139
|
|
|
119
|
-
return seats.map((val, key: number) =>
|
|
120
|
-
SEAT_EXCEPTIONS.includes(val.label) ? null : (
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
+
}
|
|
126
158
|
>
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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] ${
|
|
188
|
+
isSoldOut ? "text-[#c0c0c0]" : ""
|
|
189
|
+
}`}
|
|
190
|
+
>
|
|
191
|
+
{typeof val.label === "string" || typeof val.label === "number"
|
|
192
|
+
? removeDuplicateSeats && isPeru
|
|
193
|
+
? CommonService.truncateSeatLabel(val.label)
|
|
194
|
+
: val.label
|
|
195
|
+
: null}
|
|
196
|
+
</span>
|
|
197
|
+
</div>
|
|
198
|
+
);
|
|
199
|
+
});
|
|
135
200
|
};
|
|
136
201
|
|
|
137
202
|
const renderSeatPrices = () => {
|
|
@@ -18,6 +18,7 @@ interface ExpandedDropdownMobileProps {
|
|
|
18
18
|
femaleAnim?: any;
|
|
19
19
|
flexibleAnim?: any;
|
|
20
20
|
renderIcon?: any;
|
|
21
|
+
operatorLabel?: string;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
function ExpandedDropdownMobile({
|
|
@@ -32,6 +33,7 @@ function ExpandedDropdownMobile({
|
|
|
32
33
|
femaleAnim,
|
|
33
34
|
flexibleAnim,
|
|
34
35
|
renderIcon,
|
|
36
|
+
operatorLabel,
|
|
35
37
|
}: ExpandedDropdownMobileProps): React.ReactElement {
|
|
36
38
|
return (
|
|
37
39
|
<div
|
|
@@ -59,7 +61,7 @@ function ExpandedDropdownMobile({
|
|
|
59
61
|
hasta {serviceItem?.change_ticket_hours || 6} horas antes
|
|
60
62
|
</span>{" "}
|
|
61
63
|
de la salida del bus. El monto será reembolsado a tu billetera
|
|
62
|
-
kupospay.
|
|
64
|
+
{operatorLabel || "kupospay"}.
|
|
63
65
|
</span>
|
|
64
66
|
</div>
|
|
65
67
|
) : (
|