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.
@@ -12,16 +12,16 @@ import PaxSelector, { PaxData } from '../PaxSelector/PaxSelector';
12
12
 
13
13
  export type TransferType = 'arrival' | 'departure' | 'inter-hotel';
14
14
 
15
- // Re-export LocationData for convenience
16
- export type { LocationData };
15
+ // Re-export LocationOption for convenience
16
+ export type { LocationOption };
17
17
 
18
18
  export interface TransferLineData {
19
19
  id: string;
20
20
  type: TransferType;
21
21
  paxData?: PaxData;
22
22
  transferDate?: string;
23
- pickupPoint?: LocationData;
24
- dropoffPoint?: LocationData;
23
+ pickupPoint?: LocationOption;
24
+ dropoffPoint?: LocationOption;
25
25
  }
26
26
 
27
27
  export interface TransferLineProps {
@@ -33,10 +33,10 @@ export interface TransferLineProps {
33
33
  paxData?: PaxData;
34
34
  /** Transfer date */
35
35
  transferDate?: string;
36
- /** Selected pickup point ID (for initial value) */
37
- pickupPoint?: string | number;
38
- /** Selected dropoff point ID (for initial value) */
39
- dropoffPoint?: string | number;
36
+ /** Selected pickup point - can be an ID (string/number) or LocationOption object */
37
+ pickupPoint?: string | number | LocationOption;
38
+ /** Selected dropoff point - can be an ID (string/number) or LocationOption object */
39
+ dropoffPoint?: string | number | LocationOption;
40
40
  /** All location options - will be filtered based on transfer type */
41
41
  locations?: {
42
42
  options?: LocationOption[];
@@ -47,9 +47,9 @@ export interface TransferLineProps {
47
47
  /** Callback when transfer date changes */
48
48
  onDateChange?: (date: string) => void;
49
49
  /** Callback when pickup point changes */
50
- onPickupChange?: (location: LocationData | null) => void;
50
+ onPickupChange?: (location: LocationOption | null) => void;
51
51
  /** Callback when dropoff point changes */
52
- onDropoffChange?: (location: LocationData | null) => void;
52
+ onDropoffChange?: (location: LocationOption | null) => void;
53
53
  /** Callback when any data changes - returns complete TransferLineData */
54
54
  onDataChange?: (data: TransferLineData) => void;
55
55
  /** Callback when delete button is clicked */
@@ -93,10 +93,10 @@ const TransferLine: React.FC<TransferLineProps> = ({
93
93
  const [internalTransferDate, setInternalTransferDate] = useState<string | undefined>(
94
94
  transferDate
95
95
  );
96
- const [internalPickupPoint, setInternalPickupPoint] = useState<LocationData | null>(
96
+ const [internalPickupPoint, setInternalPickupPoint] = useState<LocationOption | null>(
97
97
  null
98
98
  );
99
- const [internalDropoffPoint, setInternalDropoffPoint] = useState<LocationData | null>(
99
+ const [internalDropoffPoint, setInternalDropoffPoint] = useState<LocationOption | null>(
100
100
  null
101
101
  );
102
102
 
@@ -153,56 +153,65 @@ const TransferLine: React.FC<TransferLineProps> = ({
153
153
  return null;
154
154
  };
155
155
 
156
- // Initialize location data from IDs or set defaults
156
+ // Helper to check if value is LocationOption
157
+ const isLocationOption = (value: string | number | LocationOption | undefined): value is LocationOption => {
158
+ return typeof value === 'object' && value !== null && 'id' in value && 'label' in value && 'type' in value;
159
+ };
160
+
161
+ // Initialize location data from IDs, LocationOption objects, or set defaults
157
162
  React.useEffect(() => {
163
+ // If pickupPoint is already a LocationOption object, use it directly
164
+ if (isLocationOption(pickupPoint)) {
165
+ // Only update if the ID is different to prevent infinite loops
166
+ if (internalPickupPoint?.id !== pickupPoint.id) {
167
+ setInternalPickupPoint(pickupPoint);
168
+ }
169
+ return;
170
+ }
171
+
158
172
  const { options, groups } = filterLocations('pickup');
159
173
  const allPickupLocations = getAllLocations(options, groups);
160
174
 
161
175
  if (pickupPoint) {
162
176
  const location = allPickupLocations.find((loc) => loc.id === pickupPoint);
163
- if (location) {
164
- setInternalPickupPoint({
165
- id: location.id,
166
- locationName: location.label,
167
- });
177
+ if (location && internalPickupPoint?.id !== location.id) {
178
+ setInternalPickupPoint(location);
168
179
  }
169
- } else {
170
- // Set default location if applicable
180
+ } else if (!internalPickupPoint) {
181
+ // Set default location if applicable (only if not already set)
171
182
  const defaultLocation = getDefaultLocation('pickup');
172
183
  if (defaultLocation) {
173
- const defaultData: LocationData = {
174
- id: defaultLocation.id,
175
- locationName: defaultLocation.label,
176
- };
177
- setInternalPickupPoint(defaultData);
178
- onPickupChange?.(defaultData);
184
+ setInternalPickupPoint(defaultLocation);
185
+ onPickupChange?.(defaultLocation);
179
186
  }
180
187
  }
181
188
  // eslint-disable-next-line react-hooks/exhaustive-deps
182
189
  }, [pickupPoint, type, locations]);
183
190
 
184
191
  React.useEffect(() => {
192
+ // If dropoffPoint is already a LocationOption object, use it directly
193
+ if (isLocationOption(dropoffPoint)) {
194
+ // Only update if the ID is different to prevent infinite loops
195
+ if (internalDropoffPoint?.id !== dropoffPoint.id) {
196
+ setInternalDropoffPoint(dropoffPoint);
197
+ }
198
+ return;
199
+ }
200
+
185
201
  const { options, groups } = filterLocations('dropoff');
186
202
  const allDropoffLocations = getAllLocations(options, groups);
187
203
 
188
204
  if (dropoffPoint) {
189
205
  const location = allDropoffLocations.find((loc) => loc.id === dropoffPoint);
190
- if (location) {
191
- setInternalDropoffPoint({
192
- id: location.id,
193
- locationName: location.label,
194
- });
206
+ if (location && internalDropoffPoint?.id !== location.id) {
207
+ setInternalDropoffPoint(location);
195
208
  }
196
- } else {
197
- // Set default location if applicable
209
+ } else if (!internalDropoffPoint) {
210
+ // Set default location if applicable (only if not already set)
198
211
  const defaultLocation = getDefaultLocation('dropoff');
199
212
  if (defaultLocation) {
200
- const defaultData: LocationData = {
201
- id: defaultLocation.id,
202
- locationName: defaultLocation.label,
203
- };
204
- setInternalDropoffPoint(defaultData);
205
- onDropoffChange?.(defaultData);
213
+ setInternalDropoffPoint(defaultLocation);
214
+ onDropoffChange?.(defaultLocation);
206
215
  }
207
216
  }
208
217
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -266,14 +275,43 @@ const TransferLine: React.FC<TransferLineProps> = ({
266
275
  onDateChange?.(dateValue);
267
276
  };
268
277
 
278
+ // Helper to convert LocationData to LocationOption
279
+ const toLocationOption = (locationData: LocationData | null, position: 'pickup' | 'dropoff'): LocationOption | null => {
280
+ if (!locationData) return null;
281
+
282
+ // Try to find in the options to get the type
283
+ const { options, groups } = filterLocations(position);
284
+ const allLocations = getAllLocations(options, groups);
285
+ const found = allLocations.find((loc) => loc.id === locationData.id);
286
+ if (found) return found;
287
+
288
+ // If not found, infer the type
289
+ const name = locationData.locationName.toLowerCase();
290
+ const id = String(locationData.id).toLowerCase();
291
+ let locType: 'airport' | 'port' | 'accommodation' = 'accommodation';
292
+ if (name.includes('harbour') || name.includes('port') || id.includes('harbour') || id.includes('port')) {
293
+ locType = 'port';
294
+ } else if (name.includes('airport') || id.includes('airport')) {
295
+ locType = 'airport';
296
+ }
297
+
298
+ return {
299
+ id: locationData.id,
300
+ label: locationData.locationName,
301
+ type: locType,
302
+ };
303
+ };
304
+
269
305
  const handlePickupChange = (location: LocationData | null) => {
270
- setInternalPickupPoint(location);
271
- onPickupChange?.(location);
306
+ const locationOption = toLocationOption(location, 'pickup');
307
+ setInternalPickupPoint(locationOption);
308
+ onPickupChange?.(locationOption);
272
309
  };
273
310
 
274
311
  const handleDropoffChange = (location: LocationData | null) => {
275
- setInternalDropoffPoint(location);
276
- onDropoffChange?.(location);
312
+ const locationOption = toLocationOption(location, 'dropoff');
313
+ setInternalDropoffPoint(locationOption);
314
+ onDropoffChange?.(locationOption);
277
315
  };
278
316
 
279
317
  // Check if inputs are empty (when checkEmpty is true)
@@ -292,6 +330,24 @@ const TransferLine: React.FC<TransferLineProps> = ({
292
330
 
293
331
  const isDropoffEmpty = checkEmpty && !internalDropoffPoint;
294
332
 
333
+ // Helper function to find LocationOption from ID or LocationOption for defaultValue
334
+ const findLocationOption = (value: string | number | LocationOption | undefined, position: 'pickup' | 'dropoff'): LocationOption | undefined => {
335
+ if (!value) return undefined;
336
+
337
+ // If value is already a LocationOption object, use it directly
338
+ if (isLocationOption(value)) {
339
+ return value;
340
+ }
341
+
342
+ // Otherwise, look up by ID in the locations
343
+ const { options, groups } = filterLocations(position);
344
+ const allLocations = getAllLocations(options, groups);
345
+ return allLocations.find((loc) => loc.id === value);
346
+ };
347
+
348
+ const defaultPickupOption = findLocationOption(pickupPoint, 'pickup');
349
+ const defaultDropoffOption = findLocationOption(dropoffPoint, 'dropoff');
350
+
295
351
  return (
296
352
  <div
297
353
  className={`transfer-line transfer-line--${type} ${disabled ? 'transfer-line--disabled' : ''} ${className}`}
@@ -367,6 +423,7 @@ const TransferLine: React.FC<TransferLineProps> = ({
367
423
  error={isPickupEmpty}
368
424
  disabled={disabled}
369
425
  scrollOnOpen={scrollOnOpen}
426
+ defaultValue={defaultPickupOption}
370
427
  />
371
428
  </div>
372
429
 
@@ -391,6 +448,7 @@ const TransferLine: React.FC<TransferLineProps> = ({
391
448
  error={isDropoffEmpty}
392
449
  disabled={disabled}
393
450
  scrollOnOpen={scrollOnOpen}
451
+ defaultValue={defaultDropoffOption}
394
452
  />
395
453
  </div>
396
454
  </div>