From 5e19a4e8bb179bbcd099d5485927d85b3569fe69 Mon Sep 17 00:00:00 2001 From: Christian Beutel <> Date: Thu, 29 Feb 2024 23:26:18 +0100 Subject: [PATCH] adds i18n --- .gitignore | 5 +- search/init.py | 43 +++ web/package-lock.json | 278 ++++++++++++-- web/package.json | 1 + web/src/hooks.client.ts | 6 +- web/src/hooks.server.ts | 18 +- web/src/lib/components/base/modal.svelte | 4 +- web/src/lib/components/confirm_modal.svelte | 15 +- .../empty_states/empty_state_search.svelte | 3 +- web/src/lib/components/footer.svelte | 16 +- web/src/lib/components/list/list_card.svelte | 9 +- web/src/lib/components/list/list_modal.svelte | 25 +- .../components/list/list_select_modal.svelte | 11 +- web/src/lib/components/nav_bar.svelte | 46 ++- web/src/lib/components/photo_card.svelte | 5 +- .../summit_log/summit_log_card.svelte | 11 +- .../summit_log/summit_log_modal.svelte | 20 +- .../trail/map_with_elevation.svelte | 111 ++++++ .../lib/components/trail/trail_card.svelte | 6 +- .../components/trail/trail_dropdown.svelte | 136 +++++++ .../trail/trail_filter_panel.svelte | 35 +- .../lib/components/trail/trail_list.svelte | 18 +- .../components/trail/trail_list_item.svelte | 6 +- .../components/waypoint/waypoint_card.svelte | 11 +- .../components/waypoint/waypoint_modal.svelte | 20 +- web/src/lib/i18n/index.ts | 14 + web/src/lib/i18n/locales/de.json | 96 +++++ web/src/lib/i18n/locales/en.json | 96 +++++ web/src/lib/stores/user_store.ts | 22 +- web/src/lib/util/authorization_util.ts | 10 + web/src/lib/util/format_util.ts | 35 +- .../vendor/leaflet-elevation/src/control.js | 361 +++++++++--------- .../vendor/leaflet-elevation/src/index.css | 17 +- web/src/routes/+layout.svelte | 13 +- web/src/routes/+layout.ts | 8 + web/src/routes/+page.svelte | 27 +- web/src/routes/lists/+page.svelte | 28 +- web/src/routes/login/+page.svelte | 16 +- web/src/routes/map/+page.svelte | 23 +- web/src/routes/map/trail/[id]/+page.svelte | 157 ++++---- web/src/routes/profile/+page.svelte | 152 ++++++-- web/src/routes/register/+page.svelte | 20 +- web/src/routes/trail/edit/[id]/+page.svelte | 53 ++- web/src/routes/trail/view/[id]/+page.svelte | 145 ++----- web/src/routes/trails/+page.svelte | 6 +- 45 files changed, 1520 insertions(+), 638 deletions(-) create mode 100644 search/init.py create mode 100644 web/src/lib/components/trail/map_with_elevation.svelte create mode 100644 web/src/lib/components/trail/trail_dropdown.svelte create mode 100644 web/src/lib/i18n/index.ts create mode 100644 web/src/lib/i18n/locales/de.json create mode 100644 web/src/lib/i18n/locales/en.json create mode 100644 web/src/lib/util/authorization_util.ts create mode 100644 web/src/routes/+layout.ts diff --git a/.gitignore b/.gitignore index 3e8bbfc0..2a2442b4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ .DS_Store .vscode/ -search/ \ No newline at end of file + +search/meilisearch +search/data.ms +search/dumps \ No newline at end of file diff --git a/search/init.py b/search/init.py new file mode 100644 index 00000000..0d9c0f49 --- /dev/null +++ b/search/init.py @@ -0,0 +1,43 @@ +from meilisearch import Client +import json + +MEILISEARCH_URL='http://localhost:7700' +MEILISEARCH_API_KEY='p2gYZAWODOrwTPr4AYoahCZ9CI8y9bUd0yQLGk-E3m8' + +client = Client(MEILISEARCH_URL, MEILISEARCH_API_KEY) + +def init(): + client.create_index('cities500', {'primaryKey': 'id'}) + + client.index('cities500').update_settings({ + 'sortableAttributes': ['_geo',], + 'filterableAttributes': ['_geo'] + }) + + client.create_index('trails', {'primaryKey': 'id'}) + + client.index('trails').update_settings({ + 'sortableAttributes': ['name', 'distance', 'elevation_gain', 'created',], + 'filterableAttributes': ['category', 'distance', 'elevation_gain', 'completed', '_geo', 'public', 'author'] + }) + + + json_file = open('cities500.json', encoding='utf-8') + cities = json.load(json_file) + + client.index('cities500').add_documents(cities) + +def generate_public_token(): + search_key = client.get_keys().results[0] + + search_rules = { + 'trails': { + 'filter': 'public=true' + }, + 'cities500': {} + } + token = client.generate_tenant_token(api_key_uid=search_key.uid, search_rules=search_rules, api_key=search_key.key) + + print(token) + +generate_public_token() \ No newline at end of file diff --git a/web/package-lock.json b/web/package-lock.json index 4487a15b..7de68033 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -22,6 +22,7 @@ "nouislider": "^15.7.1", "photoswipe": "^5.4.3", "pocketbase": "^0.21.0", + "svelte-i18n": "^4.0.0", "three": "^0.161.0", "yup": "^1.3.3" }, @@ -74,7 +75,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "aix" @@ -90,7 +90,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -106,7 +105,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -122,7 +120,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "android" @@ -138,7 +135,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -154,7 +150,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -170,7 +165,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -186,7 +180,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -202,7 +195,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -218,7 +210,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -234,7 +225,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "linux" @@ -250,7 +240,6 @@ "cpu": [ "loong64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -266,7 +255,6 @@ "cpu": [ "mips64el" ], - "dev": true, "optional": true, "os": [ "linux" @@ -282,7 +270,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -298,7 +285,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -314,7 +300,6 @@ "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" @@ -330,7 +315,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -346,7 +330,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "netbsd" @@ -362,7 +345,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "openbsd" @@ -378,7 +360,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "sunos" @@ -394,7 +375,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -410,7 +390,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -426,7 +405,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -435,6 +413,50 @@ "node": ">=12" } }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz", + "integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==", + "dependencies": { + "@formatjs/intl-localematcher": "0.5.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz", + "integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.6.tgz", + "integrity": "sha512-etVau26po9+eewJKYoiBKP6743I1br0/Ie00Pb/S/PtmYfmjTcOn2YCh2yNkSZI12h6Rg+BOgQYborXk46BvkA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/icu-skeleton-parser": "1.8.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.0.tgz", + "integrity": "sha512-QWLAYvM0n8hv7Nq5BEs4LKIjevpVpbGLAJgOaYzg9wABEoX1j0JO1q2/jVkO6CVlq0dbsxZCngS5aXbysYueqA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz", + "integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@fortawesome/fontawesome-free": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz", @@ -1328,6 +1350,21 @@ "fsevents": "~2.3.2" } }, + "node_modules/cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/code-red": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", @@ -1442,6 +1479,15 @@ "node": ">=4" } }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "node_modules/date-fns": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.3.1.tgz", @@ -1484,7 +1530,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1551,17 +1596,61 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, "node_modules/es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", "dev": true }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "node_modules/esbuild": { "version": "0.19.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", - "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -1610,6 +1699,25 @@ "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", "dev": true }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esniff/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -1618,6 +1726,15 @@ "@types/estree": "^1.0.0" } }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -1641,6 +1758,19 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -1797,14 +1927,12 @@ "node_modules/globalyzer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", - "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", - "dev": true + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" }, "node_modules/globrex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" }, "node_modules/graceful-fs": { "version": "4.2.11", @@ -1875,6 +2003,17 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/intl-messageformat": { + "version": "10.5.11", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.11.tgz", + "integrity": "sha512-eYq5fkFBVxc7GIFDzpFQkDOZgNayNTQn4Oufe8jw6YY6OHVw70/4pA3FyCsQ0Gb2DnvEJEMmN2tOaXUGByM+kg==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/fast-memoize": "2.2.0", + "@formatjs/icu-messageformat-parser": "2.7.6", + "tslib": "^2.4.0" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1938,6 +2077,11 @@ "node": ">=0.12.0" } }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, "node_modules/is-reference": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", @@ -2075,6 +2219,14 @@ "node": "14 || >=16.14" } }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, "node_modules/magic-string": { "version": "0.30.5", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", @@ -2099,6 +2251,21 @@ "cross-fetch": "^3.1.6" } }, + "node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2216,7 +2383,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "dev": true, "engines": { "node": ">=4" } @@ -2265,6 +2431,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -2891,7 +3062,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dev": true, "dependencies": { "mri": "^1.1.0" }, @@ -3275,6 +3445,34 @@ "svelte": "^3.19.0 || ^4.0.0" } }, + "node_modules/svelte-i18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-4.0.0.tgz", + "integrity": "sha512-4vivjKZADUMRIhTs38JuBNy3unbnh9AFRxWFLxq62P4NHic+/BaIZZlAsvqsCdnp7IdJf5EoSiH6TNdItcjA6g==", + "dependencies": { + "cli-color": "^2.0.3", + "deepmerge": "^4.2.2", + "esbuild": "^0.19.2", + "estree-walker": "^2", + "intl-messageformat": "^10.5.3", + "sade": "^1.8.1", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-i18n": "dist/cli.js" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "svelte": "^3 || ^4" + } + }, + "node_modules/svelte-i18n/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, "node_modules/svelte-preprocess": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.3.tgz", @@ -3421,6 +3619,15 @@ "three": ">= 0.151.0" } }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "node_modules/tiny-case": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", @@ -3430,7 +3637,6 @@ "version": "0.2.9", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", - "dev": true, "dependencies": { "globalyzer": "0.1.0", "globrex": "^0.1.2" @@ -3527,8 +3733,12 @@ "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, "node_modules/type-detect": { "version": "4.0.8", diff --git a/web/package.json b/web/package.json index 4f3777d7..5758f012 100644 --- a/web/package.json +++ b/web/package.json @@ -45,6 +45,7 @@ "nouislider": "^15.7.1", "photoswipe": "^5.4.3", "pocketbase": "^0.21.0", + "svelte-i18n": "^4.0.0", "three": "^0.161.0", "yup": "^1.3.3" } diff --git a/web/src/hooks.client.ts b/web/src/hooks.client.ts index 78ecc118..19ea1fe5 100644 --- a/web/src/hooks.client.ts +++ b/web/src/hooks.client.ts @@ -1,8 +1,8 @@ import { pb } from '$lib/pocketbase' -import { currentUser } from '$lib/stores/user_store' +import { currentUser, type User } from '$lib/stores/user_store' pb.authStore.loadFromCookie(document.cookie) pb.authStore.onChange(() => { - currentUser.set(pb.authStore.model) + currentUser.set(pb.authStore.model as User) document.cookie = pb.authStore.exportToCookie({ httpOnly: false }) -}, true) \ No newline at end of file +}, true) diff --git a/web/src/hooks.server.ts b/web/src/hooks.server.ts index cd4d7e2e..ba4491a8 100644 --- a/web/src/hooks.server.ts +++ b/web/src/hooks.server.ts @@ -1,10 +1,20 @@ import { regenerateInstance } from '$lib/meilisearch' import { pb } from '$lib/pocketbase' -import type { Handle } from '@sveltejs/kit' +import { isRouteProtected } from '$lib/util/authorization_util' +import { redirect, type Handle } from '@sveltejs/kit' +import { locale } from 'svelte-i18n' export const handle: Handle = async ({ event, resolve }) => { // load the store data from the request cookie string pb.authStore.loadFromCookie(event.request.headers.get('cookie') || '') + + const url = new URL(event.request.url); + + // validate the user existence and if the path is acceesible + if (!pb.authStore.model && isRouteProtected(url.pathname)) { + throw redirect(302, '/login'); + } + regenerateInstance(); try { // get an up-to-date auth store state by verifying and refreshing the loaded auth model (if any) @@ -19,6 +29,12 @@ export const handle: Handle = async ({ event, resolve }) => { event.locals.pb = pb event.locals.user = pb.authStore.model + const lang = pb.authStore.model?.language ?? event.request.headers.get('accept-language')?.split(',')[0] + + if (lang) { + locale.set(lang) + } + const response = await resolve(event) // send back the default 'pb_auth' cookie to the client with the latest store state diff --git a/web/src/lib/components/base/modal.svelte b/web/src/lib/components/base/modal.svelte index 63b48482..78678c12 100644 --- a/web/src/lib/components/base/modal.svelte +++ b/web/src/lib/components/base/modal.svelte @@ -1,7 +1,7 @@ @@ -10,5 +11,5 @@ alt="Empty State showing a wanderer going into the distance" /> -
Category
+{$_("category")}
{#each categories as category, i}Near
+{$_("near")}
- Radius: - {formatMeters(filter.near.radius)} + {$_("radius")}: + {formatDistance(filter.near.radius)}
Distance
+{$_("distance")}
Elevation Gain
+{$_("elevation-gain")}
Completed
+{$_("completed")}
Sort
+{$_('sort')}
Display as
+{$_('display-as')}