@autobusal/common 1.33.11 → 1.33.13
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 +12 -0
- package/Locale/DefaultLocaleGate.tsx +48 -0
- package/RouteItem/RouteItem.tsx +6 -2
- package/index.ts +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.33.13
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **`RouteItem` no longer advertises "From 0.00"**: zero-fare rows are unpriced legs search never sells, so they no longer count toward the cheapest-of figure. (Audit RT-11b.)
|
|
8
|
+
|
|
9
|
+
## 1.33.12
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **`DefaultLocaleGate`** - the mirror of `LocaleGate` for the UNPREFIXED public branch: a visitor whose stored language is not the brand default is redirected from `/help` to `/{lang}/help`, so the page shown always matches the address (and its canonical). Crawlers carry no localStorage and keep seeing the canonical default-language page. (Audit decision CMS-07c.)
|
|
14
|
+
|
|
3
15
|
## 1.33.11
|
|
4
16
|
|
|
5
17
|
### Fixed
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Navigate, useLocation } from 'react-router-dom';
|
|
2
|
+
import { useGetSettings } from '@autobusal/providers/services';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
children: JSX.Element
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Guards the UNPREFIXED branch of the public tree - the mirror of
|
|
10
|
+
* LocaleGate's job on the /:locale branch.
|
|
11
|
+
*
|
|
12
|
+
* Claude - Date: 2026-08-22 (audit decision CMS-07c)
|
|
13
|
+
*
|
|
14
|
+
* An unprefixed URL is the default language's canonical home, but the app
|
|
15
|
+
* used to render it in whatever language localStorage last held: /help
|
|
16
|
+
* with a stored "it" produced an Italian page whose canonical claimed
|
|
17
|
+
* English - a shared "English" link showed each recipient something
|
|
18
|
+
* different. The ruling: the stored preference redirects to its own
|
|
19
|
+
* prefix, so URL and content always agree. A visitor who last browsed in
|
|
20
|
+
* Italian and types /help lands on /it/help, keeping both their language
|
|
21
|
+
* and a truthful address bar.
|
|
22
|
+
*
|
|
23
|
+
* Crawlers and the prerenderer carry no localStorage, so the canonical
|
|
24
|
+
* English page is what they keep seeing - this never runs for them.
|
|
25
|
+
*
|
|
26
|
+
* Only the PUBLIC tree mounts this. The account, auth and admin areas are
|
|
27
|
+
* deliberately not localised (see Routing.tsx), and redirecting them would
|
|
28
|
+
* 404 every one of their URLs.
|
|
29
|
+
*/
|
|
30
|
+
const DefaultLocaleGate = ({ children }: Props): JSX.Element => {
|
|
31
|
+
const location = useLocation();
|
|
32
|
+
|
|
33
|
+
const { data } = useGetSettings();
|
|
34
|
+
|
|
35
|
+
const available = data?.preferences?.languages?.available ?? [];
|
|
36
|
+
|
|
37
|
+
const fallback = data?.preferences?.languages?.default ?? 'en';
|
|
38
|
+
|
|
39
|
+
const stored = localStorage.getItem('language');
|
|
40
|
+
|
|
41
|
+
if (stored && stored !== fallback && available.includes(stored)) {
|
|
42
|
+
return <Navigate to={ `/${ stored }${ location.pathname }${ location.search }${ location.hash }` } replace />;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return children;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export default DefaultLocaleGate;
|
package/RouteItem/RouteItem.tsx
CHANGED
|
@@ -25,8 +25,12 @@ const RouteItem = ({ type, route, t }: Props): JSX.Element => {
|
|
|
25
25
|
// reformatting `adult` itself - the server already applied this label's
|
|
26
26
|
// currency symbol/decimal convention, and re-deriving that here would
|
|
27
27
|
// risk disagreeing with every other price on the site.
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
// Claude - 2026-08-22 (audit finding RT-11b): zero-fare rows are
|
|
29
|
+
// unpriced legs search never sells - see RouteView's matching note.
|
|
30
|
+
const priced = route.prices.filter(price => price.adult > 0);
|
|
31
|
+
|
|
32
|
+
const cheapest = priced.length > 0
|
|
33
|
+
? priced.reduce((min, price) => (price.adult < min.adult ? price : min))
|
|
30
34
|
: null;
|
|
31
35
|
|
|
32
36
|
return (
|
package/index.ts
CHANGED
|
@@ -35,6 +35,7 @@ import RouteFeature from './RouteFeature/RouteFeature';
|
|
|
35
35
|
import Required from './Required/Required';
|
|
36
36
|
import Road from './Road/Road';
|
|
37
37
|
import LocaleGate from './Locale/LocaleGate';
|
|
38
|
+
import DefaultLocaleGate from './Locale/DefaultLocaleGate';
|
|
38
39
|
import SeoOverride from './SeoOverride/SeoOverride';
|
|
39
40
|
import HandoffBanner from './HandoffBanner/HandoffBanner';
|
|
40
41
|
import localiseRoutes from './Locale/routes';
|
|
@@ -89,6 +90,7 @@ export {
|
|
|
89
90
|
Required,
|
|
90
91
|
Road,
|
|
91
92
|
LocaleGate,
|
|
93
|
+
DefaultLocaleGate,
|
|
92
94
|
SeoOverride,
|
|
93
95
|
HandoffBanner,
|
|
94
96
|
localiseRoutes,
|