From 7dcbdb9fa67fa95fade107bd67feae0e62d99075 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Fri, 19 Jun 2026 20:42:48 -0400 Subject: [PATCH] Enhance localization support by adding new languages and updating existing translations. Added Portuguese and Catalan translations for the Navbar and various UI elements. Updated Svelte component to include transportation filtering and mapping features. Improved VSCode settings for i18n-ally framework support. --- .vscode/settings.json | 1 + frontend/src/lib/components/Navbar.svelte | 6 +- .../collections/CollectionMap.svelte | 86 ++ frontend/src/lib/config.ts | 2 +- frontend/src/locales/ar.json | 154 +- frontend/src/locales/ca.json | 1298 ++++++++++++++++- frontend/src/locales/cs.json | 1207 ++++++++++++++- frontend/src/locales/de.json | 6 +- frontend/src/locales/es.json | 147 +- frontend/src/locales/fr.json | 6 +- frontend/src/locales/hu.json | 154 +- frontend/src/locales/it.json | 138 +- frontend/src/locales/ja.json | 154 +- frontend/src/locales/ko.json | 154 +- frontend/src/locales/nl.json | 154 +- frontend/src/locales/no.json | 154 +- frontend/src/locales/pl.json | 103 +- frontend/src/locales/pt-br.json | 154 +- frontend/src/locales/pt.json | 1015 ++++++++++++- frontend/src/locales/ro.json | 154 +- frontend/src/locales/ru.json | 154 +- frontend/src/locales/sk.json | 39 +- frontend/src/locales/sv.json | 1 - frontend/src/locales/ta.json | 6 +- frontend/src/locales/tr.json | 37 +- frontend/src/locales/uk.json | 154 +- frontend/src/locales/zh.json | 154 +- frontend/src/routes/+layout.svelte | 8 +- 28 files changed, 5694 insertions(+), 106 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index a258928f..ef9c4fd9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "git.ignoreLimitWarning": true, + "i18n-ally.enabledFrameworks": ["svelte"], "i18n-ally.localesPaths": [ "frontend/src/locales", "backend/server/backend/lib/python3.12/site-packages/allauth/locale", diff --git a/frontend/src/lib/components/Navbar.svelte b/frontend/src/lib/components/Navbar.svelte index 656e5250..bee27142 100644 --- a/frontend/src/lib/components/Navbar.svelte +++ b/frontend/src/lib/components/Navbar.svelte @@ -74,12 +74,16 @@ ru: 'Русский', ja: '日本語', ar: 'العربية', + pt: 'Português', 'pt-br': 'Português (Brasil)', ro: 'Română', sk: 'Slovenský', tr: 'Türkçe', uk: 'Українська', - hu: 'Magyar' + hu: 'Magyar', + ca: 'Català', + cs: 'Čeština', + ta: 'தமிழ்' }; const submitLocaleChange = (event: Event) => { diff --git a/frontend/src/lib/components/collections/CollectionMap.svelte b/frontend/src/lib/components/collections/CollectionMap.svelte index 5a323087..adffa40a 100644 --- a/frontend/src/lib/components/collections/CollectionMap.svelte +++ b/frontend/src/lib/components/collections/CollectionMap.svelte @@ -235,6 +235,63 @@ return features; } + function transportationToLineFeature(t: any): GeoJSON.Feature | null { + const originLat = parseNumber(t?.origin_latitude); + const originLon = parseNumber(t?.origin_longitude); + const destLat = parseNumber(t?.destination_latitude); + const destLon = parseNumber(t?.destination_longitude); + + if (originLat === null || originLon === null || destLat === null || destLon === null) { + return null; + } + if (originLat === destLat && originLon === destLon) return null; + + return { + type: 'Feature', + geometry: { + type: 'LineString', + coordinates: [ + [originLon, originLat], + [destLon, destLat] + ] + }, + properties: { + id: String(t.id), + name: t?.name || t?.type || 'Transportation', + type: 'transportation', + _color: '#f59e0b' + } + }; + } + + function transportationMatchesFilters( + t: any, + filters: { startDate: string; endDate: string; search: string } + ): boolean { + const date = getTransportationDate(t); + if (!isWithinDateRange(date, filters.startDate, filters.endDate)) return false; + + if (filters.search) { + const query = filters.search.toLowerCase(); + const nameMatch = (t?.name || '').toLowerCase().includes(query); + const typeMatch = (t?.type || '').toLowerCase().includes(query); + if (!nameMatch && !typeMatch) return false; + } + + return true; + } + + function collectTransportationLinesGeojson( + transportations: any[] + ): { type: 'FeatureCollection'; features: GeoJSON.Feature[] } | null { + const features = transportations + .map(transportationToLineFeature) + .filter(Boolean) as GeoJSON.Feature[]; + + if (features.length === 0) return null; + return { type: 'FeatureCollection', features }; + } + function getActivityDate(activity: any, visit?: any): string | null { return ( activity?.start_date || @@ -380,6 +437,17 @@ startDate: startDateFilter || collection?.start_date || '', endDate: endDateFilter || collection?.end_date || '' }); + $: transportationLinesGeoJson = showTransportation + ? collectTransportationLinesGeojson( + (collection?.transportations || []).filter((t) => + transportationMatchesFilters(t, { + startDate: startDateFilter, + endDate: endDateFilter, + search: searchQuery.trim() + }) + ) + ) + : null; $: trailsGeoJson = collectTrailGeojson(collection); $: trailCount = (collection?.locations || []).reduce( (count, loc) => count + (loc.trails || []).filter((trail) => trail.geojson).length, @@ -1042,6 +1110,24 @@ {/if} + {#if transportationLinesGeoJson} + + + + {/if} + {#if canModify && newMarker}
import('../locales/tr.json')); register('uk', () => import('../locales/uk.json')); register('hu', () => import('../locales/hu.json')); + register('ca', () => import('../locales/ca.json')); + register('cs', () => import('../locales/cs.json')); let locales = [ 'en', @@ -41,12 +43,16 @@ 'ru', 'ja', 'ar', + 'pt', 'pt-br', 'ro', 'sk', 'tr', 'uk', - 'hu' + 'hu', + 'ca', + 'cs', + 'ta' ]; if (browser) {