mautourco-components 0.2.27 → 0.2.29
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/atoms/Icon/icons/BadgeAlertIcon.d.ts +4 -0
- package/dist/components/atoms/Icon/icons/BadgeAlertIcon.js +36 -0
- package/dist/components/atoms/Icon/icons/registry.d.ts +1 -0
- package/dist/components/atoms/Icon/icons/registry.js +2 -0
- package/dist/components/molecules/AccomodationDocket/AccomodationDocket.d.ts +5 -1
- package/dist/components/molecules/AccomodationDocket/AccomodationDocket.js +4 -3
- package/dist/components/molecules/Calendar/CalendarInput.js +2 -1
- package/dist/components/molecules/ExcursionDocket/ExcursionDocket.d.ts +4 -0
- package/dist/components/molecules/ExcursionDocket/ExcursionDocket.js +3 -2
- package/dist/components/molecules/LocationDropdown/LocationDropdown.d.ts +2 -0
- package/dist/components/molecules/LocationDropdown/LocationDropdown.js +9 -3
- package/dist/components/molecules/OtherServiceDocket/OtherServiceDocket.d.ts +4 -0
- package/dist/components/molecules/OtherServiceDocket/OtherServiceDocket.js +3 -2
- package/dist/components/molecules/Toast/Toast.d.ts +25 -0
- package/dist/components/molecules/Toast/Toast.js +29 -0
- package/dist/components/molecules/Toast/index.d.ts +2 -0
- package/dist/components/molecules/Toast/index.js +1 -0
- package/dist/components/molecules/TransferDocket/TransferDocket.d.ts +4 -0
- package/dist/components/molecules/TransferDocket/TransferDocket.js +3 -2
- package/dist/components/organisms/CarBookingCard/CarBookingCard.css +13 -1
- package/dist/components/organisms/CarBookingCard/CarBookingCard.d.ts +2 -0
- package/dist/components/organisms/CarBookingCard/CarBookingCard.js +4 -3
- package/dist/components/organisms/CarBookingCard/CarBookingCardSkeleton.css +2334 -0
- package/dist/components/organisms/CarBookingCard/CarBookingCardSkeleton.d.ts +19 -0
- package/dist/components/organisms/CarBookingCard/CarBookingCardSkeleton.js +35 -0
- package/dist/components/organisms/CarBookingCard/index.d.ts +4 -2
- package/dist/components/organisms/CarBookingCard/index.js +2 -1
- package/dist/components/organisms/DateTimePicker/DateTimePicker.d.ts +8 -0
- package/dist/components/organisms/DateTimePicker/DateTimePicker.js +20 -7
- package/dist/components/organisms/Docket/Docket.d.ts +25 -2
- package/dist/components/organisms/Docket/Docket.js +18 -10
- package/dist/components/organisms/PaxSelector/PaxSelector.d.ts +2 -0
- package/dist/components/organisms/PaxSelector/PaxSelector.js +11 -5
- package/dist/components/organisms/RoundTrip/RoundTrip.d.ts +4 -2
- package/dist/components/organisms/RoundTrip/RoundTrip.js +21 -11
- package/dist/components/organisms/SearchBarTransfer/SearchBarTransfer.d.ts +2 -2
- package/dist/components/organisms/SearchBarTransfer/SearchBarTransfer.js +51 -8
- package/dist/components/organisms/TransferLine/TransferLine.d.ts +4 -2
- package/dist/components/organisms/TransferLine/TransferLine.js +18 -9
- package/dist/components/ui/popover.d.ts +1 -1
- package/dist/components/ui/popover.js +5 -3
- package/dist/index.d.ts +19 -16
- package/dist/index.js +3 -1
- package/dist/lib/utils.d.ts +21 -0
- package/dist/lib/utils.js +114 -0
- package/dist/styles/components/molecule/calendarInput.css +40 -5
- package/dist/styles/components/molecule/location-dropdown.css +7 -5
- package/dist/styles/components/molecule/toast.css +2185 -0
- package/dist/styles/components/organism/docket.css +7 -1
- package/dist/styles/components/organism/pax-selector.css +12 -1
- package/dist/styles/components/organism/round-trip.css +4 -0
- package/dist/styles/components/organism/transfer-line.css +5 -1
- package/package.json +1 -1
- package/src/components/atoms/Icon/icons/BadgeAlertIcon.tsx +44 -0
- package/src/components/atoms/Icon/icons/registry.tsx +2 -0
- package/src/components/molecules/AccomodationDocket/AccomodationDocket.tsx +26 -6
- package/src/components/molecules/Calendar/CalendarInput.tsx +5 -2
- package/src/components/molecules/ExcursionDocket/ExcursionDocket.tsx +25 -5
- package/src/components/molecules/LocationDropdown/LocationDropdown.tsx +11 -0
- package/src/components/molecules/OtherServiceDocket/OtherServiceDocket.tsx +25 -5
- package/src/components/molecules/Toast/Toast.tsx +49 -0
- package/src/components/molecules/Toast/index.ts +3 -0
- package/src/components/molecules/TransferDocket/TransferDocket.tsx +21 -3
- package/src/components/organisms/CarBookingCard/CarBookingCard.css +13 -1
- package/src/components/organisms/CarBookingCard/CarBookingCard.tsx +40 -21
- package/src/components/organisms/CarBookingCard/CarBookingCardSkeleton.css +257 -0
- package/src/components/organisms/CarBookingCard/CarBookingCardSkeleton.tsx +112 -0
- package/src/components/organisms/CarBookingCard/index.ts +10 -15
- package/src/components/organisms/DateTimePicker/DateTimePicker.tsx +39 -3
- package/src/components/organisms/Docket/Docket.tsx +82 -20
- package/src/components/organisms/PaxSelector/PaxSelector.tsx +11 -0
- package/src/components/organisms/RoundTrip/RoundTrip.tsx +31 -10
- package/src/components/organisms/SearchBarTransfer/SearchBarTransfer.tsx +108 -54
- package/src/components/organisms/SearchBarTransfer/index.ts +6 -0
- package/src/components/organisms/TransferLine/TransferLine.tsx +31 -10
- package/src/components/ui/popover.tsx +7 -7
- package/src/styles/components/molecule/calendarInput.css +33 -4
- package/src/styles/components/molecule/location-dropdown.css +6 -4
- package/src/styles/components/molecule/toast.css +93 -0
- package/src/styles/components/organism/docket.css +5 -1
- package/src/styles/components/organism/pax-selector.css +12 -1
- package/src/styles/components/organism/round-trip.css +4 -0
- package/src/styles/components/organism/transfer-line.css +5 -1
|
@@ -2074,13 +2074,19 @@
|
|
|
2074
2074
|
--mobile-global-spacing-section-gap-xl: 40px;
|
|
2075
2075
|
}
|
|
2076
2076
|
|
|
2077
|
+
.docket__container {
|
|
2078
|
+
width: -webkit-fit-content;
|
|
2079
|
+
width: fit-content;
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2077
2082
|
.docket {
|
|
2078
2083
|
display: flex;
|
|
2079
2084
|
flex-direction: column;
|
|
2080
2085
|
gap: 1.5rem;
|
|
2081
2086
|
padding: 1.5rem;
|
|
2082
2087
|
width: 384px;
|
|
2083
|
-
|
|
2088
|
+
height: -webkit-fit-content;
|
|
2089
|
+
height: fit-content;
|
|
2084
2090
|
background: var(--color-elevation-level-1, #ffffff);
|
|
2085
2091
|
border: var(--border-border, 1px) solid var(--color-border-subtle, #e5e5e5);
|
|
2086
2092
|
border-radius: var(--border-radius-lg, 8px);
|
|
@@ -2107,7 +2107,7 @@
|
|
|
2107
2107
|
.pax-selector__label {
|
|
2108
2108
|
font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
|
|
2109
2109
|
font-size: 14px;
|
|
2110
|
-
line-height:
|
|
2110
|
+
line-height: 1.5;
|
|
2111
2111
|
color: var(--input-color-label-default, #262626);
|
|
2112
2112
|
}
|
|
2113
2113
|
|
|
@@ -2131,6 +2131,17 @@
|
|
|
2131
2131
|
border-color: var(--color-text-default, #262626);
|
|
2132
2132
|
}
|
|
2133
2133
|
|
|
2134
|
+
.pax-selector--error .pax-selector__input {
|
|
2135
|
+
border-color: var(--color-red-600, #dc2626);
|
|
2136
|
+
background: var(--color-coral-red-50, #fff8f8);
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
.pax-selector--error .pax-selector__input-text,
|
|
2140
|
+
.pax-selector--error .pax-selector__input-icon,
|
|
2141
|
+
.pax-selector--error .pax-selector__chevron {
|
|
2142
|
+
color: var(--color-coral-red-600, #f83b3b);
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2134
2145
|
.pax-selector__input-content {
|
|
2135
2146
|
display: flex;
|
|
2136
2147
|
align-items: center;
|
|
@@ -2127,7 +2127,7 @@
|
|
|
2127
2127
|
}
|
|
2128
2128
|
|
|
2129
2129
|
.transfer-line__field p {
|
|
2130
|
-
line-height: 1.
|
|
2130
|
+
line-height: 1.5;
|
|
2131
2131
|
}
|
|
2132
2132
|
|
|
2133
2133
|
/* Mobile layout - stack fields vertically */
|
|
@@ -2206,3 +2206,7 @@
|
|
|
2206
2206
|
.transfer-line__delete-icon {
|
|
2207
2207
|
color: var(--color-neutral-800);
|
|
2208
2208
|
}
|
|
2209
|
+
|
|
2210
|
+
.transfer-line__date-picker {
|
|
2211
|
+
height: 2.75rem;
|
|
2212
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { IconBaseProps } from './registry';
|
|
3
|
+
|
|
4
|
+
const BadgeAlertIcon: React.FC<IconBaseProps> = ({
|
|
5
|
+
size = 'md',
|
|
6
|
+
className = '',
|
|
7
|
+
color,
|
|
8
|
+
}) => {
|
|
9
|
+
const getSizeClasses = () => {
|
|
10
|
+
switch (size) {
|
|
11
|
+
case 'xs':
|
|
12
|
+
return 'w-3 h-3';
|
|
13
|
+
case 'sm':
|
|
14
|
+
return 'w-4 h-4';
|
|
15
|
+
case 'md':
|
|
16
|
+
return 'w-5 h-5';
|
|
17
|
+
case 'lg':
|
|
18
|
+
return 'w-6 h-6';
|
|
19
|
+
case 'xl':
|
|
20
|
+
return 'w-8 h-8';
|
|
21
|
+
default:
|
|
22
|
+
return 'w-5 h-5';
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const sizeClasses = getSizeClasses();
|
|
27
|
+
const colorClass = color ? `text-${color}` : 'text-current';
|
|
28
|
+
const classes = `${sizeClasses} ${colorClass} ${className}`;
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<svg
|
|
32
|
+
className={classes}
|
|
33
|
+
viewBox="0 0 24 24"
|
|
34
|
+
fill="none"
|
|
35
|
+
xmlns="http://www.w3.org/2000/svg">
|
|
36
|
+
<path
|
|
37
|
+
d="M20.9951 11.9999C20.9951 11.4964 20.8687 11.0011 20.627 10.5594C20.3851 10.1177 20.0356 9.74382 19.6113 9.47253C19.2569 9.24585 19.0826 8.82151 19.1748 8.41101C19.2858 7.91752 19.2696 7.40367 19.1289 6.91785C18.9881 6.43206 18.7267 5.98941 18.3691 5.63171C18.0114 5.27399 17.5689 5.01184 17.083 4.87097C16.5971 4.73014 16.0834 4.71511 15.5898 4.82605C15.1792 4.91837 14.7541 4.74315 14.5273 4.38855C14.2561 3.96443 13.883 3.61473 13.4414 3.37292C12.9997 3.13107 12.5036 3.00476 12 3.00476C11.4966 3.00479 11.0011 3.13121 10.5596 3.37292C10.1179 3.61477 9.74393 3.96431 9.47266 4.38855C9.24605 4.74296 8.82161 4.91808 8.41113 4.82605C7.91838 4.71561 7.40595 4.7315 6.9209 4.87195C6.43573 5.01246 5.99328 5.27297 5.63574 5.62976C5.27833 5.98651 5.01649 6.4282 4.875 6.91296C4.73362 7.39766 4.71677 7.9103 4.82617 8.4032C4.91754 8.81478 4.74102 9.23926 4.38477 9.46472C3.95737 9.73521 3.60534 10.1096 3.36133 10.5526C3.11732 10.9958 2.98927 11.494 2.98926 11.9999C2.98926 12.5058 3.1173 13.0039 3.36133 13.4471C3.60533 13.8902 3.95736 14.2645 4.38477 14.535C4.741 14.7605 4.9175 15.185 4.82617 15.5966C4.7167 16.0897 4.73347 16.6029 4.875 17.0878C5.0165 17.5724 5.27844 18.0133 5.63574 18.37C5.99328 18.7268 6.43573 18.9883 6.9209 19.1288C7.40583 19.2692 7.9185 19.2851 8.41113 19.1747L8.56543 19.1522C8.9255 19.1287 9.27556 19.3019 9.47363 19.6132C9.74456 20.0391 10.1191 20.3898 10.5615 20.6327C11.0039 20.8755 11.5003 21.0028 12.0049 21.0028C12.5097 21.0028 13.0068 20.8756 13.4492 20.6327C13.8916 20.3898 14.2652 20.039 14.5361 19.6132C14.7619 19.2582 15.186 19.0826 15.5967 19.1737C16.0898 19.2832 16.603 19.2664 17.0879 19.1249C17.5727 18.9833 18.0144 18.7216 18.3711 18.3641C18.7277 18.0067 18.9884 17.5649 19.1289 17.08C19.2694 16.5948 19.2853 16.0816 19.1748 15.5887C19.0828 15.1783 19.2569 14.7538 19.6113 14.5272C20.0356 14.2559 20.3851 13.882 20.627 13.4403C20.8687 12.9987 20.9951 12.5033 20.9951 11.9999ZM12.0098 14.9999C12.562 14.9999 13.0097 15.4476 13.0098 15.9999C13.0098 16.5522 12.5621 16.9999 12.0098 16.9999H12C11.4478 16.9998 11 16.5521 11 15.9999C11.0001 15.4477 11.4478 15 12 14.9999H12.0098ZM11 11.9999V7.99988C11.0001 7.4477 11.4478 6.99998 12 6.99988C12.5523 6.99988 12.9999 7.44764 13 7.99988V11.9999C13 12.5522 12.5523 12.9999 12 12.9999C11.4478 12.9998 11 12.5521 11 11.9999ZM22.9951 11.9999C22.9951 12.8392 22.784 13.6651 22.3809 14.4012C22.0854 14.9408 21.693 15.4182 21.2266 15.8134C21.2796 16.4247 21.2215 17.0425 21.0498 17.6356C20.8156 18.4442 20.3808 19.1813 19.7861 19.7772C19.1916 20.3729 18.4563 20.8089 17.6484 21.0448C17.0557 21.2178 16.4377 21.2771 15.8262 21.2255C15.4308 21.6943 14.952 22.0886 14.4111 22.3856C13.6738 22.7904 12.8461 23.0028 12.0049 23.0028C11.1637 23.0028 10.336 22.7905 9.59863 22.3856C9.0581 22.0888 8.57976 21.6949 8.18457 21.2264C7.57382 21.2791 6.95675 21.2213 6.36426 21.0497C5.55569 20.8155 4.81951 20.3806 4.22363 19.786C3.62782 19.1914 3.19098 18.4563 2.95508 17.6483C2.78217 17.0559 2.72194 16.4381 2.77344 15.827C2.30313 15.4318 1.90751 14.9525 1.60938 14.411C1.20278 13.6724 0.989258 12.843 0.989258 11.9999C0.989274 11.1567 1.20274 10.3274 1.60938 9.58875C1.90763 9.04703 2.30287 8.56704 2.77344 8.17175C2.72212 7.56114 2.78236 6.94431 2.95508 6.35242C3.19096 5.54429 3.62773 4.8084 4.22363 4.21375C4.81949 3.6192 5.55574 3.18423 6.36426 2.95007C6.95732 2.77833 7.57519 2.71939 8.18652 2.77234C8.5816 2.30622 9.05938 1.9143 9.59863 1.61902C10.3348 1.21596 11.1608 1.00479 12 1.00476C12.8393 1.00476 13.6652 1.21598 14.4014 1.61902C14.9406 1.91427 15.4184 2.30626 15.8135 2.77234C16.4261 2.71894 17.0453 2.7778 17.6396 2.95007C18.4495 3.18481 19.187 3.62049 19.7832 4.21667C20.3794 4.81285 20.815 5.55046 21.0498 6.36023C21.2221 6.9545 21.2799 7.57382 21.2266 8.1864C21.693 8.58158 22.0854 9.05901 22.3809 9.59851C22.7839 10.3347 22.9951 11.1606 22.9951 11.9999Z"
|
|
38
|
+
fill="currentColor"
|
|
39
|
+
/>
|
|
40
|
+
</svg>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default BadgeAlertIcon;
|
|
@@ -5,6 +5,7 @@ import AirIcon from './AirIcon';
|
|
|
5
5
|
import ArrivalIcon from './ArrivalIcon';
|
|
6
6
|
import ArrowDownOutlineIcon from './ArrowDownOutlineIcon';
|
|
7
7
|
import ArrowRightOutlineIcon from './ArrowRightOutlineIcon';
|
|
8
|
+
import BadgeAlertIcon from './BadgeAlertIcon';
|
|
8
9
|
import BikeIcon from './BikeIcon';
|
|
9
10
|
import BookingIcon from './BookingIcon';
|
|
10
11
|
import Building2OutlineIcon from './Building2OutlineIcon';
|
|
@@ -102,6 +103,7 @@ export const ICONS = {
|
|
|
102
103
|
'plane-takeoff-outline': PlaneTakeoffOutlineIcon as unknown as IconComponent,
|
|
103
104
|
'plane-landing-outline': PlaneLandingOutlineIcon as unknown as IconComponent,
|
|
104
105
|
'building-2-outline': Building2OutlineIcon as unknown as IconComponent,
|
|
106
|
+
'badge-alert': BadgeAlertIcon as unknown as IconComponent,
|
|
105
107
|
arrival: ArrivalIcon as unknown as IconComponent,
|
|
106
108
|
departure: DepartureIcon as unknown as IconComponent,
|
|
107
109
|
'map-pin': MapPinIcon as unknown as IconComponent,
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { differenceInDays } from 'date-fns';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import '../../../styles/components/molecule/accomodation-docket.css';
|
|
3
4
|
import { AccomodationDocket as AccomodationDocketType } from '../../../types/docket/services.types';
|
|
5
|
+
import Button from '../../atoms/Button/Button';
|
|
4
6
|
import Chip from '../../atoms/Chip/Chip';
|
|
5
7
|
import Icon from '../../atoms/Icon/Icon';
|
|
6
8
|
import { Text } from '../../atoms/Typography/Typography';
|
|
7
9
|
import { DateDisplay } from '../DateDisplay/DateDisplay';
|
|
8
10
|
import TextWithIcon from '../TextWithIcon/TextWithIcon';
|
|
9
|
-
import '../../../styles/components/molecule/accomodation-docket.css';
|
|
10
11
|
|
|
11
12
|
export interface AccomodationDocketProps {
|
|
12
13
|
data: AccomodationDocketType;
|
|
14
|
+
/** Remove mode - replaces price chip with remove button */
|
|
15
|
+
removeMode?: boolean;
|
|
16
|
+
/** Handler for remove button click */
|
|
17
|
+
onRemove?: () => void;
|
|
13
18
|
}
|
|
14
19
|
|
|
15
20
|
const clientTypeMap: Record<string, string> = {
|
|
@@ -19,7 +24,11 @@ const clientTypeMap: Record<string, string> = {
|
|
|
19
24
|
vvip: 'VVIP',
|
|
20
25
|
};
|
|
21
26
|
|
|
22
|
-
export const AccomodationDocket: React.FC<AccomodationDocketProps> = ({
|
|
27
|
+
export const AccomodationDocket: React.FC<AccomodationDocketProps> = ({
|
|
28
|
+
data,
|
|
29
|
+
removeMode = false,
|
|
30
|
+
onRemove,
|
|
31
|
+
}) => {
|
|
23
32
|
const { HotelName, TitleDescription, Total, Currency, Dates, Rooms } = data;
|
|
24
33
|
|
|
25
34
|
const calculateNights = (dates: string[]): number => {
|
|
@@ -196,10 +205,21 @@ export const AccomodationDocket: React.FC<AccomodationDocketProps> = ({ data })
|
|
|
196
205
|
Accommodation
|
|
197
206
|
</Text>
|
|
198
207
|
</div>
|
|
199
|
-
{
|
|
200
|
-
<
|
|
201
|
-
|
|
202
|
-
|
|
208
|
+
{removeMode ? (
|
|
209
|
+
<Button
|
|
210
|
+
variant="destructive"
|
|
211
|
+
size="sm"
|
|
212
|
+
leadingIcon="close"
|
|
213
|
+
onClick={onRemove}
|
|
214
|
+
className="accomodation-docket__remove-button">
|
|
215
|
+
Remove
|
|
216
|
+
</Button>
|
|
217
|
+
) : (
|
|
218
|
+
Total && Currency && (
|
|
219
|
+
<Chip type="filled" color="accent" size="sm">
|
|
220
|
+
{Currency} {Total}
|
|
221
|
+
</Chip>
|
|
222
|
+
)
|
|
203
223
|
)}
|
|
204
224
|
</div>
|
|
205
225
|
|
|
@@ -101,9 +101,11 @@ const CalendarInput: React.FC<CalendarInputProps> = ({
|
|
|
101
101
|
</button>
|
|
102
102
|
);
|
|
103
103
|
|
|
104
|
+
const isEmpty = !localValue;
|
|
105
|
+
|
|
104
106
|
return (
|
|
105
107
|
<div
|
|
106
|
-
className={`calendar-input calendar-input--${displayState} calendar-input--icon-${iconPosition} ${className}`.trim()}
|
|
108
|
+
className={`calendar-input calendar-input--${displayState} calendar-input--icon-${iconPosition} ${isEmpty ? 'calendar-input--empty' : ''} ${className}`.trim()}
|
|
107
109
|
data-node-id="3425:11289"
|
|
108
110
|
onClick={onClick}>
|
|
109
111
|
{iconPosition === 'left' && iconButton}
|
|
@@ -113,13 +115,14 @@ const CalendarInput: React.FC<CalendarInputProps> = ({
|
|
|
113
115
|
type="text"
|
|
114
116
|
className="calendar-input__field"
|
|
115
117
|
placeholder={placeholder}
|
|
116
|
-
value={localValue
|
|
118
|
+
value={localValue}
|
|
117
119
|
disabled={disabled}
|
|
118
120
|
onChange={handleInputChange}
|
|
119
121
|
onFocus={handleFocus}
|
|
120
122
|
onBlur={handleBlur}
|
|
121
123
|
readOnly={true}
|
|
122
124
|
aria-label={'Select date'}
|
|
125
|
+
data-empty={!localValue}
|
|
123
126
|
/>
|
|
124
127
|
{iconPosition === 'left' && showChevron && (
|
|
125
128
|
<div
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import '../../../styles/components/molecule/excursion-docket.css';
|
|
3
3
|
import { ExcursionDocket as ExcursionDocketType } from '../../../types/docket/services.types';
|
|
4
|
+
import Button from '../../atoms/Button/Button';
|
|
4
5
|
import Chip from '../../atoms/Chip/Chip';
|
|
5
6
|
import Icon from '../../atoms/Icon/Icon';
|
|
6
7
|
import { Text } from '../../atoms/Typography/Typography';
|
|
@@ -9,9 +10,17 @@ import TextWithIcon from '../TextWithIcon/TextWithIcon';
|
|
|
9
10
|
|
|
10
11
|
export interface ExcursionDocketProps {
|
|
11
12
|
data: ExcursionDocketType;
|
|
13
|
+
/** Remove mode - replaces price chip with remove button */
|
|
14
|
+
removeMode?: boolean;
|
|
15
|
+
/** Handler for remove button click */
|
|
16
|
+
onRemove?: () => void;
|
|
12
17
|
}
|
|
13
18
|
|
|
14
|
-
export const ExcursionDocket: React.FC<ExcursionDocketProps> = ({
|
|
19
|
+
export const ExcursionDocket: React.FC<ExcursionDocketProps> = ({
|
|
20
|
+
data,
|
|
21
|
+
removeMode = false,
|
|
22
|
+
onRemove,
|
|
23
|
+
}) => {
|
|
15
24
|
const {
|
|
16
25
|
ExcursionName,
|
|
17
26
|
ServiceDate,
|
|
@@ -44,10 +53,21 @@ export const ExcursionDocket: React.FC<ExcursionDocketProps> = ({ data }) => {
|
|
|
44
53
|
Excursion
|
|
45
54
|
</Text>
|
|
46
55
|
</div>
|
|
47
|
-
{
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
{removeMode ? (
|
|
57
|
+
<Button
|
|
58
|
+
variant="destructive"
|
|
59
|
+
size="sm"
|
|
60
|
+
leadingIcon="close"
|
|
61
|
+
onClick={onRemove}
|
|
62
|
+
className="excursion-docket__remove-button">
|
|
63
|
+
Remove
|
|
64
|
+
</Button>
|
|
65
|
+
) : (
|
|
66
|
+
TotalPrice && Currency && (
|
|
67
|
+
<Chip type="filled" color="accent" size="sm">
|
|
68
|
+
{formatPrice()}
|
|
69
|
+
</Chip>
|
|
70
|
+
)
|
|
51
71
|
)}
|
|
52
72
|
</div>
|
|
53
73
|
|
|
@@ -2,6 +2,7 @@ import React, { useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import '../../../styles/components/molecule/location-dropdown.css';
|
|
3
3
|
import Icon from '../../atoms/Icon/Icon';
|
|
4
4
|
import { Text } from '../../atoms/Typography/Typography';
|
|
5
|
+
import { scrollIntoViewOnOpen } from '../../../lib/utils';
|
|
5
6
|
|
|
6
7
|
export interface LocationOption {
|
|
7
8
|
id: string | number;
|
|
@@ -36,6 +37,8 @@ export interface LocationDropdownProps {
|
|
|
36
37
|
maxHeight?: number;
|
|
37
38
|
direction?: 'pickup' | 'dropoff';
|
|
38
39
|
showGroupTitles?: boolean;
|
|
40
|
+
/** Whether to scroll to the input when the dropdown opens */
|
|
41
|
+
scrollOnOpen?: boolean;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
const LocationDropdown: React.FC<LocationDropdownProps> = ({
|
|
@@ -53,9 +56,11 @@ const LocationDropdown: React.FC<LocationDropdownProps> = ({
|
|
|
53
56
|
maxHeight = 240,
|
|
54
57
|
direction = undefined,
|
|
55
58
|
showGroupTitles = true,
|
|
59
|
+
scrollOnOpen = false,
|
|
56
60
|
}) => {
|
|
57
61
|
const [isOpen, setIsOpen] = useState(false);
|
|
58
62
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
63
|
+
const inputRef = useRef<HTMLDivElement>(null);
|
|
59
64
|
|
|
60
65
|
// Close dropdown when clicking outside
|
|
61
66
|
useEffect(() => {
|
|
@@ -71,6 +76,11 @@ const LocationDropdown: React.FC<LocationDropdownProps> = ({
|
|
|
71
76
|
};
|
|
72
77
|
}, []);
|
|
73
78
|
|
|
79
|
+
// Scroll to input when dropdown opens (if scrollOnOpen is true)
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
scrollIntoViewOnOpen(inputRef, isOpen, scrollOnOpen);
|
|
82
|
+
}, [isOpen, scrollOnOpen]);
|
|
83
|
+
|
|
74
84
|
const handleToggleDropdown = () => {
|
|
75
85
|
if (!disabled) {
|
|
76
86
|
setIsOpen(!isOpen);
|
|
@@ -189,6 +199,7 @@ const LocationDropdown: React.FC<LocationDropdownProps> = ({
|
|
|
189
199
|
)}
|
|
190
200
|
|
|
191
201
|
<div
|
|
202
|
+
ref={inputRef}
|
|
192
203
|
className={`location-dropdown__input location-dropdown__input--${getDropdownState()}`}
|
|
193
204
|
onClick={handleToggleDropdown}>
|
|
194
205
|
<div className="location-dropdown__input-content">
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import '../../../styles/components/molecule/other-service-docket.css';
|
|
3
3
|
import { OtherServiceDocket as OtherServiceDocketType } from '../../../types/docket/services.types';
|
|
4
|
+
import Button from '../../atoms/Button/Button';
|
|
4
5
|
import Chip from '../../atoms/Chip/Chip';
|
|
5
6
|
import Icon from '../../atoms/Icon/Icon';
|
|
6
7
|
import { Text } from '../../atoms/Typography/Typography';
|
|
@@ -8,9 +9,17 @@ import TextWithIcon from '../TextWithIcon/TextWithIcon';
|
|
|
8
9
|
|
|
9
10
|
export interface OtherServiceDocketProps {
|
|
10
11
|
data: OtherServiceDocketType;
|
|
12
|
+
/** Remove mode - replaces price chip with remove button */
|
|
13
|
+
removeMode?: boolean;
|
|
14
|
+
/** Handler for remove button click */
|
|
15
|
+
onRemove?: () => void;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
|
-
export const OtherServiceDocket: React.FC<OtherServiceDocketProps> = ({
|
|
18
|
+
export const OtherServiceDocket: React.FC<OtherServiceDocketProps> = ({
|
|
19
|
+
data,
|
|
20
|
+
removeMode = false,
|
|
21
|
+
onRemove,
|
|
22
|
+
}) => {
|
|
14
23
|
const { service_for, Currency, TotalPrice, AdultCount } = data;
|
|
15
24
|
|
|
16
25
|
const formatPrice = () => {
|
|
@@ -29,10 +38,21 @@ export const OtherServiceDocket: React.FC<OtherServiceDocketProps> = ({ data })
|
|
|
29
38
|
Other services
|
|
30
39
|
</Text>
|
|
31
40
|
</div>
|
|
32
|
-
{
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
{removeMode ? (
|
|
42
|
+
<Button
|
|
43
|
+
variant="destructive"
|
|
44
|
+
size="sm"
|
|
45
|
+
leadingIcon="close"
|
|
46
|
+
onClick={onRemove}
|
|
47
|
+
className="other-service-docket__remove-button">
|
|
48
|
+
Remove
|
|
49
|
+
</Button>
|
|
50
|
+
) : (
|
|
51
|
+
TotalPrice && Currency && (
|
|
52
|
+
<Chip type="filled" color="accent" size="sm">
|
|
53
|
+
{formatPrice()}
|
|
54
|
+
</Chip>
|
|
55
|
+
)
|
|
36
56
|
)}
|
|
37
57
|
</div>
|
|
38
58
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import '../../../styles/components/molecule/toast.css';
|
|
3
|
+
import Icon from '../../atoms/Icon/Icon';
|
|
4
|
+
import { ICONS } from '../../atoms/Icon/icons/registry';
|
|
5
|
+
import { Text } from '../../atoms/Typography/Typography';
|
|
6
|
+
|
|
7
|
+
export type ToastType = 'informational' | 'success' | 'warning' | 'danger';
|
|
8
|
+
|
|
9
|
+
export interface ToastProps {
|
|
10
|
+
/** Toast message text */
|
|
11
|
+
text: string;
|
|
12
|
+
/** Type of toast: informational, success, warning, or danger */
|
|
13
|
+
type?: ToastType;
|
|
14
|
+
/** Additional CSS classes */
|
|
15
|
+
className?: string;
|
|
16
|
+
/** Icon name */
|
|
17
|
+
iconName?: keyof typeof ICONS;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Toast component - A brief, auto-dismissing message that appears to notify the user.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* <Toast text="Please save your quotation" type="warning" />
|
|
25
|
+
*
|
|
26
|
+
* @param ToastProps
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
const Toast: React.FC<ToastProps> = ({ text, type = 'informational', className = '', iconName = 'badge-alert' }) => {
|
|
30
|
+
return (
|
|
31
|
+
<div className={`toast toast--${type} ${className}`.trim()}>
|
|
32
|
+
<div className="toast__container">
|
|
33
|
+
<div className="toast__icon-wrapper">
|
|
34
|
+
<Icon name={iconName} size="md" className="toast__icon" />
|
|
35
|
+
</div>
|
|
36
|
+
<Text
|
|
37
|
+
size="sm"
|
|
38
|
+
variant="bold"
|
|
39
|
+
leading="5"
|
|
40
|
+
className="toast__text">
|
|
41
|
+
{text}
|
|
42
|
+
</Text>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export default Toast;
|
|
49
|
+
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { TransferDocket as TransferDocketType } from '../../../types/docket/services.types';
|
|
3
|
+
import Button from '../../atoms/Button/Button';
|
|
3
4
|
import Icon from '../../atoms/Icon/Icon';
|
|
4
5
|
import { Text } from '../../atoms/Typography/Typography';
|
|
5
6
|
import { DateDisplay } from '../DateDisplay/DateDisplay';
|
|
@@ -9,9 +10,17 @@ import '../../../styles/components/molecule/transfer-docket.css';
|
|
|
9
10
|
|
|
10
11
|
export interface TransferDocketProps {
|
|
11
12
|
data: TransferDocketType;
|
|
13
|
+
/** Remove mode - replaces price display with remove button */
|
|
14
|
+
removeMode?: boolean;
|
|
15
|
+
/** Handler for remove button click */
|
|
16
|
+
onRemove?: () => void;
|
|
12
17
|
}
|
|
13
18
|
|
|
14
|
-
export const TransferDocket: React.FC<TransferDocketProps> = ({
|
|
19
|
+
export const TransferDocket: React.FC<TransferDocketProps> = ({
|
|
20
|
+
data,
|
|
21
|
+
removeMode = false,
|
|
22
|
+
onRemove,
|
|
23
|
+
}) => {
|
|
15
24
|
const {
|
|
16
25
|
TransferDate,
|
|
17
26
|
Currency,
|
|
@@ -97,8 +106,17 @@ export const TransferDocket: React.FC<TransferDocketProps> = ({ data }) => {
|
|
|
97
106
|
Transfer
|
|
98
107
|
</Text>
|
|
99
108
|
</div>
|
|
100
|
-
{
|
|
101
|
-
<
|
|
109
|
+
{removeMode ? (
|
|
110
|
+
<Button
|
|
111
|
+
variant="destructive"
|
|
112
|
+
size="sm"
|
|
113
|
+
leadingIcon="close"
|
|
114
|
+
onClick={onRemove}
|
|
115
|
+
className="transfer-docket__remove-button">
|
|
116
|
+
Remove
|
|
117
|
+
</Button>
|
|
118
|
+
) : (
|
|
119
|
+
TotalPrice && Currency && <PriceDisplay currency={Currency} price={TotalPrice} />
|
|
102
120
|
)}
|
|
103
121
|
</div>
|
|
104
122
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
.car-booking-card--hover,
|
|
20
|
-
.car-booking-card:hover {
|
|
20
|
+
.car-booking-card:hover:not(.car-booking-card--readonly) {
|
|
21
21
|
/* Will be fine-tuned when we inspect Figma Hover variant */
|
|
22
22
|
box-shadow:
|
|
23
23
|
var(--spacing-base-0, 0px) var(--spacing-base-1, 4px)
|
|
@@ -28,6 +28,18 @@
|
|
|
28
28
|
rgba(48, 54, 66, 0.18);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/* Readonly mode styles */
|
|
32
|
+
.car-booking-card--readonly .car-booking-card__supplement-value {
|
|
33
|
+
margin: 0;
|
|
34
|
+
padding: var(--spacing-padding-py-3, 12px) var(--spacing-padding-px-4, 16px);
|
|
35
|
+
border-radius: var(--border-radius-rounded-xl, 12px);
|
|
36
|
+
background: var(--color-elevation-level-1, #ffffff);
|
|
37
|
+
border: var(--input-border-width-default, 1px) solid var(--color-border-subtle, #e5e5e5);
|
|
38
|
+
min-height: 44px; /* Match input field height */
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
}
|
|
42
|
+
|
|
31
43
|
/* NOTE: Figma Selected keeps the same white surface; selection is expressed via CTA + active divider */
|
|
32
44
|
|
|
33
45
|
.car-booking-card__image-wrap {
|
|
@@ -58,6 +58,9 @@ export interface CarBookingCardProps {
|
|
|
58
58
|
ctaButtonProps?: Omit<ButtonProps, 'children'>;
|
|
59
59
|
onCtaClick?: ButtonProps['onClick'];
|
|
60
60
|
|
|
61
|
+
/** Readonly mode - disables interactions and shows values as text */
|
|
62
|
+
readonly?: boolean;
|
|
63
|
+
|
|
61
64
|
className?: string;
|
|
62
65
|
}
|
|
63
66
|
|
|
@@ -84,6 +87,7 @@ const CarBookingCard: React.FC<CarBookingCardProps> = ({
|
|
|
84
87
|
ctaLabel,
|
|
85
88
|
ctaButtonProps,
|
|
86
89
|
onCtaClick,
|
|
90
|
+
readonly = false,
|
|
87
91
|
className = '',
|
|
88
92
|
}) => {
|
|
89
93
|
const resolvedShowSupplement =
|
|
@@ -97,6 +101,7 @@ const CarBookingCard: React.FC<CarBookingCardProps> = ({
|
|
|
97
101
|
`${baseClass}--${size}`,
|
|
98
102
|
`${baseClass}--${state}`,
|
|
99
103
|
`${baseClass}--${type}`,
|
|
104
|
+
readonly ? `${baseClass}--readonly` : '',
|
|
100
105
|
className,
|
|
101
106
|
]
|
|
102
107
|
.filter(Boolean)
|
|
@@ -111,7 +116,7 @@ const CarBookingCard: React.FC<CarBookingCardProps> = ({
|
|
|
111
116
|
<div className="car-booking-card__active-divider" />
|
|
112
117
|
|
|
113
118
|
<div className="car-booking-card__body">
|
|
114
|
-
{priceRows.length > 0 && (
|
|
119
|
+
{priceRows.length > 0 && !readonly && (
|
|
115
120
|
<section className="car-booking-card__section car-booking-card__section--price">
|
|
116
121
|
<Divider variant="dashed" className="car-booking-card__dashed-divider" />
|
|
117
122
|
<div className="car-booking-card__price-content">
|
|
@@ -160,7 +165,7 @@ const CarBookingCard: React.FC<CarBookingCardProps> = ({
|
|
|
160
165
|
))}
|
|
161
166
|
</div>
|
|
162
167
|
|
|
163
|
-
{infoText && (
|
|
168
|
+
{infoText && !readonly && (
|
|
164
169
|
<div className="car-booking-card__info">
|
|
165
170
|
<span className="car-booking-card__info-icon" aria-hidden="true">
|
|
166
171
|
i
|
|
@@ -172,7 +177,7 @@ const CarBookingCard: React.FC<CarBookingCardProps> = ({
|
|
|
172
177
|
)}
|
|
173
178
|
</section>
|
|
174
179
|
|
|
175
|
-
{resolvedShowSupplement && (
|
|
180
|
+
{resolvedShowSupplement && !readonly && (
|
|
176
181
|
<section className="car-booking-card__section car-booking-card__section--supplement">
|
|
177
182
|
<Divider variant="dashed" className="car-booking-card__dashed-divider" />
|
|
178
183
|
<div className="car-booking-card__supplement-header">
|
|
@@ -198,17 +203,29 @@ const CarBookingCard: React.FC<CarBookingCardProps> = ({
|
|
|
198
203
|
</Text>
|
|
199
204
|
)}
|
|
200
205
|
</div>
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
{readonly ? (
|
|
207
|
+
<Text
|
|
208
|
+
size="sm"
|
|
209
|
+
leading="5"
|
|
210
|
+
variant="regular"
|
|
211
|
+
color={supplementValue ? "default" : "subtle"}
|
|
212
|
+
className="car-booking-card__supplement-value"
|
|
213
|
+
>
|
|
214
|
+
{supplementValue || supplementPlaceholder}
|
|
215
|
+
</Text>
|
|
216
|
+
) : (
|
|
217
|
+
<DropdownInput
|
|
218
|
+
placeholder={supplementPlaceholder}
|
|
219
|
+
value={supplementValue}
|
|
220
|
+
state={resolvedSupplementState}
|
|
221
|
+
options={supplementOptions}
|
|
222
|
+
onSelect={onSupplementSelect}
|
|
223
|
+
/>
|
|
224
|
+
)}
|
|
208
225
|
</section>
|
|
209
226
|
)}
|
|
210
227
|
|
|
211
|
-
<footer className="car-booking-card__footer">
|
|
228
|
+
{!readonly && <footer className="car-booking-card__footer">
|
|
212
229
|
<div className="car-booking-card__total">
|
|
213
230
|
<Text size="sm" variant="bold" color="accent" className="car-booking-card__total-price">
|
|
214
231
|
{totalPrice}
|
|
@@ -218,16 +235,18 @@ const CarBookingCard: React.FC<CarBookingCardProps> = ({
|
|
|
218
235
|
</Text>
|
|
219
236
|
</div>
|
|
220
237
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
238
|
+
{!readonly && (
|
|
239
|
+
<Button
|
|
240
|
+
variant="primary"
|
|
241
|
+
size="sm"
|
|
242
|
+
{...ctaButtonProps}
|
|
243
|
+
onClick={onCtaClick}
|
|
244
|
+
className={`car-booking-card__cta ${ctaButtonProps?.className ?? ''}`.trim()}
|
|
245
|
+
>
|
|
246
|
+
{ctaLabel}
|
|
247
|
+
</Button>
|
|
248
|
+
)}
|
|
249
|
+
</footer>}
|
|
231
250
|
</div>
|
|
232
251
|
</article>
|
|
233
252
|
);
|