@autobusal/providers 1.13.0 → 1.15.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 CHANGED
@@ -7,6 +7,28 @@ adheres to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
7
7
  > Note: 1.8.0 through 1.11.0 were published without changelog entries. The
8
8
  > gap is left as-is rather than reconstructed after the fact.
9
9
 
10
+ ## [1.15.0] - 2026-08-02
11
+
12
+ ### Changed
13
+
14
+ - **The URL decides the language.** `getLanguage()` now reads a locale prefix
15
+ off the path before falling back to the stored preference and then the
16
+ brand default, and takes the brand's `available` list so an unrecognised
17
+ first segment (`/city/tirana`) is never mistaken for a language. This is
18
+ the point of localised URLs: a link has to decide what its recipient sees,
19
+ so someone whose last visit was in Albanian still gets Italian from a
20
+ shared `/it/...` link. Unprefixed URLs are unaffected.
21
+
22
+ ## [1.14.0] - 2026-08-02
23
+
24
+ ### Changed
25
+
26
+ - **`LabelSettings.telegram`/`.whatsapp` drop `price` and `refundable`.** They
27
+ moved to obtapi's `addons` table; the label manager reads them from the
28
+ label's `addons` map instead (see `@autobusal/admin-label` 1.15.0). The
29
+ public `settings.addons` shape is unchanged, but its contents are now
30
+ filtered by who is asking and through what channel.
31
+
10
32
  ## [1.13.0] - 2026-08-01
11
33
 
12
34
  ### Removed
package/Setup/Setup.tsx CHANGED
@@ -15,7 +15,7 @@ const Setup = ({ type, children }: Props): JSX.Element => {
15
15
  useGetMenu();
16
16
  useUserBootstrap();
17
17
 
18
- languages(type, data.preferences.languages.default);
18
+ languages(type, data.preferences.languages.default, data.preferences.languages.available);
19
19
 
20
20
  // Edited: Ferjolt Ozuni - Date: 2026-08-01
21
21
  // The brand's GTM container, from labels_settings via the admin GUI.
@@ -2,9 +2,34 @@ import i18next from 'i18next';
2
2
  import Backend from 'i18next-http-backend';
3
3
  import { initReactI18next } from 'react-i18next';
4
4
 
5
- export const getLanguage = (defaultLanguage: string): string => (
6
- localStorage.getItem('language') ?? defaultLanguage
7
- );
5
+ /**
6
+ * The language to start in.
7
+ *
8
+ * Edited: Ferjolt Ozuni - Date: 2026-08-02
9
+ * A locale-prefixed URL now wins over the stored preference. That ordering
10
+ * is the whole point of localised URLs: a link has to decide what its
11
+ * recipient sees, so somebody whose last visit was in Albanian must still
12
+ * get Italian when they open a shared /it/... link. The stored preference
13
+ * still covers every unprefixed URL - the homepage a returning visitor
14
+ * types in, and the whole account area, which is not localised.
15
+ *
16
+ * `available` is passed in rather than read from anywhere global so this
17
+ * stays a pure function of its inputs, and so an unrecognised first segment
18
+ * (/city/tirana) is never mistaken for a language.
19
+ */
20
+ export const getLanguage = (defaultLanguage: string, available: string[] = []): string => {
21
+ const [ , first ] = window.location.pathname.split('/');
22
+
23
+ if (first && available.includes(first)) {
24
+ return first;
25
+ }
26
+
27
+ const stored = localStorage.getItem('language');
28
+
29
+ return (stored && (available.length === 0 || available.includes(stored)))
30
+ ? stored
31
+ : defaultLanguage;
32
+ };
8
33
 
9
34
  // Cache-busting query param for the language files. `Cache-Control: no-cache`
10
35
  // on the obtapi side only asks caches to revalidate before reuse - in
@@ -18,7 +43,7 @@ export const getLanguage = (defaultLanguage: string): string => (
18
43
  // consumer that hasn't set VITE_BUILD_ID yet (no worse than before).
19
44
  const buildId = import.meta.env.VITE_BUILD_ID ?? 'dev';
20
45
 
21
- const languages = (type: string, defaultLanguage: string): void => {
46
+ const languages = (type: string, defaultLanguage: string, available: string[] = []): void => {
22
47
  if (i18next.isInitialized) {
23
48
  return;
24
49
  }
@@ -30,7 +55,7 @@ const languages = (type: string, defaultLanguage: string): void => {
30
55
  interpolation: {
31
56
  escapeValue: false
32
57
  },
33
- lng: getLanguage(defaultLanguage),
58
+ lng: getLanguage(defaultLanguage, available),
34
59
  fallbackLng: defaultLanguage,
35
60
  debug: import.meta.env.DEV,
36
61
  backend: {
@@ -45,7 +70,7 @@ const languages = (type: string, defaultLanguage: string): void => {
45
70
  // immediately (don't wait for the async backend fetch) and keep it in sync
46
71
  // on every future change, whether triggered by ChangeLanguage or anything
47
72
  // else that calls i18next.changeLanguage().
48
- document.documentElement.lang = getLanguage(defaultLanguage);
73
+ document.documentElement.lang = getLanguage(defaultLanguage, available);
49
74
  i18next.on('languageChanged', (lng) => {
50
75
  document.documentElement.lang = lng;
51
76
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobusal/providers",
3
- "version": "1.13.0",
3
+ "version": "1.15.0",
4
4
  "author": "Ferjolt Ozuni",
5
5
  "type": "module",
6
6
  "main": "index.ts"
package/types/settings.ts CHANGED
@@ -190,15 +190,9 @@ export interface LabelSettings {
190
190
  // Admin-managed Telegram bot configuration - bot_username is captured
191
191
  // automatically from a live getMe() check on save, not entered by hand.
192
192
  // 'status': same disabled/dedicated/main model as whatsapp below and
193
- // Raiffeisen's payment domain toggle. `price` is the checkout addon
194
- // price this label charges, regardless of whose bot actually sends it.
193
+ // Raiffeisen's payment domain toggle.
195
194
  telegram?: {
196
195
  status: 'disabled' | 'dedicated' | 'main'
197
- price: number
198
- // Edited: Ferjolt Ozuni - Date: 2026-07-31
199
- // whether this label gives the addon fee back on cancellation;
200
- // snapshotted onto each purchase, so it only affects future orders
201
- refundable?: boolean
202
196
  bot_token?: string
203
197
  bot_username?: string
204
198
  }
@@ -209,11 +203,6 @@ export interface LabelSettings {
209
203
  // entered by hand.
210
204
  whatsapp?: {
211
205
  status: 'disabled' | 'dedicated' | 'main'
212
- price: number
213
- // Edited: Ferjolt Ozuni - Date: 2026-07-31
214
- // whether this label gives the addon fee back on cancellation;
215
- // snapshotted onto each purchase, so it only affects future orders
216
- refundable?: boolean
217
206
  phone_number_id?: string
218
207
  access_token?: string
219
208
  template_name?: string