mautourco-components 0.2.85 → 0.2.87
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/molecules/LocationDropdown/LocationDropdown.d.ts +2 -0
- package/dist/components/molecules/LocationDropdown/LocationDropdown.js +30 -17
- package/dist/components/molecules/TransferDocket/TransferDocket.js +1 -1
- package/dist/components/molecules/VehicleSupplement/VehicleSupplement.js +3 -0
- package/dist/components/organisms/RoundTrip/RoundTrip.d.ts +12 -12
- package/dist/components/organisms/RoundTrip/RoundTrip.js +77 -24
- package/dist/components/organisms/SearchBarTransfer/SearchBarTransfer.js +8 -12
- package/dist/components/organisms/SearchBarTransfer/index.d.ts +1 -1
- package/dist/components/organisms/TransferLine/TransferLine.d.ts +10 -10
- package/dist/components/organisms/TransferLine/TransferLine.js +82 -33
- package/package.json +1 -1
- package/src/components/molecules/LocationDropdown/LocationDropdown.tsx +31 -13
- package/src/components/molecules/TransferDocket/TransferDocket.tsx +1 -1
- package/src/components/molecules/VehicleSupplement/VehicleSupplement.tsx +3 -0
- package/src/components/organisms/RoundTrip/RoundTrip.tsx +99 -37
- package/src/components/organisms/SearchBarTransfer/SearchBarTransfer.tsx +4 -4
- package/src/components/organisms/SearchBarTransfer/index.ts +1 -1
- package/src/components/organisms/TransferLine/TransferLine.tsx +101 -43
|
@@ -32,6 +32,8 @@ export interface LocationDropdownProps {
|
|
|
32
32
|
showGroupTitles?: boolean;
|
|
33
33
|
/** Whether to scroll to the input when the dropdown opens */
|
|
34
34
|
scrollOnOpen?: boolean;
|
|
35
|
+
/** Default location option to use when no value is selected */
|
|
36
|
+
defaultValue?: LocationOption;
|
|
35
37
|
}
|
|
36
38
|
declare const LocationDropdown: React.FC<LocationDropdownProps>;
|
|
37
39
|
export default LocationDropdown;
|
|
@@ -25,7 +25,7 @@ import '../../../styles/components/molecule/location-dropdown.css';
|
|
|
25
25
|
import Icon from '../../atoms/Icon/Icon';
|
|
26
26
|
import { Text } from '../../atoms/Typography/Typography';
|
|
27
27
|
var LocationDropdown = function (_a) {
|
|
28
|
-
var _b = _a.options, options = _b === void 0 ? [] : _b, _c = _a.groups, groups = _c === void 0 ? [] : _c, _d = _a.selectedValue, selectedValue = _d === void 0 ? null : _d, _e = _a.placeholder, placeholder = _e === void 0 ? 'Select a location' : _e, label = _a.label, onSelectionChange = _a.onSelectionChange, _f = _a.disabled, disabled = _f === void 0 ? false : _f, _g = _a.error, error = _g === void 0 ? false : _g, _h = _a.loading, loading = _h === void 0 ? false : _h, _j = _a.className, className = _j === void 0 ? '' : _j, _k = _a.type, type = _k === void 0 ? 'airport-port' : _k, _l = _a.maxHeight, maxHeight = _l === void 0 ? 240 : _l, _m = _a.direction, direction = _m === void 0 ? undefined : _m, _o = _a.showGroupTitles, showGroupTitles = _o === void 0 ? true : _o, _p = _a.scrollOnOpen, scrollOnOpen = _p === void 0 ? false : _p;
|
|
28
|
+
var _b = _a.options, options = _b === void 0 ? [] : _b, _c = _a.groups, groups = _c === void 0 ? [] : _c, _d = _a.selectedValue, selectedValue = _d === void 0 ? null : _d, _e = _a.placeholder, placeholder = _e === void 0 ? 'Select a location' : _e, label = _a.label, onSelectionChange = _a.onSelectionChange, _f = _a.disabled, disabled = _f === void 0 ? false : _f, _g = _a.error, error = _g === void 0 ? false : _g, _h = _a.loading, loading = _h === void 0 ? false : _h, _j = _a.className, className = _j === void 0 ? '' : _j, _k = _a.type, type = _k === void 0 ? 'airport-port' : _k, _l = _a.maxHeight, maxHeight = _l === void 0 ? 240 : _l, _m = _a.direction, direction = _m === void 0 ? undefined : _m, _o = _a.showGroupTitles, showGroupTitles = _o === void 0 ? true : _o, _p = _a.scrollOnOpen, scrollOnOpen = _p === void 0 ? false : _p, defaultValue = _a.defaultValue;
|
|
29
29
|
var _q = useState(false), isOpen = _q[0], setIsOpen = _q[1];
|
|
30
30
|
var _r = useState(''), searchQuery = _r[0], setSearchQuery = _r[1];
|
|
31
31
|
var dropdownRef = useRef(null);
|
|
@@ -53,6 +53,17 @@ var LocationDropdown = function (_a) {
|
|
|
53
53
|
setSearchQuery('');
|
|
54
54
|
}
|
|
55
55
|
}, [isOpen]);
|
|
56
|
+
// Initialize default value if provided and no selected value
|
|
57
|
+
useEffect(function () {
|
|
58
|
+
if (!selectedValue && defaultValue && !disabled) {
|
|
59
|
+
var defaultLocationData = {
|
|
60
|
+
id: defaultValue.id,
|
|
61
|
+
locationName: defaultValue.label,
|
|
62
|
+
};
|
|
63
|
+
onSelectionChange(defaultLocationData);
|
|
64
|
+
}
|
|
65
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66
|
+
}, [defaultValue]);
|
|
56
67
|
var handleToggleDropdown = function () {
|
|
57
68
|
if (!disabled) {
|
|
58
69
|
setIsOpen(!isOpen);
|
|
@@ -82,20 +93,21 @@ var LocationDropdown = function (_a) {
|
|
|
82
93
|
});
|
|
83
94
|
};
|
|
84
95
|
var getSelectedOption = function () {
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
if (selectedValue) {
|
|
97
|
+
// Search in flat options
|
|
98
|
+
var flatOption = options.find(function (opt) { return opt.id === selectedValue; });
|
|
99
|
+
if (flatOption)
|
|
100
|
+
return flatOption;
|
|
101
|
+
// Search in groups
|
|
102
|
+
for (var _i = 0, groups_1 = groups; _i < groups_1.length; _i++) {
|
|
103
|
+
var group = groups_1[_i];
|
|
104
|
+
var groupOption = group.options.find(function (opt) { return opt.id === selectedValue; });
|
|
105
|
+
if (groupOption)
|
|
106
|
+
return groupOption;
|
|
107
|
+
}
|
|
97
108
|
}
|
|
98
|
-
|
|
109
|
+
// Return default value if no selected value
|
|
110
|
+
return defaultValue || null;
|
|
99
111
|
};
|
|
100
112
|
var getIconForType = function (optionType) {
|
|
101
113
|
switch (optionType) {
|
|
@@ -128,6 +140,8 @@ var LocationDropdown = function (_a) {
|
|
|
128
140
|
// For other types (port, accommodation), show their specific icon
|
|
129
141
|
return getIconForType(option.type);
|
|
130
142
|
};
|
|
143
|
+
var selectedOption = getSelectedOption();
|
|
144
|
+
var effectiveSelectedValue = selectedValue || (defaultValue ? defaultValue.id : null);
|
|
131
145
|
var getDropdownState = function () {
|
|
132
146
|
if (disabled)
|
|
133
147
|
return 'disabled';
|
|
@@ -135,11 +149,10 @@ var LocationDropdown = function (_a) {
|
|
|
135
149
|
return 'error';
|
|
136
150
|
if (isOpen)
|
|
137
151
|
return 'open';
|
|
138
|
-
if (
|
|
152
|
+
if (effectiveSelectedValue)
|
|
139
153
|
return 'selected';
|
|
140
154
|
return 'default';
|
|
141
155
|
};
|
|
142
|
-
var selectedOption = getSelectedOption();
|
|
143
156
|
var displayText = selectedOption ? selectedOption.label : placeholder;
|
|
144
157
|
// Prepare all options (flat or grouped) and filter them
|
|
145
158
|
var allOptionsRaw = groups.length > 0 ? groups : [{ id: 'default', label: '', options: options }];
|
|
@@ -150,7 +163,7 @@ var LocationDropdown = function (_a) {
|
|
|
150
163
|
var renderSkeletonLoading = function () { return (_jsx("div", { className: "location-dropdown__panel", children: _jsx("div", { className: "location-dropdown__content", style: { maxHeight: "".concat(maxHeight, "px") }, children: _jsx("div", { className: "location-dropdown__options-wrapper", children: _jsx("div", { className: "location-dropdown__group", children: _jsx("div", { className: "location-dropdown__group-options", children: __spreadArray([], Array(5), true).map(function (_, index) { return (_jsx(SkeletonOption, {}, "skeleton-".concat(index))); }) }) }) }) }) })); };
|
|
151
164
|
return (_jsxs("div", { ref: dropdownRef, className: "location-dropdown location-dropdown--".concat(type, " ").concat(disabled ? 'location-dropdown--disabled' : '', " ").concat(className), children: [label && (_jsx("div", { className: "location-dropdown__label", children: _jsx(Text, { size: "sm", variant: "medium", children: label }) })), _jsxs("div", { ref: inputRef, className: "location-dropdown__input location-dropdown__input--".concat(getDropdownState()), onClick: handleToggleDropdown, children: [_jsxs("div", { className: "location-dropdown__input-content", children: [_jsx(Icon, { name: getInputIcon(), size: "sm", className: "location-dropdown__input-icon ".concat(!selectedOption ? 'location-dropdown__input-icon--placeholder' : '') }), isOpen ? (_jsx("input", { ref: searchInputRef, type: "text", className: "location-dropdown__input-text ".concat(!selectedOption && !searchQuery ? 'location-dropdown__input-text--placeholder' : ''), placeholder: displayText, value: searchQuery, onChange: handleSearchChange, onClick: function (e) { return e.stopPropagation(); }, disabled: disabled, autoFocus: true })) : (_jsx("span", { className: "location-dropdown__input-text ".concat(!selectedOption ? 'location-dropdown__input-text--placeholder' : ''), children: displayText }))] }), _jsx(Icon, { name: "chevron-down", size: "sm", className: "location-dropdown__input-chevron" })] }), isOpen &&
|
|
152
165
|
(loading ? (renderSkeletonLoading()) : (_jsx("div", { className: "location-dropdown__panel", children: _jsx("div", { className: "location-dropdown__content", style: { maxHeight: "".concat(maxHeight, "px") }, children: _jsx("div", { className: "location-dropdown__options-wrapper", children: allOptions.length === 0 ? (_jsx("div", { className: "location-dropdown__no-results", children: _jsx(Text, { size: "sm", variant: "medium", children: "No locations found" }) })) : (allOptions.map(function (group, groupIndex) { return (_jsxs("div", { className: "location-dropdown__group", children: [showGroupTitles && group.label && groups.length > 0 && (_jsxs(_Fragment, { children: [groupIndex > 0 && _jsx("div", { className: "location-dropdown__divider" }), _jsx("div", { className: "location-dropdown__group-header", children: _jsx(Text, { size: "xs", variant: "bold", children: group.label }) })] })), _jsx("div", { className: "location-dropdown__group-options", children: group.options.map(function (option) {
|
|
153
|
-
var isSelected =
|
|
166
|
+
var isSelected = effectiveSelectedValue === option.id;
|
|
154
167
|
var isDisabled = option.disabled || disabled;
|
|
155
168
|
return (_jsxs("div", { className: "location-dropdown__option ".concat(isSelected ? 'location-dropdown__option--selected' : '', " ").concat(isDisabled ? 'location-dropdown__option--disabled' : ''), onClick: function () { return !isDisabled && handleOptionSelect(option); }, children: [_jsx(Icon, { name: getOptionIcon(option, isSelected), size: "sm", className: "location-dropdown__option-icon" }), _jsx("span", { className: "location-dropdown__option-text", children: option.label })] }, option.id));
|
|
156
169
|
}) })] }, group.id)); })) }) }) })))] }));
|
|
@@ -46,6 +46,6 @@ export var TransferDocket = function (_a) {
|
|
|
46
46
|
}
|
|
47
47
|
return (_jsx("div", { className: "transfer-docket__children", children: childGroups.map(function (group, index) { return (_jsxs(React.Fragment, { children: [index > 0 && _jsx("div", { className: "transfer-docket__divider-vertical" }), _jsxs("span", { className: "transfer-docket__child-info", children: [_jsxs(Text, { size: "sm", variant: "medium", color: "default", children: [group.count, " Child", group.count > 1 ? 'ren' : ''] }), group.age > 0 ? (_jsxs(Text, { size: "sm", variant: "medium", className: "transfer-docket__child-age", children: [' ', "(", group.age, " y.o)"] })) : null] })] }, "child-".concat(index))); }) }));
|
|
48
48
|
};
|
|
49
|
-
return (_jsxs("div", { className: "transfer-docket", children: [_jsxs("div", { className: "transfer-docket__header", children: [_jsxs("div", { className: "transfer-docket__title-section", children: [_jsx("div", { className: "transfer-docket__title-bar" }), _jsx(Icon, { name: "bus", size: "sm" }), _jsx(Text, { variant: "bold", size: "sm", color: "accent", children: "Transfer" })] }), removeMode ? (_jsx(Button, { variant: "destructive", size: "sm", leadingIcon: "close", onClick: onRemove, className: "transfer-docket__remove-button", children: "Remove" })) : (TotalPrice && Currency && _jsx(PriceDisplay, { currency: Currency, price: TotalPrice }))] }), _jsxs("div", { className: "transfer-docket__details", children: [TransferDate && (_jsx(DateDisplay, { date: TransferDate, calendarSize: "sm", textSize: "sm", colorMode: "green" })), (LocationFromName || LocationToName) && (_jsxs("div", { className: "transfer-docket__transfer-point", children: [_jsx(Text, { variant: "medium", size: "sm", color: "subtle", leading: "none", children: LocationFromName || 'From' }), _jsx(Icon, { name: "arrow-down-outline", size: "sm" }), _jsx(Text, { variant: "medium", size: "sm", color: "subtle", leading: "none", children: LocationToName || 'To' })] })), _jsxs("div", { className: "transfer-docket__guests", children: [AdultCount !== undefined && AdultCount > 0 && (_jsxs(TextWithIcon, { icon: "user", textSize: "sm", color: "subtle", children: [AdultCount, " Adult", AdultCount > 1 ? 's' : ''] })), ((ChildCount && ChildCount > 0) || (TeenCount && TeenCount > 0)) || (InfantCount && InfantCount > 0) ? (_jsxs("div", { className: "transfer-docket__children-wrapper", children: [_jsx(Icon, { name: "user", size: "sm", color: "var(--color-text-subtle, #303642)" }), formatChildrenInfo()] })) : null] }), VehicleTypeName && (_jsx(TextWithIcon, { icon: "car", textSize: "sm", color: "subtle", textLeading: "none", children: VehicleTypeName })), showBabySeat && (_jsxs("div", { className: "transfer-docket__supplements", children: [_jsx(Text, { variant: "medium", size: "sm", color: "default", leading: "none", children: "Supplement :" }), _jsxs(TextWithIcon, { icon: "stroller", textSize: "sm", color: "subtle", children: ["Baby seat x", baby_seat_count] })] }))] })] }));
|
|
49
|
+
return (_jsxs("div", { className: "transfer-docket", children: [_jsxs("div", { className: "transfer-docket__header", children: [_jsxs("div", { className: "transfer-docket__title-section", children: [_jsx("div", { className: "transfer-docket__title-bar" }), _jsx(Icon, { name: "bus", size: "sm" }), _jsx(Text, { variant: "bold", size: "sm", color: "accent", children: "Transfer" })] }), removeMode ? (_jsx(Button, { variant: "destructive", size: "sm", leadingIcon: "close", onClick: onRemove, className: "transfer-docket__remove-button", children: "Remove" })) : (TotalPrice && Currency && _jsx(PriceDisplay, { currency: Currency, price: TotalPrice }))] }), _jsxs("div", { className: "transfer-docket__details", children: [TransferDate && (_jsx(DateDisplay, { date: TransferDate, calendarSize: "sm", textSize: "sm", colorMode: "green" })), (LocationFromName || LocationToName) && (_jsxs("div", { className: "transfer-docket__transfer-point", children: [_jsx(Text, { variant: "medium", size: "sm", color: "subtle", leading: "none", children: LocationFromName || 'From' }), _jsx(Icon, { name: "arrow-down-outline", size: "sm" }), _jsx(Text, { variant: "medium", size: "sm", color: "subtle", leading: "none", children: LocationToName || 'To' })] })), _jsxs("div", { className: "transfer-docket__guests", children: [AdultCount !== undefined && AdultCount > 0 && (_jsxs(TextWithIcon, { icon: "user", textSize: "sm", color: "subtle", children: [AdultCount, " Adult", AdultCount > 1 ? 's' : ''] })), ((ChildCount && ChildCount > 0) || (TeenCount && TeenCount > 0)) || (InfantCount && InfantCount > 0) ? (_jsxs("div", { className: "transfer-docket__children-wrapper", children: [_jsx(Icon, { name: "user", size: "sm", color: "var(--color-text-subtle, #303642)" }), formatChildrenInfo()] })) : null] }), VehicleTypeName && (_jsx(TextWithIcon, { icon: "car", textSize: "sm", color: "subtle", textLeading: "none", children: VehicleTypeName })), !!showBabySeat && (_jsxs("div", { className: "transfer-docket__supplements", children: [_jsx(Text, { variant: "medium", size: "sm", color: "default", leading: "none", children: "Supplement :" }), _jsxs(TextWithIcon, { icon: "stroller", textSize: "sm", color: "subtle", children: ["Baby seat x", baby_seat_count] })] }))] })] }));
|
|
50
50
|
};
|
|
51
51
|
export default TransferDocket;
|
|
@@ -51,6 +51,9 @@ var VehicleSupplement = function (_a) {
|
|
|
51
51
|
};
|
|
52
52
|
var getTransferTypeIcon = function (transferType) {
|
|
53
53
|
var type = transferType.toLowerCase();
|
|
54
|
+
if (type.includes('harbour')) {
|
|
55
|
+
return 'ship';
|
|
56
|
+
}
|
|
54
57
|
if (type.includes('arrival') || type.includes('airport') || type.includes('inbound')) {
|
|
55
58
|
return 'plane-landing-outline';
|
|
56
59
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import "../../../styles/components/organism/round-trip.css";
|
|
3
|
-
import {
|
|
3
|
+
import { LocationGroup, LocationOption } from "../../molecules/LocationDropdown/LocationDropdown";
|
|
4
4
|
import { PaxData } from "../PaxSelector/PaxSelector";
|
|
5
|
-
export type {
|
|
5
|
+
export type { LocationOption };
|
|
6
6
|
export interface RoundTripTransfer {
|
|
7
7
|
type: "arrival" | "departure";
|
|
8
8
|
paxData?: PaxData;
|
|
9
9
|
transferDate?: string;
|
|
10
|
-
pickupPoint?:
|
|
11
|
-
dropoffPoint?:
|
|
10
|
+
pickupPoint?: LocationOption;
|
|
11
|
+
dropoffPoint?: LocationOption;
|
|
12
12
|
}
|
|
13
13
|
export interface RoundTripData {
|
|
14
14
|
id: string;
|
|
15
15
|
paxData?: PaxData;
|
|
16
16
|
arrivalDate?: string;
|
|
17
17
|
departureDate?: string;
|
|
18
|
-
pickupDropoffPoint?:
|
|
19
|
-
accommodation?:
|
|
18
|
+
pickupDropoffPoint?: LocationOption;
|
|
19
|
+
accommodation?: LocationOption;
|
|
20
20
|
transfers: [RoundTripTransfer, RoundTripTransfer];
|
|
21
21
|
}
|
|
22
22
|
export interface RoundTripProps {
|
|
@@ -28,10 +28,10 @@ export interface RoundTripProps {
|
|
|
28
28
|
arrivalDate?: string;
|
|
29
29
|
/** Departure date */
|
|
30
30
|
departureDate?: string;
|
|
31
|
-
/** Selected pickup/dropoff point ID
|
|
32
|
-
pickupDropoffPoint?: string;
|
|
33
|
-
/** Selected accommodation ID
|
|
34
|
-
accommodation?: string;
|
|
31
|
+
/** Selected pickup/dropoff point - can be an ID string or LocationOption object */
|
|
32
|
+
pickupDropoffPoint?: string | LocationOption;
|
|
33
|
+
/** Selected accommodation - can be an ID string or LocationOption object */
|
|
34
|
+
accommodation?: string | LocationOption;
|
|
35
35
|
/** All location options */
|
|
36
36
|
locations?: {
|
|
37
37
|
options?: LocationOption[];
|
|
@@ -42,9 +42,9 @@ export interface RoundTripProps {
|
|
|
42
42
|
/** Callback when dates change */
|
|
43
43
|
onDatesChange?: (arrivalDate: string, departureDate: string) => void;
|
|
44
44
|
/** Callback when pickup/dropoff point changes */
|
|
45
|
-
onPickupDropoffChange?: (location:
|
|
45
|
+
onPickupDropoffChange?: (location: LocationOption | null) => void;
|
|
46
46
|
/** Callback when accommodation changes */
|
|
47
|
-
onAccommodationChange?: (location:
|
|
47
|
+
onAccommodationChange?: (location: LocationOption | null) => void;
|
|
48
48
|
/** Callback when any data changes - returns array of 2 transfers */
|
|
49
49
|
onChange?: (data: RoundTripData) => void;
|
|
50
50
|
/** Additional CSS classes */
|
|
@@ -75,43 +75,53 @@ var RoundTrip = function (_a) {
|
|
|
75
75
|
groups: accommodationGroups,
|
|
76
76
|
};
|
|
77
77
|
};
|
|
78
|
-
//
|
|
78
|
+
// Helper to check if value is LocationOption
|
|
79
|
+
var isLocationOption = function (value) {
|
|
80
|
+
return typeof value === 'object' && value !== null && 'id' in value && 'label' in value && 'type' in value;
|
|
81
|
+
};
|
|
82
|
+
// Initialize location data from IDs or LocationOption objects
|
|
79
83
|
useEffect(function () {
|
|
84
|
+
// If pickupDropoffPoint is already a LocationOption object, use it directly
|
|
85
|
+
if (isLocationOption(pickupDropoffPoint)) {
|
|
86
|
+
// Only update if the ID is different to prevent infinite loops
|
|
87
|
+
if ((internalPickupDropoffPoint === null || internalPickupDropoffPoint === void 0 ? void 0 : internalPickupDropoffPoint.id) !== pickupDropoffPoint.id) {
|
|
88
|
+
setInternalPickupDropoffPoint(pickupDropoffPoint);
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
80
92
|
var _a = getPickupDropoffOptions(), options = _a.options, groups = _a.groups;
|
|
81
93
|
var allLocations = getAllLocations(options, groups);
|
|
82
94
|
if (pickupDropoffPoint) {
|
|
83
95
|
var location_1 = allLocations.find(function (loc) { return loc.id === pickupDropoffPoint; });
|
|
84
|
-
if (location_1) {
|
|
85
|
-
setInternalPickupDropoffPoint(
|
|
86
|
-
id: location_1.id,
|
|
87
|
-
locationName: location_1.label,
|
|
88
|
-
});
|
|
96
|
+
if (location_1 && (internalPickupDropoffPoint === null || internalPickupDropoffPoint === void 0 ? void 0 : internalPickupDropoffPoint.id) !== location_1.id) {
|
|
97
|
+
setInternalPickupDropoffPoint(location_1);
|
|
89
98
|
}
|
|
90
99
|
}
|
|
91
|
-
else {
|
|
92
|
-
// Set default to first airport if available
|
|
100
|
+
else if (!internalPickupDropoffPoint) {
|
|
101
|
+
// Set default to first airport if available (only if not already set)
|
|
93
102
|
var defaultAirport = allLocations.find(function (loc) { return loc.type === "airport"; });
|
|
94
103
|
if (defaultAirport) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
locationName: defaultAirport.label,
|
|
98
|
-
};
|
|
99
|
-
setInternalPickupDropoffPoint(defaultData);
|
|
100
|
-
onPickupDropoffChange === null || onPickupDropoffChange === void 0 ? void 0 : onPickupDropoffChange(defaultData);
|
|
104
|
+
setInternalPickupDropoffPoint(defaultAirport);
|
|
105
|
+
onPickupDropoffChange === null || onPickupDropoffChange === void 0 ? void 0 : onPickupDropoffChange(defaultAirport);
|
|
101
106
|
}
|
|
102
107
|
}
|
|
103
108
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
104
109
|
}, [pickupDropoffPoint, locations]);
|
|
105
110
|
useEffect(function () {
|
|
111
|
+
// If accommodation is already a LocationOption object, use it directly
|
|
112
|
+
if (isLocationOption(accommodation)) {
|
|
113
|
+
// Only update if the ID is different to prevent infinite loops
|
|
114
|
+
if ((internalAccommodation === null || internalAccommodation === void 0 ? void 0 : internalAccommodation.id) !== accommodation.id) {
|
|
115
|
+
setInternalAccommodation(accommodation);
|
|
116
|
+
}
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
106
119
|
var _a = getAccommodationOptions(), options = _a.options, groups = _a.groups;
|
|
107
120
|
var allLocations = getAllLocations(options, groups);
|
|
108
121
|
if (accommodation) {
|
|
109
122
|
var location_2 = allLocations.find(function (loc) { return loc.id === accommodation; });
|
|
110
|
-
if (location_2) {
|
|
111
|
-
setInternalAccommodation(
|
|
112
|
-
id: location_2.id,
|
|
113
|
-
locationName: location_2.label,
|
|
114
|
-
});
|
|
123
|
+
if (location_2 && (internalAccommodation === null || internalAccommodation === void 0 ? void 0 : internalAccommodation.id) !== location_2.id) {
|
|
124
|
+
setInternalAccommodation(location_2);
|
|
115
125
|
}
|
|
116
126
|
}
|
|
117
127
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -164,13 +174,41 @@ var RoundTrip = function (_a) {
|
|
|
164
174
|
onDatesChange === null || onDatesChange === void 0 ? void 0 : onDatesChange(dates[0], dates[1]);
|
|
165
175
|
}
|
|
166
176
|
};
|
|
177
|
+
// Helper to convert LocationData to LocationOption
|
|
178
|
+
var toLocationOption = function (locationData, locationType) {
|
|
179
|
+
if (!locationData)
|
|
180
|
+
return null;
|
|
181
|
+
// Try to find in the options to get the type
|
|
182
|
+
var _a = locationType === 'pickup-dropoff' ? getPickupDropoffOptions() : getAccommodationOptions(), options = _a.options, groups = _a.groups;
|
|
183
|
+
var allLocations = getAllLocations(options, groups);
|
|
184
|
+
var found = allLocations.find(function (loc) { return loc.id === locationData.id; });
|
|
185
|
+
if (found)
|
|
186
|
+
return found;
|
|
187
|
+
// If not found, infer the type
|
|
188
|
+
var name = locationData.locationName.toLowerCase();
|
|
189
|
+
var id = String(locationData.id).toLowerCase();
|
|
190
|
+
var type = 'accommodation';
|
|
191
|
+
if (name.includes('harbour') || name.includes('port') || id.includes('harbour') || id.includes('port')) {
|
|
192
|
+
type = 'port';
|
|
193
|
+
}
|
|
194
|
+
else if (name.includes('airport') || id.includes('airport')) {
|
|
195
|
+
type = 'airport';
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
id: locationData.id,
|
|
199
|
+
label: locationData.locationName,
|
|
200
|
+
type: type,
|
|
201
|
+
};
|
|
202
|
+
};
|
|
167
203
|
var handlePickupDropoffChange = function (location) {
|
|
168
|
-
|
|
169
|
-
|
|
204
|
+
var locationOption = toLocationOption(location, 'pickup-dropoff');
|
|
205
|
+
setInternalPickupDropoffPoint(locationOption);
|
|
206
|
+
onPickupDropoffChange === null || onPickupDropoffChange === void 0 ? void 0 : onPickupDropoffChange(locationOption);
|
|
170
207
|
};
|
|
171
208
|
var handleAccommodationChange = function (location) {
|
|
172
|
-
|
|
173
|
-
|
|
209
|
+
var locationOption = toLocationOption(location, 'accommodation');
|
|
210
|
+
setInternalAccommodation(locationOption);
|
|
211
|
+
onAccommodationChange === null || onAccommodationChange === void 0 ? void 0 : onAccommodationChange(locationOption);
|
|
174
212
|
};
|
|
175
213
|
// Check if inputs are empty (when checkEmpty is true)
|
|
176
214
|
var isPaxEmpty = checkEmpty && (!internalPaxData ||
|
|
@@ -184,6 +222,21 @@ var RoundTrip = function (_a) {
|
|
|
184
222
|
var isAccommodationEmpty = checkEmpty && !internalAccommodation;
|
|
185
223
|
var pickupDropoffOptions = getPickupDropoffOptions();
|
|
186
224
|
var accommodationOptions = getAccommodationOptions();
|
|
187
|
-
|
|
225
|
+
// Helper function to find LocationOption from ID or LocationOption for defaultValue
|
|
226
|
+
var findLocationOption = function (value, locationType) {
|
|
227
|
+
if (!value)
|
|
228
|
+
return undefined;
|
|
229
|
+
// If value is already a LocationOption object, use it directly
|
|
230
|
+
if (isLocationOption(value)) {
|
|
231
|
+
return value;
|
|
232
|
+
}
|
|
233
|
+
// Otherwise, look up by ID in the locations
|
|
234
|
+
var _a = locationType === 'pickup-dropoff' ? getPickupDropoffOptions() : getAccommodationOptions(), options = _a.options, groups = _a.groups;
|
|
235
|
+
var allLocations = getAllLocations(options, groups);
|
|
236
|
+
return allLocations.find(function (loc) { return loc.id === value; });
|
|
237
|
+
};
|
|
238
|
+
var defaultPickupDropoffOption = findLocationOption(pickupDropoffPoint, 'pickup-dropoff');
|
|
239
|
+
var defaultAccommodationOption = findLocationOption(accommodation, 'accommodation');
|
|
240
|
+
return (_jsx("div", { className: "round-trip ".concat(className), "data-round-trip-id": id, children: _jsxs("div", { className: "round-trip__content", children: [_jsx("div", { className: "round-trip__field round-trip__field--pax ".concat(isPaxEmpty ? 'round-trip__field--error' : ''), children: _jsx(PaxSelector, { label: "Number of pax", value: internalPaxData, onChange: handlePaxChange, placeholder: "2 pax", className: isPaxEmpty ? 'pax-selector--error' : '', scrollOnOpen: scrollOnOpen, checkEmpty: checkEmpty }) }), _jsxs("div", { className: "round-trip__field round-trip__field--dates", children: [_jsx(Text, { size: "sm", variant: "regular", className: "round-trip__field-label", children: "Arrival date - Departure date" }), _jsx(DateTimePicker, { placeholder: "DD/MM/YYYY - DD/MM/YYYY", mode: "calendar", iconPosition: "left", numberOfMonths: 2, iconBGFull: false, showChevron: true, onValueChange: handleDateRangeChange, selectionMode: "range", defaultValue: internalArrivalDate && internalDepartureDate ? [internalArrivalDate, internalDepartureDate] : undefined, inputClassName: "round-trip__date-picker--input", state: isDateEmpty ? 'error' : undefined, scrollOnOpen: scrollOnOpen })] }), _jsx("div", { className: "round-trip__field round-trip__field--pickup-dropoff", children: _jsx(LocationDropdown, { label: "Pick up / Drop-off point", options: pickupDropoffOptions.options, groups: pickupDropoffOptions.groups, selectedValue: (internalPickupDropoffPoint === null || internalPickupDropoffPoint === void 0 ? void 0 : internalPickupDropoffPoint.id) || null, onSelectionChange: handlePickupDropoffChange, placeholder: "Select pick-up / drop-off point", direction: undefined, type: "airport-port", showGroupTitles: true, error: isPickupDropoffEmpty, scrollOnOpen: scrollOnOpen, defaultValue: defaultPickupDropoffOption }) }), _jsx("div", { className: "round-trip__field round-trip__field--accommodation", children: _jsx(LocationDropdown, { label: "Accommodation", options: accommodationOptions.options, groups: accommodationOptions.groups, selectedValue: (internalAccommodation === null || internalAccommodation === void 0 ? void 0 : internalAccommodation.id) || null, onSelectionChange: handleAccommodationChange, placeholder: "Select accommodation", direction: "dropoff", type: "accommodation", showGroupTitles: false, error: isAccommodationEmpty, scrollOnOpen: scrollOnOpen, defaultValue: defaultAccommodationOption }) })] }) }));
|
|
188
241
|
};
|
|
189
242
|
export default RoundTrip;
|
|
@@ -31,8 +31,7 @@ import RoundTrip from "../RoundTrip/RoundTrip";
|
|
|
31
31
|
import TransferLine from "../TransferLine/TransferLine";
|
|
32
32
|
var transferIdCounter = 0;
|
|
33
33
|
var SearchBarTransfer = function (_a) {
|
|
34
|
-
var _b, _c;
|
|
35
|
-
var _d = _a.mode, initialMode = _d === void 0 ? "roundtrip" : _d, _e = _a.locations, locations = _e === void 0 ? { options: [], groups: [] } : _e, defaultRoundTripData = _a.defaultRoundTripData, defaultTransferLines = _a.defaultTransferLines, _f = _a.defaultSameVehicle, defaultSameVehicle = _f === void 0 ? false : _f, onSearch = _a.onSearch, onChange = _a.onChange, onRemove = _a.onRemove, _g = _a.className, className = _g === void 0 ? "" : _g, _h = _a.scrollOnOpen, scrollOnOpen = _h === void 0 ? false : _h;
|
|
34
|
+
var _b = _a.mode, initialMode = _b === void 0 ? "roundtrip" : _b, _c = _a.locations, locations = _c === void 0 ? { options: [], groups: [] } : _c, defaultRoundTripData = _a.defaultRoundTripData, defaultTransferLines = _a.defaultTransferLines, _d = _a.defaultSameVehicle, defaultSameVehicle = _d === void 0 ? false : _d, onSearch = _a.onSearch, onChange = _a.onChange, onRemove = _a.onRemove, _e = _a.className, className = _e === void 0 ? "" : _e, _f = _a.scrollOnOpen, scrollOnOpen = _f === void 0 ? false : _f;
|
|
36
35
|
// Generate unique ID for transfer lines
|
|
37
36
|
var generateTransferId = function () {
|
|
38
37
|
transferIdCounter += 1;
|
|
@@ -44,11 +43,11 @@ var SearchBarTransfer = function (_a) {
|
|
|
44
43
|
return [];
|
|
45
44
|
return lines.map(function (line) { return (__assign(__assign({}, line), { id: line.id || generateTransferId() })); });
|
|
46
45
|
};
|
|
47
|
-
var
|
|
48
|
-
var
|
|
49
|
-
var
|
|
50
|
-
var
|
|
51
|
-
var
|
|
46
|
+
var _g = useState(initialMode), mode = _g[0], setMode = _g[1];
|
|
47
|
+
var _h = useState(defaultSameVehicle), sameVehicle = _h[0], setSameVehicle = _h[1];
|
|
48
|
+
var _j = useState(defaultRoundTripData), roundTripData = _j[0], setRoundTripData = _j[1];
|
|
49
|
+
var _k = useState(initializeTransferLines(defaultTransferLines)), transferLines = _k[0], setTransferLines = _k[1];
|
|
50
|
+
var _l = useState(null), error = _l[0], setError = _l[1];
|
|
52
51
|
// Notify parent of changes
|
|
53
52
|
useEffect(function () {
|
|
54
53
|
var data = {
|
|
@@ -310,7 +309,7 @@ var SearchBarTransfer = function (_a) {
|
|
|
310
309
|
onSearch === null || onSearch === void 0 ? void 0 : onSearch(data);
|
|
311
310
|
}
|
|
312
311
|
};
|
|
313
|
-
return (_jsxs("div", { className: "search-bar-transfer ".concat(className), children: [_jsxs("div", { className: "search-bar-transfer__header", children: [_jsx(Heading, { level: 5, variant: "bold", color: "accent", children: "Select your transfer details" }), _jsx("div", { className: "search-bar-transfer__mode-selector", children: _jsx(SegmentedButton, { options: modeOptions, value: mode, onChange: handleModeChange, name: "transfer-mode" }) })] }), mode === "roundtrip" ? (_jsxs(_Fragment, { children: [_jsx(RoundTrip, { id: "roundtrip-main", locations: locations, paxData: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.paxData, arrivalDate: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.arrivalDate, departureDate: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.departureDate, pickupDropoffPoint:
|
|
312
|
+
return (_jsxs("div", { className: "search-bar-transfer ".concat(className), children: [_jsxs("div", { className: "search-bar-transfer__header", children: [_jsx(Heading, { level: 5, variant: "bold", color: "accent", children: "Select your transfer details" }), _jsx("div", { className: "search-bar-transfer__mode-selector", children: _jsx(SegmentedButton, { options: modeOptions, value: mode, onChange: handleModeChange, name: "transfer-mode" }) })] }), mode === "roundtrip" ? (_jsxs(_Fragment, { children: [_jsx(RoundTrip, { id: "roundtrip-main", locations: locations, paxData: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.paxData, arrivalDate: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.arrivalDate, departureDate: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.departureDate, pickupDropoffPoint: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.pickupDropoffPoint, accommodation: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.accommodation, onChange: setRoundTripData, checkEmpty: error !== null, scrollOnOpen: scrollOnOpen }), _jsx("div", { className: "search-bar-transfer__transfer-type", children: renderTransferTypeButtons(handleAddTransferFromRoundTrip) })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "search-bar-transfer__transfer-type", children: [_jsx(Text, { size: "lg", variant: "bold", color: "subtle", as: "div", className: "search-bar-transfer__transfer-type-label", children: "Select a transfer type you want to add" }), renderTransferTypeButtons(handleAddTransfer)] }), transferLines.length === 0 && (_jsx(TransferLine, { id: "placeholder-transfer", type: "inter-hotel", locations: locations, onDataChange: function () { }, showDelete: false, disabled: true, scrollOnOpen: scrollOnOpen })), transferLines.length > 0 && (_jsx("div", { className: "search-bar-transfer__transfer-lines", children: (function () {
|
|
314
313
|
// Group transfers by type
|
|
315
314
|
var groupedTransfers = {
|
|
316
315
|
arrival: [],
|
|
@@ -329,10 +328,7 @@ var SearchBarTransfer = function (_a) {
|
|
|
329
328
|
departure: { label: "Departure", icon: "departure" },
|
|
330
329
|
"inter-hotel": { label: "Inter-Hotel", icon: "building" },
|
|
331
330
|
};
|
|
332
|
-
return nonEmptyGroups.map(function (type, groupIndex) { return (_jsxs(React.Fragment, { children: [_jsxs("div", { className: "search-bar-transfer__category-header", children: [_jsx(Icon, { name: categoryInfo[type].icon, size: "md" }), _jsx(Text, { size: "md", variant: "bold", color: "default", as: "span", children: categoryInfo[type].label })] }), groupedTransfers[type].map(function (line) {
|
|
333
|
-
var _a, _b;
|
|
334
|
-
return (_jsx(TransferLine, { id: line.id, type: line.type, paxData: line.paxData, transferDate: line.transferDate, pickupPoint: (_a = line.pickupPoint) === null || _a === void 0 ? void 0 : _a.id, dropoffPoint: (_b = line.dropoffPoint) === null || _b === void 0 ? void 0 : _b.id, locations: locations, onDataChange: function (data) { return handleTransferLineChange(line.id, data); }, onDelete: function () { return handleDeleteTransferLine(line.id); }, showDelete: transferLines.length > 1, checkEmpty: error !== null, scrollOnOpen: scrollOnOpen }, line.id));
|
|
335
|
-
}), groupIndex < nonEmptyGroups.length - 1 && (_jsx("svg", { className: "search-bar-transfer__divider", xmlns: "http://www.w3.org/2000/svg", width: "100%", height: "1", viewBox: "0 0 1076 1", fill: "none", preserveAspectRatio: "none", children: _jsx("path", { d: "M0 0.5L1076 0.499906", stroke: "var(--color-border-medium, #A3A3A3)", strokeWidth: "1", strokeDasharray: "10 10" }) }))] }, type)); });
|
|
331
|
+
return nonEmptyGroups.map(function (type, groupIndex) { return (_jsxs(React.Fragment, { children: [_jsxs("div", { className: "search-bar-transfer__category-header", children: [_jsx(Icon, { name: categoryInfo[type].icon, size: "md" }), _jsx(Text, { size: "md", variant: "bold", color: "default", as: "span", children: categoryInfo[type].label })] }), groupedTransfers[type].map(function (line) { return (_jsx(TransferLine, { id: line.id, type: line.type, paxData: line.paxData, transferDate: line.transferDate, pickupPoint: line.pickupPoint, dropoffPoint: line.dropoffPoint, locations: locations, onDataChange: function (data) { return handleTransferLineChange(line.id, data); }, onDelete: function () { return handleDeleteTransferLine(line.id); }, showDelete: transferLines.length > 1, checkEmpty: error !== null, scrollOnOpen: scrollOnOpen }, line.id)); }), groupIndex < nonEmptyGroups.length - 1 && (_jsx("svg", { className: "search-bar-transfer__divider", xmlns: "http://www.w3.org/2000/svg", width: "100%", height: "1", viewBox: "0 0 1076 1", fill: "none", preserveAspectRatio: "none", children: _jsx("path", { d: "M0 0.5L1076 0.499906", stroke: "var(--color-border-medium, #A3A3A3)", strokeWidth: "1", strokeDasharray: "10 10" }) }))] }, type)); });
|
|
336
332
|
})() }))] })), _jsxs("div", { className: "search-bar-transfer__actions", children: [_jsx(Checkbox, { checked: sameVehicle, onChange: setSameVehicle, label: "Use the same vehicle for all your transfers" }), _jsxs("div", { className: "search-bar-transfer__cta", children: [error && (_jsx(Toast, { text: error, type: "danger" })), _jsx(Button, { variant: "primary", size: "lg", onClick: handleSearch, children: "Search" })] })] })] }));
|
|
337
333
|
};
|
|
338
334
|
export default SearchBarTransfer;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default } from './SearchBarTransfer';
|
|
2
|
-
export type {
|
|
2
|
+
export type { SearchBarTransferData, SearchBarTransferProps, TransferMode } from './SearchBarTransfer';
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import '../../../styles/components/organism/transfer-line.css';
|
|
3
|
-
import {
|
|
3
|
+
import { LocationGroup, LocationOption } from '../../molecules/LocationDropdown/LocationDropdown';
|
|
4
4
|
import { PaxData } from '../PaxSelector/PaxSelector';
|
|
5
5
|
export type TransferType = 'arrival' | 'departure' | 'inter-hotel';
|
|
6
|
-
export type {
|
|
6
|
+
export type { LocationOption };
|
|
7
7
|
export interface TransferLineData {
|
|
8
8
|
id: string;
|
|
9
9
|
type: TransferType;
|
|
10
10
|
paxData?: PaxData;
|
|
11
11
|
transferDate?: string;
|
|
12
|
-
pickupPoint?:
|
|
13
|
-
dropoffPoint?:
|
|
12
|
+
pickupPoint?: LocationOption;
|
|
13
|
+
dropoffPoint?: LocationOption;
|
|
14
14
|
}
|
|
15
15
|
export interface TransferLineProps {
|
|
16
16
|
/** Unique identifier for this transfer line */
|
|
@@ -21,10 +21,10 @@ export interface TransferLineProps {
|
|
|
21
21
|
paxData?: PaxData;
|
|
22
22
|
/** Transfer date */
|
|
23
23
|
transferDate?: string;
|
|
24
|
-
/** Selected pickup point ID (
|
|
25
|
-
pickupPoint?: string | number;
|
|
26
|
-
/** Selected dropoff point ID (
|
|
27
|
-
dropoffPoint?: string | number;
|
|
24
|
+
/** Selected pickup point - can be an ID (string/number) or LocationOption object */
|
|
25
|
+
pickupPoint?: string | number | LocationOption;
|
|
26
|
+
/** Selected dropoff point - can be an ID (string/number) or LocationOption object */
|
|
27
|
+
dropoffPoint?: string | number | LocationOption;
|
|
28
28
|
/** All location options - will be filtered based on transfer type */
|
|
29
29
|
locations?: {
|
|
30
30
|
options?: LocationOption[];
|
|
@@ -35,9 +35,9 @@ export interface TransferLineProps {
|
|
|
35
35
|
/** Callback when transfer date changes */
|
|
36
36
|
onDateChange?: (date: string) => void;
|
|
37
37
|
/** Callback when pickup point changes */
|
|
38
|
-
onPickupChange?: (location:
|
|
38
|
+
onPickupChange?: (location: LocationOption | null) => void;
|
|
39
39
|
/** Callback when dropoff point changes */
|
|
40
|
-
onDropoffChange?: (location:
|
|
40
|
+
onDropoffChange?: (location: LocationOption | null) => void;
|
|
41
41
|
/** Callback when any data changes - returns complete TransferLineData */
|
|
42
42
|
onDataChange?: (data: TransferLineData) => void;
|
|
43
43
|
/** Callback when delete button is clicked */
|