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) {