@autobusal/providers 1.45.3 → 1.46.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/Setup/Preload.tsx CHANGED
@@ -1,6 +1,6 @@
1
1
  import { useEffect } from 'react';
2
2
  import { JsonLd, hasMetaMounted, setServerToday } from '@autobusal/common';
3
- import { SettingsData } from '../types/settings';
3
+ import { SettingsData, OrganizationSettings } from '../types/settings';
4
4
  import { useSystemTheme } from '@autobusal/hooks';
5
5
 
6
6
  interface Props {
@@ -137,13 +137,54 @@ const Preload = ({ data, children }: Props): JSX.Element => {
137
137
  // this brand/environment.
138
138
  const siteUrl = window.location.origin;
139
139
 
140
+ /*
141
+ * Claude - 2026-09-26: the admin's Organization tab (preferences.
142
+ * organization, null until filled in) - the legal entity, where it is,
143
+ * how customers reach it, and the profiles elsewhere that are the same
144
+ * organisation. That last one is what lets Google's knowledge panel and
145
+ * the assistants tell this brand from a similarly named business.
146
+ * Every empty field is omitted rather than published blank.
147
+ */
148
+ const org: OrganizationSettings = data.preferences.organization ?? {};
149
+
150
+ const present = (value?: string | null): value is string => Boolean(value && value.trim());
151
+
152
+ const address = {
153
+ ...(present(org.street) ? { streetAddress: org.street } : {}),
154
+ ...(present(org.city) ? { addressLocality: org.city } : {}),
155
+ ...(present(org.postal_code) ? { postalCode: org.postal_code } : {}),
156
+ ...(present(org.country) ? { addressCountry: org.country } : {})
157
+ };
158
+
159
+ const languages = (org.languages ?? '').split(',').map(language => language.trim()).filter(Boolean);
160
+
161
+ const contact = {
162
+ ...(present(org.phone) ? { telephone: org.phone } : {}),
163
+ ...(present(org.email) ? { email: org.email } : {}),
164
+ ...(languages.length > 0 ? { availableLanguage: languages } : {})
165
+ };
166
+
167
+ // the footer's social links and the admin's own list, once each
168
+ const sameAs = Array.from(new Set([
169
+ ...Object.values(data.preferences.social).filter(present),
170
+ ...(org.same_as ?? []).filter(present),
171
+ ...(present(org.wikidata) ? [ `https://www.wikidata.org/wiki/${ org.wikidata }` ] : [])
172
+ ]));
173
+
140
174
  const organizationLd = {
141
175
  '@context': 'https://schema.org',
142
176
  '@type': 'Organization',
143
177
  name: data.preferences.company,
144
178
  url: siteUrl,
145
179
  logo: `${ data.url }/favicons/apple-touch-icon.png`,
146
- sameAs: Object.values(data.preferences.social).filter(Boolean)
180
+ ...(present(org.legal_name) ? { legalName: org.legal_name } : {}),
181
+ ...(present(org.alternate_name) ? { alternateName: org.alternate_name } : {}),
182
+ ...(present(org.description) ? { description: org.description } : {}),
183
+ ...(present(org.founding_date) ? { foundingDate: org.founding_date } : {}),
184
+ ...(Object.keys(address).length > 0 ? { address: { '@type': 'PostalAddress', ...address } } : {}),
185
+ // telephone or email is what makes a contact point; languages alone are not one
186
+ ...((contact.telephone || contact.email) ? { contactPoint: { '@type': 'ContactPoint', contactType: 'customer service', ...contact } } : {}),
187
+ ...(sameAs.length > 0 ? { sameAs } : {})
147
188
  };
148
189
 
149
190
  const websiteLd = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobusal/providers",
3
- "version": "1.45.3",
3
+ "version": "1.46.0",
4
4
  "author": "Ferjolt Ozuni",
5
5
  "type": "module",
6
6
  "main": "index.ts",
package/types/routes.ts CHANGED
@@ -34,6 +34,8 @@ export interface RouteData {
34
34
  language: string
35
35
  template: string
36
36
  searchable: number
37
+ // Claude - 2026-09-26: consent to publish in the GTFS feed (1 by default)
38
+ gtfs?: number | boolean
37
39
  information_en: string
38
40
  information_sq: string
39
41
 
package/types/settings.ts CHANGED
@@ -1,5 +1,32 @@
1
1
  import { PublicPromotion } from './promotions';
2
2
 
3
+ /**
4
+ * Who the brand is, for search engines and AI assistants - Claude, 2026-09-26.
5
+ * Saved from admin-label's Organization tab (type `organization`) and
6
+ * published in the sitewide Organization JSON-LD (Setup/Preload.tsx). Every
7
+ * field optional: the server drops empty ones, so an absent key means unset.
8
+ */
9
+ export interface OrganizationSettings {
10
+ legal_name?: string
11
+ alternate_name?: string
12
+ description?: string
13
+ // YYYY, YYYY-MM or YYYY-MM-DD
14
+ founding_date?: string
15
+ street?: string
16
+ city?: string
17
+ postal_code?: string
18
+ // ISO 3166-1 alpha-2
19
+ country?: string
20
+ phone?: string
21
+ email?: string
22
+ // free text, comma separated ("English, Albanian, Italian")
23
+ languages?: string
24
+ // profiles elsewhere that are the same organisation
25
+ same_as?: string[]
26
+ // Wikidata item id, e.g. Q12345
27
+ wikidata?: string
28
+ }
29
+
3
30
  export interface SettingsData {
4
31
  // Edited: Ferjolt Ozuni - Date: 2026-08-03
5
32
  // The earliest bookable date as the SERVER reckons it, d/m/Y. The date
@@ -175,6 +202,10 @@ export interface SettingsData {
175
202
  from: string
176
203
  to: string
177
204
  }
205
+
206
+ // Claude - 2026-09-26: the brand's Organization details (null until an
207
+ // admin fills the Organization tab in) - see OrganizationSettings
208
+ organization?: OrganizationSettings | null
178
209
  }
179
210
 
180
211
  theme: {
@@ -384,6 +415,9 @@ export interface LabelSettings {
384
415
  // Admin-managed footer social-share links (public preferences.social
385
416
  // above is populated from this) - distinct from `social` above, which
386
417
  // holds OAuth login credentials, not share URLs.
418
+ // Claude - 2026-09-26: the Organization tab's saved values
419
+ organization?: OrganizationSettings
420
+
387
421
  share?: {
388
422
  facebook?: string
389
423
  x?: string