@autobusal/routes-order 1.37.9 → 1.38.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/RoutesOrder.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { useState, useEffect, useMemo } from 'react';
1
+ import { useState, useEffect, useMemo, useRef } from 'react';
2
2
  import { useParams, useSearchParams, useNavigate, useLocation } from 'react-router-dom';
3
3
  import { TFunction } from 'i18next';
4
4
  import { AiOutlineSearch, AiOutlineCaretDown, AiOutlineCaretUp } from 'react-icons/ai';
@@ -308,6 +308,36 @@ const RoutesOrder = ({ t }: Props): JSX.Element => {
308
308
  setRedirected(true);
309
309
  };
310
310
 
311
+ /*
312
+ * Claude - 2026-09-24: a link that names the coach.
313
+ *
314
+ * A referral partner shows our departures on their own site and sends the
315
+ * buyer here through the API's purchase_url, which is this page's 9-segment
316
+ * search URL plus `route=<id>` (and `return_route=<id>` on a round trip).
317
+ * The buyer already chose on the partner's page; making them choose again
318
+ * on our results would lose a share of them. So the moment the results
319
+ * that link describes arrive, the named coach is selected exactly as a
320
+ * click on its Select button would, and the wizard moves on to checkout.
321
+ *
322
+ * Once per mount and per slot: the ref remembers what was honoured, so
323
+ * Back to the results does not re-select the coach the buyer just left,
324
+ * while a reload of the checkout URL (which still carries the params)
325
+ * lands on checkout again, as a shared link should. A named coach that is
326
+ * not in the results - sold out, gone - leaves the buyer on the results
327
+ * with everything that is available.
328
+ */
329
+ const preselected = useRef<Set<string>>(new Set());
330
+
331
+ const preselect = (slot: 'route' | 'return_route'): (string | undefined) => {
332
+ const id = searchParams.get(slot);
333
+
334
+ return id && !preselected.current.has(slot) ? id : undefined;
335
+ };
336
+
337
+ const honour = (slot: 'route' | 'return_route'): void => {
338
+ preselected.current.add(slot);
339
+ };
340
+
311
341
  const onStep2 = (data: FoundData): void => {
312
342
  setStep2(data);
313
343
 
@@ -418,9 +448,10 @@ const RoutesOrder = ({ t }: Props): JSX.Element => {
418
448
  { showStep2 && (
419
449
  <Step2
420
450
  step1={ step1 }
451
+ preselect={ preselect('route') }
421
452
  t={ t }
422
453
  onSearch={ onSearchDate }
423
- onSave={ onStep2 }
454
+ onSave={ data => { honour('route'); onStep2(data); } }
424
455
  onBack={ onBack }
425
456
  />
426
457
  ) }
@@ -429,9 +460,10 @@ const RoutesOrder = ({ t }: Props): JSX.Element => {
429
460
  <Step3
430
461
  step1={ step1 }
431
462
  step2={ step2 }
463
+ preselect={ preselect('return_route') }
432
464
  t={ t }
433
465
  onSearch={ onSearchDate }
434
- onSave={ onStep3 }
466
+ onSave={ data => { honour('return_route'); onStep3(data); } }
435
467
  onBack={ onBack }
436
468
  />
437
469
  ) }
package/Step2.tsx CHANGED
@@ -1,3 +1,4 @@
1
+ import { useEffect } from 'react';
1
2
  import { TFunction } from 'i18next';
2
3
  import { RiBus2Line } from 'react-icons/ri';
3
4
  import { AiOutlineCaretLeft } from 'react-icons/ai';
@@ -12,15 +13,30 @@ import { useGetSuggestions } from '@autobusal/routes-search/services';
12
13
 
13
14
  interface Props {
14
15
  step1: RoutesSearchForm
16
+ // the id of a coach a link named, to select as soon as it is in the results
17
+ preselect?: string
15
18
  t: TFunction<'common'>
16
19
  onSearch: (data: ('departure' | '_return'), day: string) => void
17
20
  onSave: (data: FoundData) => void
18
21
  onBack: (step: number) => void
19
22
  }
20
23
 
21
- const Step2 = ({ step1, t, onSearch, onSave, onBack }: Props): JSX.Element => {
24
+ const Step2 = ({ step1, preselect, t, onSearch, onSave, onBack }: Props): JSX.Element => {
22
25
  const { data, isFetching } = useGetDepartures(step1);
23
26
 
27
+ // Claude - 2026-09-24: a purchase_url named this coach - see RoutesOrder
28
+ useEffect(() => {
29
+ if (preselect === undefined || data === undefined) {
30
+ return;
31
+ }
32
+
33
+ const named = data.find(item => String(item.id) === preselect && item.type !== 'external');
34
+
35
+ if (named) {
36
+ onSave(named);
37
+ }
38
+ }, [ preselect, data ]);
39
+
24
40
  /**
25
41
  * Edited: Ferjolt Ozuni - Date: 2026-08-01
26
42
  *
package/Step3.tsx CHANGED
@@ -1,3 +1,4 @@
1
+ import { useEffect } from 'react';
1
2
  import { TFunction } from 'i18next';
2
3
  import { RiBus2Line } from 'react-icons/ri';
3
4
  import { AiOutlineCaretLeft } from 'react-icons/ai';
@@ -12,15 +13,30 @@ import { useGetReturns } from './services';
12
13
  interface Props {
13
14
  step1: RoutesSearchForm
14
15
  step2: FoundData
16
+ // the id of a coach a link named, to select as soon as it is in the results
17
+ preselect?: string
15
18
  t: TFunction<'common'>
16
19
  onSearch: (data: ('departure' | '_return'), day: string) => void
17
20
  onSave: (data: FoundData) => void
18
21
  onBack: (step: number) => void
19
22
  }
20
23
 
21
- const Step3 = ({ step1, step2, t, onSearch, onSave, onBack }: Props): JSX.Element => {
24
+ const Step3 = ({ step1, step2, preselect, t, onSearch, onSave, onBack }: Props): JSX.Element => {
22
25
  const { data, isFetching } = useGetReturns(step1, step2);
23
26
 
27
+ // Claude - 2026-09-24: a purchase_url named this coach - see RoutesOrder
28
+ useEffect(() => {
29
+ if (preselect === undefined || data === undefined) {
30
+ return;
31
+ }
32
+
33
+ const named = data.find(item => String(item.id) === preselect && item.type !== 'external');
34
+
35
+ if (named) {
36
+ onSave(named);
37
+ }
38
+ }, [ preselect, data ]);
39
+
24
40
  return (
25
41
  <>
26
42
  <Title>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobusal/routes-order",
3
- "version": "1.37.9",
3
+ "version": "1.38.0",
4
4
  "author": "Ferjolt Ozuni",
5
5
  "type": "module",
6
6
  "main": "index.ts",