@autobusal/routes-search 1.1.0 → 1.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ # Changelog
2
+
3
+ ## 1.2.0
4
+
5
+ **The date picker follows the departure city.** Choosing a "from" city now sets the picker's floor to that city's timezone, and a pre-filled form (a shared link, or the search form kept on the results page) sets it on mount rather than waiting for a keystroke.
6
+
7
+ An unknown city *clears* the zone rather than keeping the last one — silently flooring a new search on the previous journey's clock is the subtler version of the same bug.
8
+
9
+ All notable changes to `@autobusal/routes-search` are documented here. This
10
+ project adheres to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
11
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
12
+
13
+ ## [1.1.1] - 2026-08-01
14
+
15
+ ### Fixed
16
+
17
+ - **The return date could be set before the departure date.** The picker
18
+ floored at today, so an invalid pair was selectable and only refused by
19
+ an alert after pressing search. It now floors at whatever departure
20
+ currently holds, and follows it when that changes.
21
+
22
+ ## [1.1.0] - 2026-07-25
23
+
24
+ ### Fixed
25
+
26
+ - **Recovered as canonical source.** This package was published to npm and
27
+ in active use, but had no source anywhere in this monorepo (no
28
+ `packages/routes-search` directory, no git history) - the only copy of its
29
+ code existed as the published npm artifact. Recreated here,
30
+ byte-for-byte identical to the published 1.1.0 tarball (verified via
31
+ `diff` against the installed `node_modules/@autobusal/routes-search`), so it
32
+ can be edited and republished like every other package instead of
33
+ requiring reverse-engineering from `node_modules` or the npm tarball.
34
+ History prior to this point is not recoverable - no git log,
35
+ changelog, or other record of it exists.
36
+
37
+ Authored by Ferjolt Ozuni.
package/RoutesSearch.tsx CHANGED
@@ -1,9 +1,9 @@
1
- import { useState } from 'react';
1
+ import { useState, useEffect, useCallback } from 'react';
2
2
  import { TFunction } from 'i18next';
3
3
  import { useForm } from 'react-hook-form';
4
4
  import { FaArrowUp, FaHistory } from 'react-icons/fa';
5
5
  import { AiOutlineSearch } from 'react-icons/ai';
6
- import { Button, Autocomplete, Calendar, Passengers } from '@autobusal/common';
6
+ import { Button, Autocomplete, Calendar, Passengers, setDepartureZone } from '@autobusal/common';
7
7
  import { Display, createDate } from '@autobusal/utilities';
8
8
  import { getCities } from './utilities';
9
9
  import { Options, Columns, Column, Item, Title, Action } from './styles';
@@ -26,10 +26,43 @@ interface Props {
26
26
  const RoutesSearch = ({ type, from, to, departure, _return, adultsNo, childrenNo, babiesNo, t, onSearch }: Props): JSX.Element => {
27
27
  const [ selected, setSelected ] = useState<'departure' | 'return'>(type);
28
28
 
29
+ // Edited: Ferjolt Ozuni - Date: 2026-08-01
30
+ // Tracked in state rather than read from the form, because the return
31
+ // picker's floor has to move the moment the departure date changes -
32
+ // react-hook-form's value alone would not re-render this.
33
+ const [ departureDate, setDepartureDate ] = useState<string>(departure);
34
+
29
35
  const { register, handleSubmit, formState: { errors }, setValue } = useForm<RoutesSearchForm>();
30
36
 
31
37
  const { data: CitiesData } = useGetSuggestions();
32
38
 
39
+ /**
40
+ * Tell the date picker which clock this journey starts on.
41
+ *
42
+ * Edited: Ferjolt Ozuni - Date: 2026-08-03
43
+ *
44
+ * The picker used to floor on the buyer's device, then on our server's
45
+ * date - both wrong for the same reason: neither has anything to do with
46
+ * where the coach leaves from. Somebody in Shanghai at 06:00 on the 5th
47
+ * looking at an Italian coach leaving on the evening of the 4th had that
48
+ * day greyed out and could not ask for a seat the server would have sold.
49
+ *
50
+ * The value carries an optional stop (`slug:id`), so only the slug is
51
+ * matched. An unknown city clears the zone rather than keeping the last
52
+ * one, which would silently floor a new search on the old journey's clock.
53
+ */
54
+ const onDeparture = useCallback((value: string): void => {
55
+ const slug = String(value).split(':')[0];
56
+
57
+ setDepartureZone(CitiesData.find(city => city.slug === slug)?.country?.timezone ?? null);
58
+ }, [CitiesData]);
59
+
60
+ // the form can also arrive pre-filled - from a shared link, or the search
61
+ // form kept on the results page - so the zone cannot wait for a keystroke
62
+ useEffect(() => {
63
+ onDeparture(from);
64
+ }, [from, onDeparture]);
65
+
33
66
  const onClick = (type: ('departure' | 'return')): void => {
34
67
  setSelected(type);
35
68
  };
@@ -104,7 +137,7 @@ const RoutesSearch = ({ type, from, to, departure, _return, adultsNo, childrenNo
104
137
  validation="required"
105
138
  t={ t }
106
139
  refs={ register }
107
- onUpdate={ setValue }
140
+ onUpdate={ (_, value) => { setValue('from', value); onDeparture(String(value)); } }
108
141
  />
109
142
 
110
143
  { Display(errors.from) }
@@ -138,7 +171,11 @@ const RoutesSearch = ({ type, from, to, departure, _return, adultsNo, childrenNo
138
171
  t={ t }
139
172
  validation="required"
140
173
  refs={ register }
141
- onUpdate={ setValue }
174
+ onUpdate={ ((name, value) => {
175
+ setValue(name, value);
176
+
177
+ setDepartureDate(String(value));
178
+ }) as typeof setValue }
142
179
  />
143
180
 
144
181
  { Display(errors.departure) }
@@ -148,10 +185,17 @@ const RoutesSearch = ({ type, from, to, departure, _return, adultsNo, childrenNo
148
185
  <Item>
149
186
  <Title>{ t('routes_search.return', { ns: 'common' }) }</Title>
150
187
 
188
+ { /* Edited: Ferjolt Ozuni - Date: 2026-08-01
189
+ The return leg cannot start before the outbound one, so
190
+ the picker floors at whatever departure currently holds.
191
+ It used to floor at today, which let someone pick a
192
+ return before their departure and only told them so with
193
+ an alert after they pressed search. */ }
151
194
  <Calendar
152
195
  type="picker"
153
196
  name="_return"
154
197
  defaultValue={ _return }
198
+ minDate={ departureDate }
155
199
  t={ t }
156
200
  validation="required"
157
201
  refs={ register }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@autobusal/routes-search",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
+ "author": "Ferjolt Ozuni",
4
5
  "type": "module",
5
6
  "main": "index.ts"
6
7
  }