kupos-ui-components-lib 9.3.9 → 9.4.0
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 +36 -34
- package/dist/components/ServiceItem/ServiceItemMobile.js +20 -25
- package/dist/components/ServiceItem/mobileTypes.d.ts +2 -0
- package/dist/components/ServiceItem/types.d.ts +4 -0
- package/dist/styles.css +29 -2
- package/dist/ui/KuposButton/KuposButton.js +2 -1
- package/dist/ui/SeatSection/SeatSection.d.ts +2 -1
- package/dist/ui/SeatSection/SeatSection.js +57 -8
- package/dist/ui/ServiceBadges/ServiceBadges.js +1 -1
- package/dist/ui/mobileweb/DateTimeSectionMobile.d.ts +2 -1
- package/dist/ui/mobileweb/DateTimeSectionMobile.js +2 -2
- package/dist/ui/mobileweb/SeatSectionMobile.d.ts +2 -1
- package/dist/ui/mobileweb/SeatSectionMobile.js +32 -2
- package/dist/ui/mobileweb/ServiceBadgesMobile.js +1 -1
- package/package.json +1 -1
- package/src/components/ServiceItem/ServiceItemDesktop.tsx +74 -47
- package/src/components/ServiceItem/ServiceItemMobile.tsx +67 -66
- package/src/components/ServiceItem/mobileTypes.ts +2 -0
- package/src/components/ServiceItem/types.ts +5 -0
- package/src/ui/KuposButton/KuposButton.tsx +7 -2
- package/src/ui/SeatSection/SeatSection.tsx +83 -7
- package/src/ui/ServiceBadges/ServiceBadges.tsx +1 -1
- package/src/ui/mobileweb/DateTimeSectionMobile.tsx +3 -0
- package/src/ui/mobileweb/SeatSectionMobile.tsx +95 -1
- package/src/ui/mobileweb/ServiceBadgesMobile.tsx +1 -1
|
@@ -14,6 +14,7 @@ interface SeatSectionProps {
|
|
|
14
14
|
availableSeats: number;
|
|
15
15
|
isSoldOut: boolean;
|
|
16
16
|
priceColor?: string;
|
|
17
|
+
dpSeatColor?: string;
|
|
17
18
|
currencySign?: string;
|
|
18
19
|
removeDuplicateSeats?: boolean;
|
|
19
20
|
isPeru?: boolean;
|
|
@@ -98,6 +99,7 @@ function SeatSection({
|
|
|
98
99
|
isPeru,
|
|
99
100
|
serviceItem,
|
|
100
101
|
renderIcon,
|
|
102
|
+
dpSeatColor,
|
|
101
103
|
}: SeatSectionProps): React.ReactElement {
|
|
102
104
|
const uniqueSeats = getUniqueSeats(seatTypes);
|
|
103
105
|
const sortedSeatTypes = getSortedSeatTypes(seatTypes);
|
|
@@ -220,30 +222,102 @@ function SeatSection({
|
|
|
220
222
|
return renderSeatNames();
|
|
221
223
|
};
|
|
222
224
|
|
|
225
|
+
if (serviceItem?.is_dp_enabled) {
|
|
226
|
+
const dpSeats = (
|
|
227
|
+
removeDuplicateSeats ? uniqueSeats : sortedSeatTypes
|
|
228
|
+
).filter((s) => !SEAT_EXCEPTIONS.includes(s.label));
|
|
229
|
+
const lowestFare =
|
|
230
|
+
dpSeats.length > 0 ? Math.min(...dpSeats.map((s) => Number(s.price))) : 0;
|
|
231
|
+
|
|
232
|
+
return (
|
|
233
|
+
<div className="flex items-center justify-between text-[13.33px] ">
|
|
234
|
+
<div>
|
|
235
|
+
<span className="text-[13.33px] font-normal leading-[24px] text-[#464647]">
|
|
236
|
+
Desde
|
|
237
|
+
</span>
|
|
238
|
+
</div>
|
|
239
|
+
<div>
|
|
240
|
+
<span
|
|
241
|
+
className="flex items-center gap-[6px] text-[22px] bold-text leading-[30px] relative"
|
|
242
|
+
style={{ color: isSoldOut ? "#c0c0c0" : dpSeatColor }}
|
|
243
|
+
>
|
|
244
|
+
<div className="absolute bottom-[85%]">
|
|
245
|
+
<span
|
|
246
|
+
className="rounded-[100px] bg-[#ff5964] px-[6px] w-fit text-[12px] bold-text leading-[20px] text-white"
|
|
247
|
+
style={{
|
|
248
|
+
animation: "pulse-zoom 2s ease-in-out infinite",
|
|
249
|
+
whiteSpace: "nowrap",
|
|
250
|
+
color: dpSeatColor,
|
|
251
|
+
}}
|
|
252
|
+
>
|
|
253
|
+
Mejor precio
|
|
254
|
+
</span>
|
|
255
|
+
</div>
|
|
256
|
+
<div className="absolute -left-[20px]">
|
|
257
|
+
{renderIcon("fireIcon", "16px")}
|
|
258
|
+
</div>
|
|
259
|
+
{availableSeats <= 0
|
|
260
|
+
? CommonService.currency(0, currencySign)
|
|
261
|
+
: CommonService.discountedCurrency(lowestFare, currencySign)}
|
|
262
|
+
</span>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
// <div className="flex items-center justify-between text-[13.33px]">
|
|
266
|
+
// <span className="text-[13.33px] font-normal leading-[24px] text-[#464647]">
|
|
267
|
+
// Desde
|
|
268
|
+
// </span>
|
|
269
|
+
// <div className="flex flex-col items-center gap-[2px]">
|
|
270
|
+
// <span
|
|
271
|
+
// className="rounded-[100px] bg-[#ff5964] px-[6px] w-fit text-[12px] bold-text leading-[20px] text-white"
|
|
272
|
+
// style={{
|
|
273
|
+
// animation: "pulse-zoom 2s ease-in-out infinite",
|
|
274
|
+
// whiteSpace: "nowrap",
|
|
275
|
+
// color: dpSeatColor,
|
|
276
|
+
// }}
|
|
277
|
+
// >
|
|
278
|
+
// Mejor precio
|
|
279
|
+
// </span>
|
|
280
|
+
// <span
|
|
281
|
+
// className="flex items-center gap-[6px] text-[22px] bold-text leading-[30px] relative"
|
|
282
|
+
// style={{ color: isSoldOut ? "#c0c0c0" : dpSeatColor }}
|
|
283
|
+
// >
|
|
284
|
+
// <div className="absolute -left-[20px]">
|
|
285
|
+
// {renderIcon("fireIcon", "16px")}
|
|
286
|
+
// </div>
|
|
287
|
+
// {availableSeats <= 0
|
|
288
|
+
// ? CommonService.currency(0, currencySign)
|
|
289
|
+
// : CommonService.discountedCurrency(lowestFare, currencySign)}
|
|
290
|
+
// </span>
|
|
291
|
+
// </div>
|
|
292
|
+
// </div>
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
223
296
|
if (hasDiscount && discountSeat) {
|
|
224
297
|
return (
|
|
225
|
-
<div className="grid
|
|
298
|
+
<div className="grid grid-cols-2 items-center text-[13.33px] relative">
|
|
226
299
|
<div className="col-start-1 row-start-2 flex items-center">
|
|
227
|
-
<span className="text-[13.33px] font-normal leading-[22px] text-[#
|
|
300
|
+
<span className="text-[13.33px] font-normal leading-[22px] text-[#ccc]">
|
|
228
301
|
Antes
|
|
229
302
|
</span>
|
|
230
303
|
</div>
|
|
231
304
|
|
|
232
|
-
<div className="col-start-1 row-start-3 flex h-[
|
|
233
|
-
<span className="text-[13.33px] font-normal leading-[
|
|
305
|
+
<div className="col-start-1 row-start-3 flex h-[20px] items-end">
|
|
306
|
+
<span className="text-[13.33px] font-normal leading-[20px] text-[#464647]">
|
|
234
307
|
Desde
|
|
235
308
|
</span>
|
|
236
309
|
</div>
|
|
237
310
|
|
|
238
311
|
<div
|
|
239
312
|
className="col-start-2 row-start-1 flex items-center justify-center absolute"
|
|
240
|
-
style={{ top: "-22px",
|
|
313
|
+
style={{ top: "-22px", left: "50%", transform: "translateX(-50%)" }}
|
|
241
314
|
>
|
|
242
315
|
{discountValue != null && (
|
|
243
316
|
<span
|
|
244
317
|
className="rounded-[100px] bg-[#ff5964] px-[6px] text-[12px] bold-text leading-[20px] text-white"
|
|
245
318
|
style={{
|
|
246
319
|
animation: "pulse-zoom 2s ease-in-out infinite",
|
|
320
|
+
whiteSpace: "nowrap",
|
|
247
321
|
}}
|
|
248
322
|
>
|
|
249
323
|
{discountValue}% OFF
|
|
@@ -277,13 +351,15 @@ function SeatSection({
|
|
|
277
351
|
</span>
|
|
278
352
|
</div>
|
|
279
353
|
|
|
280
|
-
<div className="col-start-2 row-start-3 flex h-[30px] items-end justify-center">
|
|
354
|
+
<div className="col-start-2 row-start-3 flex h-[30px] items-end justify-center relative">
|
|
281
355
|
<span
|
|
282
356
|
className="flex items-center gap-[6px] text-[22px] bold-text leading-[30px]"
|
|
283
357
|
style={{ color: isSoldOut ? "#c0c0c0" : "#ff5964" }}
|
|
284
358
|
>
|
|
285
359
|
{/* <span className="text-[18px] leading-[24px]">🔥</span> */}
|
|
286
|
-
|
|
360
|
+
<div className="absolute -left-[8px]">
|
|
361
|
+
{renderIcon("fireIcon", "16px")}
|
|
362
|
+
</div>
|
|
287
363
|
{availableSeats <= 0
|
|
288
364
|
? CommonService.currency(0, currencySign)
|
|
289
365
|
: CommonService.discountedCurrency(
|
|
@@ -24,7 +24,7 @@ const ServiceBadges: React.FC<ServiceBadgesProps> = ({
|
|
|
24
24
|
serviceItem,
|
|
25
25
|
}) => {
|
|
26
26
|
return (
|
|
27
|
-
<div className="absolute -top-[
|
|
27
|
+
<div className="absolute -top-[10px] left-0 w-full flex items-center justify-end gap-[12px] pr-[22px] z-10">
|
|
28
28
|
{showTopLabel && (
|
|
29
29
|
<div
|
|
30
30
|
className={`flex items-center gap-[10px] py-[4px] px-[14px] rounded-[38px] text-[12.5px] z-10`}
|
|
@@ -23,6 +23,7 @@ interface DateTimeSectionMobileProps {
|
|
|
23
23
|
removeDuplicateSeats?: boolean;
|
|
24
24
|
serviceItem?: any;
|
|
25
25
|
tooltipBgColor?: string;
|
|
26
|
+
showLastSeats?: boolean;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
const pad = (n: number) => (n < 10 ? "0" + n : String(n));
|
|
@@ -121,6 +122,7 @@ function DateTimeSectionMobile({
|
|
|
121
122
|
removeDuplicateSeats,
|
|
122
123
|
serviceItem,
|
|
123
124
|
tooltipBgColor,
|
|
125
|
+
showLastSeats,
|
|
124
126
|
}: DateTimeSectionMobileProps): React.ReactElement {
|
|
125
127
|
const { cleaned: cleanedDepTime, hasAM, hasPM } = getCleanedDepTime(depTime);
|
|
126
128
|
|
|
@@ -190,6 +192,7 @@ function DateTimeSectionMobile({
|
|
|
190
192
|
removeDuplicateSeats={removeDuplicateSeats}
|
|
191
193
|
serviceItem={serviceItem}
|
|
192
194
|
tooltipBgColor={tooltipBgColor}
|
|
195
|
+
showLastSeats={showLastSeats}
|
|
193
196
|
/>
|
|
194
197
|
</div>
|
|
195
198
|
);
|
|
@@ -29,6 +29,7 @@ interface SeatSectionMobileProps {
|
|
|
29
29
|
removeDuplicateSeats?: boolean;
|
|
30
30
|
serviceItem?: any;
|
|
31
31
|
tooltipBgColor?: string;
|
|
32
|
+
showLastSeats?: boolean;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
interface SeatRowProps {
|
|
@@ -114,6 +115,7 @@ function SeatSectionMobile({
|
|
|
114
115
|
removeDuplicateSeats,
|
|
115
116
|
serviceItem,
|
|
116
117
|
tooltipBgColor,
|
|
118
|
+
showLastSeats,
|
|
117
119
|
}: SeatSectionMobileProps): React.ReactElement {
|
|
118
120
|
const hasMultipleTypes = (seatTypesData?.length ?? 0) > 2;
|
|
119
121
|
|
|
@@ -183,6 +185,81 @@ function SeatSectionMobile({
|
|
|
183
185
|
);
|
|
184
186
|
};
|
|
185
187
|
|
|
188
|
+
const renderDpSeats = () => {
|
|
189
|
+
const lowestFare = getLowestFare();
|
|
190
|
+
if (lowestFare === null) return null;
|
|
191
|
+
|
|
192
|
+
const { discountedPrice } = commonService.calculateDiscountedPrice(
|
|
193
|
+
lowestFare,
|
|
194
|
+
serviceItem,
|
|
195
|
+
);
|
|
196
|
+
const priceColor = isSoldOut ? "#bbb" : tooltipBgColor;
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
<div className="relative flex flex-col justify-center h-full">
|
|
200
|
+
<div
|
|
201
|
+
className="absolute right-[0px]"
|
|
202
|
+
style={{
|
|
203
|
+
animation: "pulse-zoom 2s ease-in-out infinite",
|
|
204
|
+
top:
|
|
205
|
+
serviceItem?.available_seats < 10 &&
|
|
206
|
+
serviceItem?.available_seats > 0
|
|
207
|
+
? "-20px"
|
|
208
|
+
: "-10px",
|
|
209
|
+
}}
|
|
210
|
+
>
|
|
211
|
+
<span
|
|
212
|
+
className="rounded-[100px] px-[8px] text-[11px] bold-text leading-[20px] text-[#fff]"
|
|
213
|
+
style={{
|
|
214
|
+
backgroundColor: tooltipBgColor,
|
|
215
|
+
}}
|
|
216
|
+
>
|
|
217
|
+
Mejor precio
|
|
218
|
+
</span>
|
|
219
|
+
</div>
|
|
220
|
+
<div className="w-[100%] flex flex-row justify-between items-center">
|
|
221
|
+
<span
|
|
222
|
+
className="min-[420]:text-[13px] text-[12px]"
|
|
223
|
+
style={{ color: isSoldOut ? "#bbb" : "#464647" }}
|
|
224
|
+
>
|
|
225
|
+
Desde
|
|
226
|
+
</span>
|
|
227
|
+
<span
|
|
228
|
+
className="flex items-center gap-[4px] min-[420]:text-[13px] text-[14px] bold-text"
|
|
229
|
+
style={{ color: priceColor }}
|
|
230
|
+
>
|
|
231
|
+
{serviceItem?.icons?.fireIcon ? (
|
|
232
|
+
<img
|
|
233
|
+
src={serviceItem.icons.fireIcon}
|
|
234
|
+
alt="dp"
|
|
235
|
+
className="h-[14px] w-[14px] object-contain"
|
|
236
|
+
style={{ filter: isSoldOut ? "grayscale(1)" : "" }}
|
|
237
|
+
/>
|
|
238
|
+
) : null}
|
|
239
|
+
{commonService.currency(discountedPrice, currencySign)}
|
|
240
|
+
</span>
|
|
241
|
+
</div>
|
|
242
|
+
{showLastSeats ? (
|
|
243
|
+
<div className="flex justify-end">
|
|
244
|
+
{serviceItem?.available_seats < 10 &&
|
|
245
|
+
serviceItem?.available_seats > 0 && (
|
|
246
|
+
<div className="text-[10px] text-[#464647] text-center mt-[3px]">
|
|
247
|
+
¡Últimos Asientos!
|
|
248
|
+
</div>
|
|
249
|
+
)}
|
|
250
|
+
</div>
|
|
251
|
+
) : null}
|
|
252
|
+
{isSoldOut ? (
|
|
253
|
+
<div className="flex justify-end">
|
|
254
|
+
<span className="min-[420]:text-[13px] text-[12px] text-[#ccc]">
|
|
255
|
+
Agotado
|
|
256
|
+
</span>
|
|
257
|
+
</div>
|
|
258
|
+
) : null}
|
|
259
|
+
</div>
|
|
260
|
+
);
|
|
261
|
+
};
|
|
262
|
+
|
|
186
263
|
const renderSeats = () => {
|
|
187
264
|
if (isPeru) {
|
|
188
265
|
return renderPeruSeats();
|
|
@@ -262,7 +339,14 @@ function SeatSectionMobile({
|
|
|
262
339
|
|
|
263
340
|
return (
|
|
264
341
|
<div className="content-center relative" style={{ width: "40%" }}>
|
|
265
|
-
{
|
|
342
|
+
{serviceItem?.is_dp_enabled ? (
|
|
343
|
+
<div
|
|
344
|
+
className="flex flex-col justify-between h-[2.5rem]"
|
|
345
|
+
style={{ gap: isSoldOut ? "0px" : "5px" }}
|
|
346
|
+
>
|
|
347
|
+
{renderDpSeats()}
|
|
348
|
+
</div>
|
|
349
|
+
) : hasDiscount && discountSeat ? (
|
|
266
350
|
<div className="relative grid grid-cols-[auto_auto] justify-between gap-x-[8px] ">
|
|
267
351
|
{discountValue != null && (
|
|
268
352
|
<div
|
|
@@ -348,6 +432,16 @@ function SeatSectionMobile({
|
|
|
348
432
|
}}
|
|
349
433
|
>
|
|
350
434
|
{renderSeats()}
|
|
435
|
+
{showLastSeats ? (
|
|
436
|
+
<div className="flex justify-end ">
|
|
437
|
+
{serviceItem?.available_seats < 10 &&
|
|
438
|
+
serviceItem?.available_seats > 0 && (
|
|
439
|
+
<div className="text-[10px] text-[#464647] text-center">
|
|
440
|
+
¡ Últimos Asientos!
|
|
441
|
+
</div>
|
|
442
|
+
)}
|
|
443
|
+
</div>
|
|
444
|
+
) : null}
|
|
351
445
|
|
|
352
446
|
{isSoldOut ? (
|
|
353
447
|
<div className="flex justify-end">
|
|
@@ -24,7 +24,7 @@ const ServiceBadgesMobile: React.FC<ServiceBadgesMobileProps> = ({
|
|
|
24
24
|
isConexion,
|
|
25
25
|
}) => {
|
|
26
26
|
return (
|
|
27
|
-
<div className="absolute -top-[
|
|
27
|
+
<div className="absolute -top-[10px] left-0 w-full flex items-center justify-end gap-[12px] pr-[17px] z-10">
|
|
28
28
|
{showTopLabel && (
|
|
29
29
|
<div
|
|
30
30
|
className={`flex items-center gap-[2px] py-[4px] px-[10px] rounded-[38px] min-[420]:text-[12px] text-[10px] z-20`}
|