@autobusal/routes-search 1.0.1 → 1.1.1

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,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@autobusal/routes-search` are documented here. This
4
+ project adheres to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [1.1.1] - 2026-08-01
8
+
9
+ ### Fixed
10
+
11
+ - **The return date could be set before the departure date.** The picker
12
+ floored at today, so an invalid pair was selectable and only refused by
13
+ an alert after pressing search. It now floors at whatever departure
14
+ currently holds, and follows it when that changes.
15
+
16
+ ## [1.1.0] - 2026-07-25
17
+
18
+ ### Fixed
19
+
20
+ - **Recovered as canonical source.** This package was published to npm and
21
+ in active use, but had no source anywhere in this monorepo (no
22
+ `packages/routes-search` directory, no git history) - the only copy of its
23
+ code existed as the published npm artifact. Recreated here,
24
+ byte-for-byte identical to the published 1.1.0 tarball (verified via
25
+ `diff` against the installed `node_modules/@autobusal/routes-search`), so it
26
+ can be edited and republished like every other package instead of
27
+ requiring reverse-engineering from `node_modules` or the npm tarball.
28
+ History prior to this point is not recoverable - no git log,
29
+ changelog, or other record of it exists.
30
+
31
+ Authored by Ferjolt Ozuni.
package/RoutesSearch.tsx CHANGED
@@ -5,8 +5,8 @@ import { FaArrowUp, FaHistory } from 'react-icons/fa';
5
5
  import { AiOutlineSearch } from 'react-icons/ai';
6
6
  import { Button, Autocomplete, Calendar, Passengers } from '@autobusal/common';
7
7
  import { Display, createDate } from '@autobusal/utilities';
8
+ import { getCities } from './utilities';
8
9
  import { Options, Columns, Column, Item, Title, Action } from './styles';
9
- import { AutocompleteData } from '@autobusal/common/Autocomplete/types';
10
10
  import { RoutesSearchForm } from './types';
11
11
  import { useGetSuggestions } from './services';
12
12
 
@@ -26,9 +26,15 @@ 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
- const { data } = useGetSuggestions();
37
+ const { data: CitiesData } = useGetSuggestions();
32
38
 
33
39
  const onClick = (type: ('departure' | 'return')): void => {
34
40
  setSelected(type);
@@ -45,6 +51,16 @@ const RoutesSearch = ({ type, from, to, departure, _return, adultsNo, childrenNo
45
51
  data.babies = Number(data.babies);
46
52
  data.children = Number(data.children);
47
53
 
54
+ // add the locations
55
+ const from = data.from.split(':');
56
+ data.from = from[0];
57
+ data.stop_from = from[1];
58
+
59
+ // add the to locations
60
+ const to = data.to.split(':');
61
+ data.to = to[0];
62
+ data.stop_to = to[1];
63
+
48
64
  if (data.adults == 0) {
49
65
  alert(t('routes_search.errors.adults'));
50
66
  } else if (data.adults + data.children > 5) {
@@ -58,10 +74,7 @@ const RoutesSearch = ({ type, from, to, departure, _return, adultsNo, childrenNo
58
74
  }
59
75
  };
60
76
 
61
- const cities: AutocompleteData[] = data.map(city => ({
62
- name: `${ city.name }, ${ city.country?.name ?? '' }`,
63
- value: city.slug
64
- }));
77
+ const cities = getCities(CitiesData, t);
65
78
 
66
79
  return (
67
80
  <form onSubmit={ handleSubmit(onSubmit) }>
@@ -131,7 +144,11 @@ const RoutesSearch = ({ type, from, to, departure, _return, adultsNo, childrenNo
131
144
  t={ t }
132
145
  validation="required"
133
146
  refs={ register }
134
- onUpdate={ setValue }
147
+ onUpdate={ ((name, value) => {
148
+ setValue(name, value);
149
+
150
+ setDepartureDate(String(value));
151
+ }) as typeof setValue }
135
152
  />
136
153
 
137
154
  { Display(errors.departure) }
@@ -141,10 +158,17 @@ const RoutesSearch = ({ type, from, to, departure, _return, adultsNo, childrenNo
141
158
  <Item>
142
159
  <Title>{ t('routes_search.return', { ns: 'common' }) }</Title>
143
160
 
161
+ { /* Edited: Ferjolt Ozuni - Date: 2026-08-01
162
+ The return leg cannot start before the outbound one, so
163
+ the picker floors at whatever departure currently holds.
164
+ It used to floor at today, which let someone pick a
165
+ return before their departure and only told them so with
166
+ an alert after they pressed search. */ }
144
167
  <Calendar
145
168
  type="picker"
146
169
  name="_return"
147
170
  defaultValue={ _return }
171
+ minDate={ departureDate }
148
172
  t={ t }
149
173
  validation="required"
150
174
  refs={ register }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@autobusal/routes-search",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
+ "author": "Ferjolt Ozuni",
4
5
  "type": "module",
5
6
  "main": "index.ts"
6
7
  }
package/types.ts CHANGED
@@ -7,4 +7,6 @@ export interface RoutesSearchForm {
7
7
  adults: number
8
8
  children: number
9
9
  babies: number
10
+ stop_from?: string
11
+ stop_to?: string
10
12
  }
package/utilities.ts ADDED
@@ -0,0 +1,23 @@
1
+ import { TFunction } from 'i18next';
2
+ import { AutocompleteData } from '@autobusal/common/Autocomplete/types';
3
+ import { CityData } from '@autobusal/providers/types/locations';
4
+
5
+ export const getCities = (cities: CityData[], t: TFunction<'common'>): AutocompleteData[] => {
6
+ const data: AutocompleteData[] = [];
7
+
8
+ cities.forEach(city => {
9
+ data.push({
10
+ name: `${ city.name }, ${ city.country?.name ?? '' } (${ t('all_stations', { ns: 'common' }) })`,
11
+ value: `${ city.slug }`
12
+ });
13
+
14
+ city.stops?.forEach(stop => {
15
+ data.push({
16
+ name: `${ city.name }, ${ city.country?.name ?? '' } (${ stop.name })`,
17
+ value: `${ city.slug }:${ stop.id }`
18
+ });
19
+ });
20
+ });
21
+
22
+ return data;
23
+ };