Compare commits

...

92 Commits

Author SHA1 Message Date
331d737796 🚀RELEASE v0.12.5
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-08 19:30:20 +02:00
ef81b8adf9 Merge pull request 'Added runner team's parentorg name to runenr overciew' (#129) from feature/128-runner_orgs into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #129
2021-04-08 17:29:27 +00:00
8a7d635cef Switched to html entity
ref #128
2021-04-08 18:00:47 +02:00
4c259c1eef Added runner team's parentorg name to runenr overciew
ref #128
2021-04-08 17:58:49 +02:00
5b4ede5e2f 🚀RELEASE v0.12.4
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-08 17:34:32 +02:00
d0ab3dda78 🚑 [HOTFIX] - drop "svelte-infinite-loading"
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-08 17:34:04 +02:00
d9cf51b4bb 🚀RELEASE v0.12.3
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-08 17:30:23 +02:00
aa17f24220 new license file version [CI SKIP] 2021-04-08 15:28:50 +00:00
cf60edf7d4 Merge pull request 'fix' (#126) from bugfix/125-mobile into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #126
close #125
2021-04-08 15:27:22 +00:00
ffbc243194 custom css fix for collapsed_navigation
ref #125
2021-04-07 21:44:29 +02:00
b6b07cf30c 🐞 bugfix for svelte x tailwind class names
ref #125
2021-04-07 21:35:01 +02:00
495a6b22bd almost fixed... 2021-04-07 21:28:21 +02:00
0acaffbdfa fix
ref #125
2021-04-07 20:25:04 +02:00
6043bc4517 🚀RELEASE v0.12.2
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-07 20:11:21 +02:00
e6ed066e3f Merge pull request 'feature/110-virtual_list' (#124) from feature/110-virtual_list into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #124
2021-04-07 18:10:02 +00:00
ee4e8655b8 Merge branch 'dev' into feature/110-virtual_list 2021-04-07 20:09:35 +02:00
37970d2be6 pre-merge fixes
ref #110
2021-04-07 18:59:46 +02:00
1376788016 updated virtual scroll list 2021-04-07 18:38:52 +02:00
4cad86cf85 fixed height table 2021-04-07 18:19:58 +02:00
6304116edb wip on virtuallist 2021-04-06 22:16:24 +02:00
834ff8fa63 🚀RELEASE v0.12.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-06 16:47:37 +02:00
1f428a535e Merge pull request 'ImportRunnerModal Cancel Button feature/122-import_cancel' (#123) from feature/112-import_cancel into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #123
2021-04-06 14:42:37 +00:00
0c40966970 Added cancel button for the first stage of runner import
ref #112
2021-04-05 16:23:24 +02:00
9da071fe9b Escape now triggers foll modal close (including reset) instead of just hiding th modal
ref #112
2021-04-05 16:14:43 +02:00
892a04f289 🚀RELEASE v0.12.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-05 16:09:17 +02:00
27cc9727f1 Fixed package version
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-05 16:08:41 +02:00
f0738d451b Merge pull request 'Implmented certificate generation feature/119-Certificate_generation' (#120) from feature/119-Certificate_generation into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #120
2021-04-05 14:05:38 +00:00
9e6a8daf2c Sorted translations 🌍
ref #119
2021-04-05 16:04:44 +02:00
bfacfec765 The PFS Prefixes now get translated via i18n
ref #119
2021-04-05 16:04:26 +02:00
0bae5bf32b sponsoring pdf names now include their locale
ref #119
2021-04-05 15:37:12 +02:00
22b09d16d0 Cleaned up generation strings and added the schem for single runner generations for sponsoring contracts
ref #119
2021-04-05 15:36:01 +02:00
9c867e106e Cleaned up generation strings and added the schem for single runner generations for cards
ref #119
2021-04-05 15:33:55 +02:00
304f28a3c1 certificate pdf names now include their locale
ref #119
2021-04-05 15:31:52 +02:00
d65d3793de Changed the basic nameing generation for runenr certificate files
ref #119
2021-04-05 15:31:01 +02:00
3638d87bd2 Runnercard pdfs now include their locale
ref #119
2021-04-05 15:28:13 +02:00
b97a92860d Fixed wrong permissiong getting checked
ref #119
2021-04-05 15:24:42 +02:00
7c86a5eeb3 added missing/ wrong translations + formatting!
ref #119
2021-04-05 12:02:18 +02:00
d23dbaaf69 Removed useless console.log
ref #119
2021-04-03 20:05:27 +02:00
e6ffc371e1 Certificate generation from org detail
ref #119
2021-04-03 20:03:57 +02:00
3177c6eaa3 Certificate generation from org overview
ref #119
2021-04-03 20:02:52 +02:00
acd2f0519d Certificate generation from team detail
ref #119
2021-04-03 20:00:51 +02:00
18ec100c33 Certificate generation from team overview
ref #119
2021-04-03 19:59:34 +02:00
fa55fce76e Merge branch 'feature/119-Certificate_generation' of git.odit.services:lfk/frontend into feature/119-Certificate_generation 2021-04-03 19:59:20 +02:00
f47d5e347d Copy-paste fix
ref #119
2021-04-03 19:59:18 +02:00
7488a8b597 Copy-paste fix
ref #119
2021-04-03 19:58:24 +02:00
2e3ac154be Implemented generation for orgs
ref #119
2021-04-03 19:52:41 +02:00
2472640755 Implemented generation for teams
ref #119
2021-04-03 19:51:01 +02:00
7b685d6cad Added certificate generation from runner overview and detail
ref #119
2021-04-03 19:48:31 +02:00
17f6f4e616 Added i18n
ref #119
2021-04-03 19:46:17 +02:00
48cfc15cfb Removed useless console log
ref #119
2021-04-03 19:44:57 +02:00
bb9b779cee You can now generate certificates from the runner overview
ref #119
2021-04-03 19:44:26 +02:00
af63ce67ae Added basic certificate generation component
ref #119
2021-04-03 19:38:54 +02:00
5cc4871ec4 new license file version [CI SKIP] 2021-04-03 17:18:28 +00:00
c8cfe669b8 Merge pull request 'feature/108_vite_migration' (#118) from feature/108_vite_migration into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #118
close #108
2021-04-03 17:17:23 +00:00
8b74d6d759 bump @odit/lfk-client-js@0.10.1
ref #108
2021-04-03 19:16:53 +02:00
a9227768de 🐞 fix await for esNext
ref #108
2021-04-03 19:13:05 +02:00
d966e1d4de Merge branch 'dev' into feature/108_vite_migration
# Conflicts:
#	index.html
#	package.json
#	public/licenses.json
#	src/App.svelte
#	src/components/orgs/OrgOverview.svelte
#	src/components/teams/TeamsOverview.svelte
2021-04-03 19:10:10 +02:00
ceb2146c1b 🔨 dev container open
ref #108
2021-04-03 18:31:03 +02:00
8d006d8c74 version bump: vite-plugin-windicss@0.12.2
ref #108
2021-04-03 18:22:00 +02:00
777304f259 🔨🔥 alpine based devcontainer with working yarn PnP
ref #108
2021-04-02 21:57:56 +02:00
12433f7c23 🧹 reorder + fix package
ref #108
2021-04-02 21:56:57 +02:00
44b53da345 🚚 move @svitejs/vite-plugin-svelte to @sveltejs/vite-plugin-svelte
ref #108
2021-04-02 21:47:43 +02:00
ab45fc144e upgrade vite-plugin-windicss@0.12.1
ref #108
2021-04-02 21:20:48 +02:00
e99e9e0708 update licenses.json
ref #108
2021-04-02 21:20:05 +02:00
467404bfc8 🐞 fix main.js linking
ref #108
2021-04-02 21:19:49 +02:00
ce50fa2a62 🧹 drop unused dependencies
ref #108
2021-04-02 21:19:29 +02:00
10a011d842 🐞 fix vite config for production system
ref #108
2021-04-02 21:07:16 +02:00
5352410d0c 🐞 fix NGINX config
ref #108
2021-04-02 21:06:57 +02:00
c5d155396a 💾 prevent env.js from being cached
ref #108
2021-04-01 19:35:27 +02:00
93187099d3 🔨 re-added VS Code devcontainer config
ref #108
2021-04-01 19:35:10 +02:00
aa24b1dce5 📃 added readme
ref #108
2021-04-01 19:32:10 +02:00
eb3ede9593 fix dev script
ref #108
2021-04-01 19:30:31 +02:00
d7fecfbd0b version bumps
ref #108
2021-04-01 19:30:15 +02:00
b065b4ff21 📍 version bump + pin
ref #108
2021-03-30 18:36:20 +02:00
87370d24be Merge branch 'dev' of git.odit.services:lfk/frontend into dev
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-30 18:29:03 +02:00
8f8b9988ad new license file version [CI SKIP] 2021-03-30 16:29:19 +00:00
f8ccf4f5d8 🚀RELEASE v0.11.0 2021-03-30 18:28:53 +02:00
25d8b86efd Merge pull request 'Generate and print bulk blank cards feature/116-download_blanc_cards' (#117) from feature/116-download_blanc_cards into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #117
2021-03-30 16:27:48 +00:00
0cd3e937d8 bump vite to 2.1.3
ref #108
2021-03-30 18:21:18 +02:00
89bb9c215e Sorted translations
ref #116
2021-03-29 18:52:25 +02:00
2d18686ce7 Bumped lfk client js version
ref #116
2021-03-29 18:52:10 +02:00
1d999d4910 Now returning cards on creation with pdf
ref #116
2021-03-29 18:23:17 +02:00
7dfaa7579a Bumped lfk-client-js
ref #116
2021-03-29 18:15:00 +02:00
08cb079e97 Fixed button styling
ref #116
2021-03-29 17:57:34 +02:00
450aa83592 Merge branch 'feature/116-download_blanc_cards' of git.odit.services:lfk/frontend into feature/116-download_blanc_cards
# Conflicts:
#	src/components/cards/AddCardBulkModal.svelte
2021-03-29 17:47:18 +02:00
0614c76e92 Added button (including translations
ref #116
2021-03-29 17:46:56 +02:00
6be2ee626a package cleanup 2021-03-26 21:22:46 +01:00
008027db0e added windicss settings for VSCode
ref #108
2021-03-25 18:57:33 +01:00
aec5e3473e for await fix - ViteJS
ref #108
2021-03-25 18:56:18 +01:00
95c8fde72f updated default entrypoint
ref #108
2021-03-25 18:56:02 +01:00
0f32968fae 🐳 new Dockerfiles
ref #108
2021-03-25 18:55:43 +01:00
ae79e9fea1 basic ViteJS migration
ref #108
2021-03-25 18:55:24 +01:00
40 changed files with 1909 additions and 1381 deletions

6
.devcontainer/Dockerfile Normal file
View File

@@ -0,0 +1,6 @@
FROM mcr.microsoft.com/vscode/devcontainers/base:alpine-3.12
RUN apk update
RUN apk add --upgrade nodejs-current npm
RUN npm i -g yarn rimraf
RUN rimraf node_modules
RUN yarn set version berry

View File

@@ -0,0 +1,20 @@
{
"name": "Node.js",
"build": {
"dockerfile": "Dockerfile"
},
"settings": {
"terminal.integrated.shell.linux": "/bin/sh"
},
"extensions": [
"dbaeumer.vscode-eslint",
"2gua.rainbow-brackets",
"christian-kohler.npm-intellisense",
"remimarsal.prettier-now",
"svelte.svelte-vscode",
"lokalise.i18n-ally",
"fivethree.vscode-svelte-snippets",
"voorjaar.windicss-intellisense"
],
"postCreateCommand": "yarn && yarn dev --open"
}

View File

@@ -1,3 +1 @@
public/env.sample.js public/env.sample.js
public/workbox-*.js
public/workbox-*.js.map

9
.gitignore vendored
View File

@@ -1,11 +1,10 @@
node_modules node_modules
build
package-lock.json package-lock.json
yarn.lock yarn.lock
*.map *.map
public/env.js public/env.js
public/sw.js
public/index.html
public/workbox-*.js
svelte.config.js
public/index.html public/index.html
/dist
.yarn
.pnp.js
.yarnrc.yml

View File

@@ -5,7 +5,8 @@
"remimarsal.prettier-now", "remimarsal.prettier-now",
"svelte.svelte-vscode", "svelte.svelte-vscode",
"lokalise.i18n-ally", "lokalise.i18n-ally",
"fivethree.vscode-svelte-snippets" "fivethree.vscode-svelte-snippets",
"voorjaar.windicss-intellisense"
], ],
"unwantedRecommendations": [ "unwantedRecommendations": [
"antfu.i18n-ally" "antfu.i18n-ally"

View File

@@ -1,4 +1,5 @@
{ {
"i18n-ally.localesPaths": "src/locales", "i18n-ally.localesPaths": "src/locales",
"i18n-ally.keystyle": "nested" "i18n-ally.keystyle": "nested",
"windicss.enableCodeFolding": false,
} }

View File

@@ -2,12 +2,137 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC. All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [0.12.5](https://git.odit.services/lfk/frontend/compare/0.12.4...0.12.5)
- Merge pull request 'Added runner team's parentorg name to runenr overciew' (#129) from feature/128-runner_orgs into dev [`ef81b8a`](https://git.odit.services/lfk/frontend/commit/ef81b8adf9bef685a55936d7544bf645c0d6ecbe)
- Switched to html entity [`8a7d635`](https://git.odit.services/lfk/frontend/commit/8a7d635cef2d465e70c84e1f7a7b90b98a8dbab1)
- Added runner team's parentorg name to runenr overciew [`4c259c1`](https://git.odit.services/lfk/frontend/commit/4c259c1eef2b0166ce6a8493d0c9e9d5ede11146)
#### [0.12.4](https://git.odit.services/lfk/frontend/compare/0.12.3...0.12.4)
> 8 April 2021
- 🚀RELEASE v0.12.4 [`5b4ede5`](https://git.odit.services/lfk/frontend/commit/5b4ede5e2f6a26b475a7a4b430a4146d21fb9671)
- 🚑 [HOTFIX] - drop "svelte-infinite-loading" [`d0ab3dd`](https://git.odit.services/lfk/frontend/commit/d0ab3dda78bbad2cea18a2491056530897d56607)
#### [0.12.3](https://git.odit.services/lfk/frontend/compare/0.12.2...0.12.3)
> 8 April 2021
- Merge pull request 'fix' (#126) from bugfix/125-mobile into dev [`#125`](https://git.odit.services/lfk/frontend/issues/125)
- almost fixed... [`495a6b2`](https://git.odit.services/lfk/frontend/commit/495a6b22bd8036593f390bdb862d325524cefbcc)
- 🐞 bugfix for svelte x tailwind class names [`b6b07cf`](https://git.odit.services/lfk/frontend/commit/b6b07cf30cc6533bd5dbfec1f813c16fde85634d)
- fix [`0acaffb`](https://git.odit.services/lfk/frontend/commit/0acaffbdfa359e52654a5afe2788aa59fe6f9036)
- 🚀RELEASE v0.12.3 [`d9cf51b`](https://git.odit.services/lfk/frontend/commit/d9cf51b4bbc2136594a03c5d0eeb8cb3f3440b2a)
- custom css fix for collapsed_navigation [`ffbc243`](https://git.odit.services/lfk/frontend/commit/ffbc243194c7faeb4fe61c12711a1c441c3994ef)
- new license file version [CI SKIP] [`aa17f24`](https://git.odit.services/lfk/frontend/commit/aa17f242209f7e7cecff774ace7a35b581adec1f)
#### [0.12.2](https://git.odit.services/lfk/frontend/compare/0.12.1...0.12.2)
> 7 April 2021
- 🚀RELEASE v0.12.2 [`6043bc4`](https://git.odit.services/lfk/frontend/commit/6043bc45174d51ab110b0ed10a8679d96127ab87)
- Merge pull request 'feature/110-virtual_list' (#124) from feature/110-virtual_list into dev [`e6ed066`](https://git.odit.services/lfk/frontend/commit/e6ed066e3ffabba6519f94d801d21a27819d0492)
- wip on virtuallist [`6304116`](https://git.odit.services/lfk/frontend/commit/6304116edb7f5e3c7b67c15e0b1740d34c513155)
- fixed height table [`4cad86c`](https://git.odit.services/lfk/frontend/commit/4cad86cf852468428d77103d052c6974b17c34c3)
- pre-merge fixes [`37970d2`](https://git.odit.services/lfk/frontend/commit/37970d2be6b6502701914e41e5bfe2c418438480)
- updated virtual scroll list [`1376788`](https://git.odit.services/lfk/frontend/commit/1376788016e767f006661f8c9e6747781f2dce55)
#### [0.12.1](https://git.odit.services/lfk/frontend/compare/0.12.0...0.12.1)
> 6 April 2021
- 🚀RELEASE v0.12.1 [`834ff8f`](https://git.odit.services/lfk/frontend/commit/834ff8fa63178f36dcacf931c128ba67a3e7bd1b)
- Merge pull request 'ImportRunnerModal Cancel Button feature/122-import_cancel' (#123) from feature/112-import_cancel into dev [`1f428a5`](https://git.odit.services/lfk/frontend/commit/1f428a535e3ae619cbf8db51d04255aac8dd8614)
- Added cancel button for the first stage of runner import [`0c40966`](https://git.odit.services/lfk/frontend/commit/0c409669700d3a8096cc04716154b0fdca458fe5)
- Escape now triggers foll modal close (including reset) instead of just hiding th modal [`9da071f`](https://git.odit.services/lfk/frontend/commit/9da071fe9ba067160334682bf00163e3630fe919)
#### [0.12.0](https://git.odit.services/lfk/frontend/compare/0.11.0...0.12.0)
> 5 April 2021
- Merge pull request 'feature/108_vite_migration' (#118) from feature/108_vite_migration into dev [`#108`](https://git.odit.services/lfk/frontend/issues/108)
- 🚀RELEASE v0.12.0 [`892a04f`](https://git.odit.services/lfk/frontend/commit/892a04f28930481715eb486b1ef4efeb98a6e999)
- Fixed package version [`27cc972`](https://git.odit.services/lfk/frontend/commit/27cc9727f1d02d186c3ccadb06e5b4b1b1d6202d)
- Merge pull request 'Implmented certificate generation feature/119-Certificate_generation' (#120) from feature/119-Certificate_generation into dev [`f0738d4`](https://git.odit.services/lfk/frontend/commit/f0738d451b02e4a298b5f9cb8ab0be16aed10a38)
- The PFS Prefixes now get translated via i18n [`bfacfec`](https://git.odit.services/lfk/frontend/commit/bfacfec76511cae3015f52698fdcbd80a7a15981)
- Sorted translations 🌍 [`9e6a8da`](https://git.odit.services/lfk/frontend/commit/9e6a8daf2c394cf17da532382ec7d049a0f89577)
- added missing/ wrong translations + formatting! [`7c86a5e`](https://git.odit.services/lfk/frontend/commit/7c86a5eeb370a43451d180a09a501066b023b9a0)
- Added i18n [`17f6f4e`](https://git.odit.services/lfk/frontend/commit/17f6f4e616bf57424ee12ad53b939429c02a0171)
- Added basic certificate generation component [`af63ce6`](https://git.odit.services/lfk/frontend/commit/af63ce67ae7d8f8a70706c3bd6755197908996ff)
- basic ViteJS migration [`ae79e9f`](https://git.odit.services/lfk/frontend/commit/ae79e9fea1963e977ef468e8e56f87d68916fadd)
- Implemented generation for orgs [`2e3ac15`](https://git.odit.services/lfk/frontend/commit/2e3ac154be0bf0776cd00f7d510f41ec676ae690)
- Implemented generation for teams [`2472640`](https://git.odit.services/lfk/frontend/commit/2472640755e3e41259a44127a875d00517a25842)
- updated default entrypoint [`95c8fde`](https://git.odit.services/lfk/frontend/commit/95c8fde72fca5cd5a644d51a33dc88e0b59fce92)
- ⏫📍 version bump + pin [`b065b4f`](https://git.odit.services/lfk/frontend/commit/b065b4ff218d07952fa45989e6e2ee7df13e07c1)
- 🧹 reorder + fix package [`12433f7`](https://git.odit.services/lfk/frontend/commit/12433f7c236906fe2b29848a0acaa6be1724da56)
- 🔨 re-added VS Code devcontainer config [`9318709`](https://git.odit.services/lfk/frontend/commit/93187099d32c506329b1437642aae985f2850689)
- 🐳 new Dockerfiles [`0f32968`](https://git.odit.services/lfk/frontend/commit/0f32968fae8b55a13d387918211983d0e61f85ab)
- 📃 added readme [`aa24b1d`](https://git.odit.services/lfk/frontend/commit/aa24b1dce5d6d73c8f42fc57f81b692350bf9665)
- Copy-paste fix [`f47d5e3`](https://git.odit.services/lfk/frontend/commit/f47d5e347d97ee127fa0380620138a9672665cd5)
- 🔨🔥 alpine based devcontainer with working yarn PnP [`777304f`](https://git.odit.services/lfk/frontend/commit/777304f2593df36f4e89d2ba7680add183ff062f)
- Copy-paste fix [`7488a8b`](https://git.odit.services/lfk/frontend/commit/7488a8b597a148c309e1b4499d277fed7f3bf9f4)
- You can now generate certificates from the runner overview [`bb9b779`](https://git.odit.services/lfk/frontend/commit/bb9b779cee909ab85ef52f13be0a917f1c0a9e62)
- Cleaned up generation strings and added the schem for single runner generations for cards [`9c867e1`](https://git.odit.services/lfk/frontend/commit/9c867e106edd68784e6d19743519c1952a0f0bc7)
- Changed the basic nameing generation for runenr certificate files [`d65d379`](https://git.odit.services/lfk/frontend/commit/d65d3793de869bcd6733a1bbdac378d0bc1128b3)
- ⏫ version bumps [`d7fecfb`](https://git.odit.services/lfk/frontend/commit/d7fecfbd0bc01f1cd44dea3c3837e0cc44afab12)
- Cleaned up generation strings and added the schem for single runner generations for sponsoring contracts [`22b09d1`](https://git.odit.services/lfk/frontend/commit/22b09d16d0acc2883e3448dad95ed0f4ea7c6aeb)
- Certificate generation from org overview [`3177c6e`](https://git.odit.services/lfk/frontend/commit/3177c6eaa31636ed4546f4797775a0f0a930f5d1)
- certificate pdf names now include their locale [`304f28a`](https://git.odit.services/lfk/frontend/commit/304f28a3c10bc4745aa5b7c80d7ba0e651540706)
- Runnercard pdfs now include their locale [`3638d87`](https://git.odit.services/lfk/frontend/commit/3638d87bd2ff83618eefda5af18ba19e38e3c2eb)
- 🐞 fix await for esNext [`a922776`](https://git.odit.services/lfk/frontend/commit/a9227768de29305b51d10c8a6e4fa1d39b7d998f)
- Certificate generation from team overview [`18ec100`](https://git.odit.services/lfk/frontend/commit/18ec100c33a1fbab526187e769dbae54d9db0867)
- Added certificate generation from runner overview and detail [`7b685d6`](https://git.odit.services/lfk/frontend/commit/7b685d6cad97d2f7f48c4b19bfc128e1355b70c4)
- package cleanup [`6be2ee6`](https://git.odit.services/lfk/frontend/commit/6be2ee626addaf5113b4b4821bd99a276bf4f329)
- sponsoring pdf names now include their locale [`0bae5bf`](https://git.odit.services/lfk/frontend/commit/0bae5bf32b8687057dca50cde21022ea8c3abee8)
- ✨ update licenses.json [`e99e9e0`](https://git.odit.services/lfk/frontend/commit/e99e9e07089520d5a48021e10d2af7739656641a)
- added windicss settings for VSCode [`008027d`](https://git.odit.services/lfk/frontend/commit/008027db0e2736a9bb9defd67178ab3fe580de04)
- Certificate generation from team detail [`acd2f05`](https://git.odit.services/lfk/frontend/commit/acd2f0519d62e55dad8e9c3c41e77b6967212502)
- ⚡💾 prevent env.js from being cached [`c5d1553`](https://git.odit.services/lfk/frontend/commit/c5d155396a92dfee6d592fb24a936ab521215f6d)
- for await fix - ViteJS [`aec5e34`](https://git.odit.services/lfk/frontend/commit/aec5e3473e687415fbfd69c550d9b012e1b1be43)
- Certificate generation from org detail [`e6ffc37`](https://git.odit.services/lfk/frontend/commit/e6ffc371e1ca2d4451e7dd4a3ca3c05564edb5fb)
- 🧹 drop unused dependencies [`ce50fa2`](https://git.odit.services/lfk/frontend/commit/ce50fa2a62f8ff98e8be9c66432caeebb3952019)
- 🐞 fix NGINX config [`5352410`](https://git.odit.services/lfk/frontend/commit/5352410d0c76fd14575d7beafc6a83f028062efe)
- Fixed wrong permissiong getting checked [`b97a928`](https://git.odit.services/lfk/frontend/commit/b97a92860d71eb0384170e245a67fa3ea3fd8e85)
- new license file version [CI SKIP] [`5cc4871`](https://git.odit.services/lfk/frontend/commit/5cc4871ec4be9f0af07738f6e3d44bdbe31cd25a)
- ⏫ bump @odit/lfk-client-js@0.10.1 [`8b74d6d`](https://git.odit.services/lfk/frontend/commit/8b74d6d759c8481f012c201e2ea0d12b29ddef90)
- 🔨 dev container open ⚡ [`ceb2146`](https://git.odit.services/lfk/frontend/commit/ceb2146c1b08bbe9250e4db7846e06bd89526c21)
- ⏫ version bump: vite-plugin-windicss@0.12.2 [`8d006d8`](https://git.odit.services/lfk/frontend/commit/8d006d8c74d71c43a9031d58f5a8c7fc55ed95fc)
- 🚚 move @svitejs/vite-plugin-svelte to @sveltejs/vite-plugin-svelte [`44b53da`](https://git.odit.services/lfk/frontend/commit/44b53da34516b00671b3e5060ba831e409ac3dd5)
- ⏫ upgrade vite-plugin-windicss@0.12.1 [`ab45fc1`](https://git.odit.services/lfk/frontend/commit/ab45fc144eaf14f63d86ee53c1db4eefd88f9c7f)
- 🐞 fix main.js linking [`467404b`](https://git.odit.services/lfk/frontend/commit/467404bfc87f3c08c5e227f194d71eea7cc48921)
- 🐞 fix vite config for production system [`10a011d`](https://git.odit.services/lfk/frontend/commit/10a011d8426e475105ff5d2d5cf4adca2ef7625c)
- fix dev script [`eb3ede9`](https://git.odit.services/lfk/frontend/commit/eb3ede9593e2e527df3e3a2f81c8e179bb555f51)
- ⏫ bump vite to 2.1.3 [`0cd3e93`](https://git.odit.services/lfk/frontend/commit/0cd3e937d852eeabe43eb6298bfabe20834240b2)
- Removed useless console.log [`d23dbaa`](https://git.odit.services/lfk/frontend/commit/d23dbaaf695a60fe5ebbc9945646a16b5fc45a16)
- Removed useless console log [`48cfc15`](https://git.odit.services/lfk/frontend/commit/48cfc15cfb09096db1bd5ddbe9138b1a604d581f)
#### [0.11.0](https://git.odit.services/lfk/frontend/compare/0.10.0...0.11.0)
> 30 March 2021
- Added button (including translations [`0614c76`](https://git.odit.services/lfk/frontend/commit/0614c76e924b18b512bab59933a26fec07cf483d)
- Added button (including translations [`97e338f`](https://git.odit.services/lfk/frontend/commit/97e338f9d4f388596d550990457254c7fa1a3492)
- Sorted translations [`89bb9c2`](https://git.odit.services/lfk/frontend/commit/89bb9c215e356e0940678f5cabd9e38bc203040e)
- Added function for generating cards with pdf [`c8d6390`](https://git.odit.services/lfk/frontend/commit/c8d639024a5f2f72d6e30d2ce990b08bd71a5471)
- 🚀RELEASE v0.11.0 [`f8ccf4f`](https://git.odit.services/lfk/frontend/commit/f8ccf4f5d8f68ecee31430029889b8ab1ecec682)
- Fixed button styling [`08cb079`](https://git.odit.services/lfk/frontend/commit/08cb079e9798392e26515d559af2637e74deea97)
- Now returning cards on creation with pdf [`1d999d4`](https://git.odit.services/lfk/frontend/commit/1d999d4910acb5efa21b3f9922cdb359babff404)
- new license file version [CI SKIP] [`8f8b998`](https://git.odit.services/lfk/frontend/commit/8f8b9988ad94ee9f3729a3fe6fdb4c558828d892)
- Merge pull request 'Generate and print bulk blank cards feature/116-download_blanc_cards' (#117) from feature/116-download_blanc_cards into dev [`25d8b86`](https://git.odit.services/lfk/frontend/commit/25d8b86efd89c442d1bf308a8743134820acfd1f)
- Added comment [`636f018`](https://git.odit.services/lfk/frontend/commit/636f018daa33b99468a257bfc33477e1e644d081)
- Bumped lfk client js version [`2d18686`](https://git.odit.services/lfk/frontend/commit/2d18686ce782a434ca7bd34c07c36a35b9497273)
- Bumped lfk-client-js [`7dfaa75`](https://git.odit.services/lfk/frontend/commit/7dfaa7579a22b13194fcdd1c02b4437958261472)
#### [0.10.0](https://git.odit.services/lfk/frontend/compare/0.9.1...0.10.0) #### [0.10.0](https://git.odit.services/lfk/frontend/compare/0.9.1...0.10.0)
> 26 March 2021
- Added translations [`79c447b`](https://git.odit.services/lfk/frontend/commit/79c447b4c65e55ebb5af71fb0b09174c36e2cecf) - Added translations [`79c447b`](https://git.odit.services/lfk/frontend/commit/79c447b4c65e55ebb5af71fb0b09174c36e2cecf)
- Sorted translations 🌍 [`5bd3a46`](https://git.odit.services/lfk/frontend/commit/5bd3a463f00abaf2c98ab554f88e5542d01f364a) - Sorted translations 🌍 [`5bd3a46`](https://git.odit.services/lfk/frontend/commit/5bd3a463f00abaf2c98ab554f88e5542d01f364a)
- Reset can now only be triggered if pw is strong enoug [`75d8f73`](https://git.odit.services/lfk/frontend/commit/75d8f7331b6ae78f3979bb62148188a16f83cb8d) - Reset can now only be triggered if pw is strong enoug [`75d8f73`](https://git.odit.services/lfk/frontend/commit/75d8f7331b6ae78f3979bb62148188a16f83cb8d)
- Module now exports functions that check if a password is strong enough and equal to a potential confirmation field [`b2509e9`](https://git.odit.services/lfk/frontend/commit/b2509e9e53ab6b51dfd55e26712e8928160cd64b) - Module now exports functions that check if a password is strong enough and equal to a potential confirmation field [`b2509e9`](https://git.odit.services/lfk/frontend/commit/b2509e9e53ab6b51dfd55e26712e8928160cd64b)
- 🚀RELEASE v0.10.0 [`f7fc196`](https://git.odit.services/lfk/frontend/commit/f7fc1967a50f302af1d8b668628be2f4ab2975a3)
- Added more cirteria to the password strength component [`5fa9939`](https://git.odit.services/lfk/frontend/commit/5fa9939696a35d60d762feb0cebef61d31869218) - Added more cirteria to the password strength component [`5fa9939`](https://git.odit.services/lfk/frontend/commit/5fa9939696a35d60d762feb0cebef61d31869218)
- Now using pw strength component [`6aaf838`](https://git.odit.services/lfk/frontend/commit/6aaf8384512185a3a319ce6b3e2505e910468e64) - Now using pw strength component [`6aaf838`](https://git.odit.services/lfk/frontend/commit/6aaf8384512185a3a319ce6b3e2505e910468e64)
- Added a password strength verification [`ad3bd31`](https://git.odit.services/lfk/frontend/commit/ad3bd312e9a5785f81029ea2b7e302ea1addd988) - Added a password strength verification [`ad3bd31`](https://git.odit.services/lfk/frontend/commit/ad3bd312e9a5785f81029ea2b7e302ea1addd988)

View File

@@ -1,18 +1,14 @@
FROM node:15.5.1-alpine3.12 FROM node:15.5.1-alpine3.12
WORKDIR /app WORKDIR /app
RUN npm i -g pnpm
COPY package.json ./ COPY package.json ./
RUN pnpm i RUN yarn
COPY package.json *.config.js workbox-config.js template-copy.js index.template.html s-config.template.js ./ COPY package.json *.config.js index.html ./
COPY src ./src COPY src ./src
COPY public ./public COPY public ./public
RUN pnpm run build RUN yarn build
# final image # final image
FROM alpine FROM alpine
COPY --from=0 /app/build /app COPY --from=0 /app/dist /app
RUN rm -rf /app/build/_dist_/components
RUN rm -rf /app/build/_dist_/locales
RUN rm -rf /app/build-manifest.json
FROM fholzer/nginx-brotli:v1.19.1 FROM fholzer/nginx-brotli:v1.19.1
COPY --from=1 /app /usr/share/nginx/html COPY --from=1 /app /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf COPY ./nginx.conf /etc/nginx/nginx.conf

22
README.md Normal file
View File

@@ -0,0 +1,22 @@
# @odit/lfk-frontend
## ✒️ Overview
This is an API client for [https://git.odit.services/lfk/backend](@lfk/backend)
- WebApp built with [Svelte](https://svelte.dev), [WindiCSS](https://windicss.org/) (to compile [TailwindCSS](https://tailwindcss.com/)) and [Vite](https://vitejs.dev).
This application is intended for use by admin users/ members only.
## 🚀 Getting Started
```
yarn
```
## Development
```
yarn dev
/
yarn dev --open
```
## Build
```
yarn build
```

View File

@@ -10,14 +10,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Lauf Für Kaya! - Admin" /> <meta name="description" content="Lauf Für Kaya! - Admin" />
<title>Lauf für Kaya! - Admin</title> <title>Lauf für Kaya! - Admin</title>
__TAILWIND_INSERT__
</head> </head>
<body> <body>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.10.0-RELEASE_INFO</span> <span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.12.5-RELEASE_INFO</span>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/env.js"></script> <script src="/env.js"></script>
<script defer type="module" src="/_dist_/index.js"></script> <script type="module" src="/src/main.js"></script>
</body> </body>
</html> </html>

View File

@@ -6,6 +6,15 @@ http {
server { server {
error_page 404 /index.html; error_page 404 /index.html;
root /usr/share/nginx/html; root /usr/share/nginx/html;
location = /index.html {
add_header Cache-Control 'no-store';
}
location = / {
add_header Cache-Control 'no-store';
}
location = /env.js {
add_header Cache-Control 'no-store';
}
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }

View File

@@ -1,46 +1,40 @@
{ {
"name": "@odit/lfk-frontend", "name": "@odit/lfk-frontend",
"version": "0.10.0", "version": "0.12.5",
"scripts": { "scripts": {
"i18n-order": "node order.js", "i18n-order": "node order.js",
"dev:all": "yarn prebuild && snowpack dev", "dev": "vite",
"dev": "cross-env NODE_ENV_ODIT=development_fast node template-copy.js && yarn build:sw && snowpack dev", "build": "vite build",
"build": "yarn prebuild && snowpack build",
"prebuild": "cross-env NODE_ENV_ODIT=production node template-copy.js && yarn build:sw",
"build:sw": "workbox generateSW workbox-config.js",
"release": "release-it", "release": "release-it",
"licenses:export": "license-exporter --json -o public" "licenses:export": "license-exporter --json -o public"
}, },
"license": "CC-BY-NC-SA-4.0", "license": "CC-BY-NC-SA-4.0",
"dependencies": {
"@odit/lfk-client-js": "0.8.0",
"check-password-strength": "^2.0.2",
"csvtojson": "^2.0.10",
"gridjs": "3.3.0",
"localforage": "1.9.0",
"marked": "^2.0.1",
"svelte-focus-trap": "1.0.1",
"svelte-i18n": "3.3.7",
"svelte-select": "^3.17.0",
"tailwindcss": "2.0.3",
"tinro": "0.6.1",
"toastify-js": "1.9.3",
"validator": "13.5.2",
"xlsx": "^0.16.9"
},
"devDependencies": { "devDependencies": {
"@odit/license-exporter": "^0.0.11", "check-password-strength": "2.0.2",
"@snowpack/plugin-svelte": "3.5.2", "@odit/lfk-client-js": "0.10.1",
"auto-changelog": "^2.2.1", "@odit/license-exporter": "0.0.11",
"@sveltejs/vite-plugin-svelte": "1.0.0-next.6",
"@types/html-minifier": "4.0.0",
"auto-changelog": "2.2.1",
"autoprefixer": "10.2.5", "autoprefixer": "10.2.5",
"cross-env": "^7.0.3", "csvtojson": "2.0.10",
"postcss": "8.2.8", "gridjs": "3.4.0",
"postcss-load-config": "3.0.1", "html-minifier": "4.0.0",
"release-it": "^14.4.1", "localforage": "1.9.0",
"snowpack": "3.0.13", "marked": "2.0.1",
"svelte": "3.35.0", "release-it": "14.5.1",
"svelte-preprocess": "4.6.9", "svelte": "3.37.0",
"workbox-cli": "6.1.2" "svelte-focus-trap": "1.2.0",
"svelte-i18n": "3.3.9",
"svelte-preprocess": "4.7.0",
"svelte-select": "3.17.0",
"tailwindcss": "2.1.1",
"tinro": "0.6.1",
"toastify-js": "1.10.0",
"validator": "13.5.2",
"vite": "2.1.5",
"vite-plugin-windicss": "0.12.5",
"xlsx": "0.16.9"
}, },
"release-it": { "release-it": {
"git": { "git": {
@@ -56,7 +50,7 @@
"publish": false "publish": false
}, },
"hooks": { "hooks": {
"after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node versionbuilder.js && git add index.template.html && node order.js && git add src/locales" "after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node versionbuilder.js && git add index.html && node order.js && git add src/locales"
} }
} }
} }

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +0,0 @@
const sveltePreprocess = require('svelte-preprocess');
const preprocess = sveltePreprocess(__insert__);
module.exports = {
preprocess
};

View File

@@ -1,26 +0,0 @@
/** @type {import("snowpack").SnowpackUserConfig } */
module.exports = {
mount: {
public: '/',
src: '/_dist_'
},
plugins: [ '@snowpack/plugin-svelte' ],
routes: [
/* Enable an SPA Fallback in development: */
{ match: 'routes', src: '.*', dest: '/index.html' }
],
packageOptions: {
/* ... */
sourceMap: false
},
devOptions: {
/* ... */
},
buildOptions: {
/* ... */
},
alias: {
/* ... */
},
optimize: { bundle: true, minify: true }
};

View File

@@ -1,224 +1,221 @@
<script> <script>
import "./TailwindStyles.svelte"; import "toastify-js/src/toastify.css";
import "toastify-js/src/toastify.css"; import "gridjs/dist/theme/mermaid.css";
import "gridjs/dist/theme/mermaid.css"; import { Route, router } from "tinro";
import { Route, router } from "tinro"; router.subscribe((routeInfo) => {
router.subscribe((routeInfo) => { window.scrollTo(0, 0);
window.scrollTo(0, 0); });
}); if (config.prefersHashRouting) {
if (config.prefersHashRouting) { if (config.prefersHashRouting === true) {
if (config.prefersHashRouting === true) { router.useHashNavigation();
router.useHashNavigation(); }
} }
} import localForage from "localforage";
import localForage from "localforage"; import { addMessages, init, getLocaleFromNavigator } from "svelte-i18n";
import { addMessages, init, getLocaleFromNavigator } from "svelte-i18n"; import en from "./locales/en.json";
import en from "./locales/en.json"; import de from "./locales/de.json";
import de from "./locales/de.json"; addMessages("en", en);
addMessages("en", en); addMessages("de", de);
addMessages("de", de); init({
init({ fallbackLocale: "en",
fallbackLocale: "en", initialLocale: getLocaleFromNavigator(),
initialLocale: getLocaleFromNavigator(), });
}); localForage.config({
localForage.config({ name: "lfk_admin",
name: "lfk_admin", version: 1.0,
version: 1.0, storeName: "lfk_admin",
storeName: "lfk_admin", description: "LfK! admin dashbaord",
description: "LfK! admin dashbaord", });
}); window.onunhandledrejection = (event) => {
window.onunhandledrejection = (event) => { if (event.reason.toString() == "Error: Unauthorized") {
if (event.reason.toString() == "Error: Unauthorized") { console.log("Found 1");
console.log("Found 1"); localForage.clear();
localForage.clear(); location.replace("/");
location.replace("/"); }
} };
}; //
// import Login from "./components/auth/Login.svelte";
import Login from "./components/auth/Login.svelte"; import Dashboard from "./components/dashboard/Dashboard.svelte";
import Dashboard from "./components/dashboard/Dashboard.svelte"; import store from "./store.js";
import store from "./store.js"; import ForgotPassword from "./components/auth/ForgotPassword.svelte";
import ForgotPassword from "./components/auth/ForgotPassword.svelte"; import MainDashContent from "./components/dashboard/MainDashContent.svelte";
import MainDashContent from "./components/dashboard/MainDashContent.svelte"; import Users from "./components/users/Users.svelte";
import Users from "./components/users/Users.svelte"; import About from "./components/general/About.svelte";
import About from "./components/general/About.svelte"; import Settings from "./components/settings/Settings.svelte";
import Settings from "./components/settings/Settings.svelte"; import Transition from "./components/base/Transition.svelte";
import Transition from "./components/base/Transition.svelte"; import Orgs from "./components/orgs/Orgs.svelte";
import Orgs from "./components/orgs/Orgs.svelte"; import Runners from "./components/runners/Runners.svelte";
import Runners from "./components/runners/Runners.svelte"; import Footer from "./components/general/Footer.svelte";
import Footer from "./components/general/Footer.svelte"; import TracksOverview from "./components/tracks/TracksOverview.svelte";
import TracksOverview from "./components/tracks/TracksOverview.svelte"; import OrgDetail from "./components/orgs/OrgDetail.svelte";
import OrgDetail from "./components/orgs/OrgDetail.svelte"; import Teams from "./components/teams/Teams.svelte";
import Teams from "./components/teams/Teams.svelte"; import { OpenAPI } from "@odit/lfk-client-js";
import { OpenAPI } from "@odit/lfk-client-js"; import UserDetail from "./components/users/UserDetail.svelte";
import UserDetail from "./components/users/UserDetail.svelte"; OpenAPI.BASE = config.baseurl;
OpenAPI.BASE = config.baseurl; import TeamDetail from "./components/teams/TeamDetail.svelte";
import { register as registerSW } from "./swmodule"; import UserPermissions from "./components/users/UserPermissions.svelte";
import TeamDetail from "./components/teams/TeamDetail.svelte"; import GroupPermissions from "./components/groups/GroupPermissions.svelte";
import UserPermissions from "./components/users/UserPermissions.svelte"; import RunnerDetail from "./components/runners/RunnerDetail.svelte";
import GroupPermissions from "./components/groups/GroupPermissions.svelte"; import Imprint from "./components/general/Imprint.svelte";
import RunnerDetail from "./components/runners/RunnerDetail.svelte"; import Privacy from "./components/general/Privacy.svelte";
import Imprint from "./components/general/Imprint.svelte"; import ResetPassword from "./components/auth/ResetPassword.svelte";
import Privacy from "./components/general/Privacy.svelte"; import Contacts from "./components/contacts/Contacts.svelte";
import ResetPassword from "./components/auth/ResetPassword.svelte"; import ContactDetail from "./components/contacts/ContactDetail.svelte";
import Contacts from "./components/contacts/Contacts.svelte"; import Donors from "./components/donors/Donors.svelte";
import ContactDetail from "./components/contacts/ContactDetail.svelte"; import Groups from "./components/groups/Groups.svelte";
import Donors from "./components/donors/Donors.svelte"; import DonorDetail from "./components/donors/DonorDetail.svelte";
import Groups from "./components/groups/Groups.svelte"; import Donations from "./components/donations/Donations.svelte";
import DonorDetail from "./components/donors/DonorDetail.svelte"; import DonationDetail from "./components/donations/DonationDetail.svelte";
import Donations from "./components/donations/Donations.svelte"; import GroupDetail from "./components/groups/GroupDetail.svelte";
import DonationDetail from "./components/donations/DonationDetail.svelte"; import ScanStations from "./components/scanstations/ScanStations.svelte";
import GroupDetail from "./components/groups/GroupDetail.svelte"; import ScanStationDetail from "./components/scanstations/ScanStationDetail.svelte";
import ScanStations from "./components/scanstations/ScanStations.svelte"; import Scans from "./components/scans/Scans.svelte";
import ScanStationDetail from "./components/scanstations/ScanStationDetail.svelte"; import ScanDetail from "./components/scans/ScanDetail.svelte";
import Scans from "./components/scans/Scans.svelte"; import Cards from "./components/cards/Cards.svelte";
import ScanDetail from "./components/scans/ScanDetail.svelte"; store.init();
import Cards from "./components/cards/Cards.svelte"; </script>
store.init();
registerSW(); <Route>
</script> {#if $router.path === '/forgot_password'}
<Route path="/forgot_password">
<Route> <ForgotPassword />
{#if $router.path === '/forgot_password'} </Route>
<Route path="/forgot_password"> {:else if $router.path.includes('/reset')}
<ForgotPassword /> <Route path="/reset/:resetkey" let:params>
</Route> <ResetPassword {params} />
{:else if $router.path.includes('/reset')} </Route>
<Route path="/reset/:resetkey" let:params> {:else if $router.path === '/about'}
<ResetPassword {params} /> <Route path="/about">
</Route> <About />
{:else if $router.path === '/about'} </Route>
<Route path="/about"> {:else if $router.path === '/imprint'}
<About /> <Route path="/imprint">
</Route> <Imprint />
{:else if $router.path === '/imprint'} </Route>
<Route path="/imprint"> {:else if $router.path === '/privacy'}
<Imprint /> <Route path="/privacy">
</Route> <Privacy />
{:else if $router.path === '/privacy'} </Route>
<Route path="/privacy"> {:else if $store.isLoggedIn}
<Privacy /> <Dashboard>
</Route> <Transition>
{:else if $store.isLoggedIn} <Route path="/">
<Dashboard> <MainDashContent />
<Transition> </Route>
<Route path="/"> <Route path="/users/*">
<MainDashContent /> <Route path="/">
</Route> <Users />
<Route path="/users/*"> </Route>
<Route path="/"> <Route path="/:userid/*" let:params>
<Users /> <Route path="/">
</Route> <UserDetail {params} />
<Route path="/:userid/*" let:params> </Route>
<Route path="/"> <Route path="/permissions/">
<UserDetail {params} /> <UserPermissions {params} />
</Route> </Route>
<Route path="/permissions/"> </Route>
<UserPermissions {params} /> </Route>
</Route> <Route path="/groups/*">
</Route> <Route path="/">
</Route> <Groups />
<Route path="/groups/*"> </Route>
<Route path="/"> <Route path="/:groupid/*" let:params>
<Groups /> <Route path="/">
</Route> <GroupDetail {params} />
<Route path="/:groupid/*" let:params> </Route>
<Route path="/"> <Route path="/permissions/">
<GroupDetail {params} /> <GroupPermissions {params} />
</Route> </Route>
<Route path="/permissions/"> </Route>
<GroupPermissions {params} /> </Route>
</Route> <Route path="/tracks/*">
</Route> <Route path="/">
</Route> <TracksOverview />
<Route path="/tracks/*"> </Route>
<Route path="/"> <Route path="/:trackid" let:params />
<TracksOverview /> </Route>
</Route> <Route path="/runners/*">
<Route path="/:trackid" let:params /> <Route path="/">
</Route> <Runners />
<Route path="/runners/*"> </Route>
<Route path="/"> <Route path="/:runnerid" let:params>
<Runners /> <RunnerDetail {params} />
</Route> </Route>
<Route path="/:runnerid" let:params> </Route>
<RunnerDetail {params} /> <Route path="/teams/*">
</Route> <Route path="/">
</Route> <Teams />
<Route path="/teams/*"> </Route>
<Route path="/"> <Route path="/:teamid" let:params>
<Teams /> <TeamDetail {params} />
</Route> </Route>
<Route path="/:teamid" let:params> </Route>
<TeamDetail {params} /> <Route path="/contacts/*">
</Route> <Route path="/">
</Route> <Contacts />
<Route path="/contacts/*"> </Route>
<Route path="/"> <Route path="/:contact" let:params>
<Contacts /> <ContactDetail {params} />
</Route> </Route>
<Route path="/:contact" let:params> </Route>
<ContactDetail {params} /> <Route path="/orgs/*">
</Route> <Route path="/">
</Route> <Orgs />
<Route path="/orgs/*"> </Route>
<Route path="/"> <Route path="/:orgid" let:params>
<Orgs /> <OrgDetail {params} />
</Route> </Route>
<Route path="/:orgid" let:params> </Route>
<OrgDetail {params} /> <Route path="/donors/*">
</Route> <Route path="/">
</Route> <Donors />
<Route path="/donors/*"> </Route>
<Route path="/"> <Route path="/:donorid" let:params>
<Donors /> <DonorDetail {params} />
</Route> </Route>
<Route path="/:donorid" let:params> </Route>
<DonorDetail {params} /> <Route path="/donations/*">
</Route> <Route path="/">
</Route> <Donations />
<Route path="/donations/*"> </Route>
<Route path="/"> <Route path="/:donationid" let:params>
<Donations /> <DonationDetail {params} />
</Route> </Route>
<Route path="/:donationid" let:params> </Route>
<DonationDetail {params} /> <Route path="/cards/*">
</Route> <Route path="/">
</Route> <Cards />
<Route path="/cards/*"> </Route>
<Route path="/"> <!-- <Route path="/:scanid" let:params>
<Cards /> <ScanDetail {params} />
</Route> </Route> -->
<!-- <Route path="/:scanid" let:params> </Route>
<ScanDetail {params} /> <Route path="/scans/*">
</Route> --> <Route path="/">
</Route> <Scans />
<Route path="/scans/*"> </Route>
<Route path="/"> <Route path="/:scanid" let:params>
<Scans /> <ScanDetail {params} />
</Route> </Route>
<Route path="/:scanid" let:params> </Route>
<ScanDetail {params} /> <Route path="/scanstations/*">
</Route> <Route path="/">
</Route> <ScanStations />
<Route path="/scanstations/*"> </Route>
<Route path="/"> <Route path="/:stationid" let:params>
<ScanStations /> <ScanStationDetail {params} />
</Route> </Route>
<Route path="/:stationid" let:params> </Route>
<ScanStationDetail {params} /> <Route path="/about">
</Route> <About />
</Route> </Route>
<Route path="/about"> <Route path="/settings">
<About /> <Settings />
</Route> </Route>
<Route path="/settings"> </Transition>
<Settings /> <Footer />
</Route> </Dashboard>
</Transition> {:else}
<Footer /> <Login />
</Dashboard> {/if}
{:else} </Route>
<Login />
{/if}
</Route>

View File

@@ -1,6 +0,0 @@
<style global>
/*! @import */
@tailwind base;
@tailwind components;
@tailwind utilities;
</style>

View File

@@ -34,7 +34,7 @@
text: $_("creating-blanco-cards"), text: $_("creating-blanco-cards"),
duration: -1, duration: -1,
}).showToast(); }).showToast();
RunnerCardService.runnerCardControllerPostBlancoBulk(card_count) RunnerCardService.runnerCardControllerPostBlancoBulk(card_count, false)
.then((result) => { .then((result) => {
bulk_modal_open = false; bulk_modal_open = false;
// //
@@ -62,8 +62,7 @@
text: $_("creating-blanco-cards"), text: $_("creating-blanco-cards"),
duration: -1, duration: -1,
}).showToast(); }).showToast();
//TODO: Adjust generation function, when backend is merged RunnerCardService.runnerCardControllerPostBlancoBulk(card_count, true)
RunnerCardService.runnerCardControllerPostBlancoBulk(card_count)
.then((result) => { .then((result) => {
bulk_modal_open = false; bulk_modal_open = false;
// //
@@ -72,6 +71,7 @@
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
current_cards = current_cards.concat(result);
const toast = Toastify({ const toast = Toastify({
text: $_("generating-pdf"), text: $_("generating-pdf"),
duration: -1, duration: -1,
@@ -149,14 +149,14 @@
class="hidden sm:inline-block sm:align-middle sm:h-screen" class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span> aria-hidden="true">&#8203;</span>
<div <div
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full" class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-2xl sm:w-full"
role="dialog" role="dialog"
aria-modal="true" aria-modal="true"
aria-labelledby="modal-headline"> aria-labelledby="modal-headline">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4"> <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start"> <div class="sm:flex sm:items-start">
<div <div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"> class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w- rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
<svg <svg
class="h-6 w-6 text-blue-600" class="h-6 w-6 text-blue-600"
fill="currentColor" fill="currentColor"
@@ -212,7 +212,7 @@
<button <button
disabled={!createbtnenabled} disabled={!createbtnenabled}
class:opacity-50={!createbtnenabled} class:opacity-50={!createbtnenabled}
on:click={submit_without_print} on:click={submit_with_print}
type="button" type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"> class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
{$_('create-and-generate-pdf')} {$_('create-and-generate-pdf')}
@@ -222,7 +222,7 @@
class:opacity-50={!createbtnenabled} class:opacity-50={!createbtnenabled}
on:click={submit_without_print} on:click={submit_without_print}
type="button" type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"> class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-400 text-base font-medium text-white hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
{$_('create-without-pdf')} {$_('create-without-pdf')}
</button> </button>
<button <button
@@ -230,7 +230,7 @@
bulk_modal_open = false; bulk_modal_open = false;
}} }}
type="button" type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"> class="mr-auto mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
{$_('cancel')} {$_('cancel')}
</button> </button>
</div> </div>

View File

@@ -1,5 +1,5 @@
<script> <script>
import { getLocaleFromNavigator, json, _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { RunnerCardService } from "@odit/lfk-client-js"; import { RunnerCardService } from "@odit/lfk-client-js";
import store from "../../store"; import store from "../../store";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
@@ -11,11 +11,21 @@
export let editable = {}; export let editable = {};
export let original_data = {}; export let original_data = {};
export let current_cards = []; export let current_cards = [];
$: filtered_cards = current_cards.filter(function (c) {
if (
c.code.toLowerCase().includes(searchvalue_lowercase) ||
c.runner?.firstname.toLowerCase().includes(searchvalue_lowercase) ||
c.runner?.middlename.toLowerCase().includes(searchvalue_lowercase) ||
c.runner?.lastname.toLowerCase().includes(searchvalue_lowercase) ||
should_display_based_on_id(c.id)
) {
return true;
}
});
$: searchvalue = ""; $: searchvalue = "";
$: searchvalue_lowercase = searchvalue.toLowerCase();
$: active_deletes = []; $: active_deletes = [];
$: cards_show = current_cards.some( $: cards_show = current_cards.some((r) => r.is_selected === true);
(r) => r.is_selected === true
);
$: generate_cards = current_cards.filter((r) => r.is_selected === true); $: generate_cards = current_cards.filter((r) => r.is_selected === true);
const cards_promise = RunnerCardService.runnerCardControllerGetAll().then( const cards_promise = RunnerCardService.runnerCardControllerGetAll().then(
(val) => { (val) => {
@@ -46,8 +56,38 @@
original_data = Object.assign(original_data, card); original_data = Object.assign(original_data, card);
edit_modal_open = true; edit_modal_open = true;
} }
// -----------------
let scrollTop = 0;
$: rendered = filtered_cards;
let innerHeight = 0;
let ele;
$: updateSlice(scrollTop);
$: innerHeight = `${filtered_cards.length * 25}px`;
$: if (ele) updateSlice();
function updateSlice() {
const height = ele ? parseInt(ele.clientHeight) : 100;
const init = scrollTop / 25;
const end = Math.ceil((scrollTop + height) / 25);
rendered = filtered_cards.slice(init, end + 15);
}
function updateScroll($event) {
scrollTop = $event.target.scrollTop;
}
</script> </script>
<style>
table tbody {
display: block;
overflow-y: scroll;
}
table thead, table tbody tr {
display: table;
width: 100%;
table-layout: fixed;
}
</style>
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:UPDATE')} {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:UPDATE')}
<CardDetailModal <CardDetailModal
bind:current_cards bind:current_cards
@@ -121,107 +161,111 @@
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-200"> <tbody class="divide-y divide-gray-200 virtual-wrapper"
{#each current_cards as card} on:scroll={updateScroll}
{#if card.code style="height: 70vh; width:100%"
.toLowerCase() bind:this={ele}
.includes( >
searchvalue.toLowerCase() {#each filtered_cards as card, index}
) || card.runner?.firstname {#if card.code
.toLowerCase() .toLowerCase()
.includes( .includes(
searchvalue.toLowerCase() searchvalue.toLowerCase()
) || card.runner?.middlename ) || card.runner?.firstname
.toLowerCase() .toLowerCase()
.includes( .includes(
searchvalue.toLowerCase() searchvalue.toLowerCase()
) || card.runner?.lastname ) || card.runner?.middlename
.toLowerCase() .toLowerCase()
.includes( .includes(
searchvalue.toLowerCase() searchvalue.toLowerCase()
) || should_display_based_on_id(card.id)} ) || card.runner?.lastname
<tr data-rowid="card_{card.id}"> .toLowerCase()
<td class="px-6 py-4 whitespace-nowrap"> .includes(
<input searchvalue.toLowerCase()
bind:checked={card.is_selected} ) || should_display_based_on_id(card.id)}
type="checkbox" <tr data-rowid="card_{card.id}">
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" /> <td class="px-6 py-4 whitespace-nowrap">
</td> <input
<td class="px-6 py-4 whitespace-nowrap"> bind:checked={card.is_selected}
<div class="flex items-center">{card.code}</div> type="checkbox"
</td> class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
<td class="px-6 py-4 whitespace-nowrap"> </td>
<div class="flex items-center"> <td class="px-6 py-4 whitespace-nowrap">
{#if card.runner} <div class="flex items-center">{card.code}</div>
<a </td>
href="../runners/{card.runner.id}" <td class="px-6 py-4 whitespace-nowrap">
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{card.runner.firstname} <div class="flex items-center">
{card.runner.middlename || ''} {#if card.runner}
{card.runner.lastname}</a> <a
{:else}{$_('non-blanko')}{/if} href="../runners/{card.runner.id}"
</div> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{card.runner.firstname}
</td> {card.runner.middlename || ''}
<td class="px-6 py-4 whitespace-nowrap"> {card.runner.lastname}</a>
<div class="flex items-center"> {:else}{$_('non-blanko')}{/if}
{#if card.enabled} </div>
<span </td>
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('enabled')}</span> <td class="px-6 py-4 whitespace-nowrap">
{:else} <div class="flex items-center">
<span {#if card.enabled}
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('disabled')}</span> <span
{/if} class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('enabled')}</span>
</div> {:else}
</td> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('disabled')}</span>
{/if}
</div>
</td>
{#if active_deletes[card.id] === true} {#if active_deletes[card.id] === true}
<td <td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button <button
on:click={() => { on:click={() => {
active_deletes[card.id] = false; active_deletes[card.id] = false;
}} }}
tabindex="0" tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button> class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
<button <button
on:click={() => { on:click={() => {
RunnerCardService.runnerCardControllerRemove(card.id, false).then( RunnerCardService.runnerCardControllerRemove(card.id, false).then(
(resp) => { (resp) => {
current_cards = current_cards.filter( current_cards = current_cards.filter(
(obj) => obj.id !== card.id (obj) => obj.id !== card.id
); );
Toastify({ Toastify({
text: $_('card-deleted'), text: $_('card-deleted'),
duration: 500, duration: 500,
backgroundColor: backgroundColor:
'linear-gradient(to right, #00b09b, #96c93d)', 'linear-gradient(to right, #00b09b, #96c93d)',
}).showToast(); }).showToast();
} }
); );
}} }}
tabindex="0" tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button> class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
</td> </td>
{:else} {:else}
<td <td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button <button
on:click={() => { on:click={() => {
open_edit_modal(card); open_edit_modal(card);
}} }}
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</button> class="text-indigo-600 hover:text-indigo-900">{$_('details')}</button>
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')} {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')}
<button <button
on:click={() => { on:click={() => {
active_deletes[card.id] = true; active_deletes[card.id] = true;
}} }}
tabindex="0" tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button> class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
{/if} {/if}
</td> </td>
{/if} {/if}
</tr> </tr>
{/if} {/if}
{/each} {/each}
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@@ -12,11 +12,21 @@
} }
</script> </script>
<style>
.collapsed_navigation {
transform: translateX(-100%);
}
@media (min-width: 768px) {
.collapsed_navigation {
transform: translateX(0px);
}
}
</style>
<section class="min-h-screen bg-gray-50"> <section class="min-h-screen bg-gray-50">
<nav <div
class:-translate-x-full={!navOpen} class:collapsed_navigation={!navOpen}
class:translate-x-0={navOpen} class="select-none fixed top-0 left-0 z-20 h-full pb-10 overflow-x-hidden overflow-y-auto transition origin-left transform border-r w-60 bg-gray-50">
class="select-none fixed top-0 left-0 z-20 h-full pb-10 overflow-x-hidden overflow-y-auto transition origin-left transform border-r w-60 md:translate-x-0 bg-gray-50">
<a href="/" class="flex items-center px-4 py-5"> <a href="/" class="flex items-center px-4 py-5">
<img src="/lfk-logo.png" alt="Logo" class="h-10" /> <img src="/lfk-logo.png" alt="Logo" class="h-10" />
<h3 class="text-lg">Lauf für Kaya! Admin</h3> <h3 class="text-lg">Lauf für Kaya! Admin</h3>
@@ -297,14 +307,15 @@
<span>{$_('logout')}</span> <span>{$_('logout')}</span>
</span> </span>
</nav> </nav>
</nav> </div>
<div class="ml-0 transition md:ml-60"> <div class="ml-0 transition md:ml-60">
<header <header
on:click={() => {
navOpen = true;
}}
class="flex items-center justify-between w-full px-4 bg-white border-b h-14 md:hidden"> class="flex items-center justify-between w-full px-4 bg-white border-b h-14 md:hidden">
<button class="block btn btn-light md:hidden"> <button
on:click={() => {
navOpen = true;
}}
class="block btn btn-light md:hidden">
<span class="sr-only">Menu</span><svg <span class="sr-only">Menu</span><svg
class="w-4 h-4" class="w-4 h-4"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@@ -318,10 +329,13 @@
<NoComponentLoaded /> <NoComponentLoaded />
</slot> </slot>
</div> </div>
<div {#if navOpen === true}
on:click={() => { <div
navOpen = false; on:click={() => {
}} navOpen = false;
class:hidden={!navOpen} console.log({ navOpen });
class="fixed inset-0 z-10 w-screen h-screen bg-black bg-opacity-25 md:hidden" /> }}
class:hidden={!navOpen}
class="fixed inset-0 z-10 w-screen h-screen bg-black bg-opacity-25 md:hidden" />
{/if}
</section> </section>

View File

@@ -12,6 +12,7 @@
import Select from "svelte-select"; import Select from "svelte-select";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
import { tick } from "svelte"; import { tick } from "svelte";
$: delete_triggered = false; $: delete_triggered = false;
$: address_valid_or_none = $: address_valid_or_none =
@@ -34,6 +35,7 @@
$: iscityvalid = editable.address?.city?.trim().length !== 0; $: iscityvalid = editable.address?.city?.trim().length !== 0;
$: sponsoring_contracts_show = true; $: sponsoring_contracts_show = true;
$: cards_show = true; $: cards_show = true;
$: certificates_show = true;
$: generate_orgs = [original_object]; $: generate_orgs = [original_object];
$: registrationLink = `${config.baseurl}/selfservice/register/${editable.registrationKey}`; $: registrationLink = `${config.baseurl}/selfservice/register/${editable.registrationKey}`;
const getContactLabel = (option) => const getContactLabel = (option) =>
@@ -176,6 +178,7 @@
bind:sponsoring_contracts_show bind:sponsoring_contracts_show
bind:generate_orgs /> bind:generate_orgs />
<GenerateRunnerCards bind:cards_show bind:generate_orgs /> <GenerateRunnerCards bind:cards_show bind:generate_orgs />
<GenerateRunnerCertificates bind:certificates_show bind:generate_orgs />
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')} {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
<button <button
on:click={() => { on:click={() => {
@@ -186,7 +189,7 @@
{$_('import-runners')} {$_('import-runners')}
</button> </button>
{/if} {/if}
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')} {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
{#if delete_triggered} {#if delete_triggered}
<button <button
on:click={deleteOrganization} on:click={deleteOrganization}

View File

@@ -9,11 +9,15 @@
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte"; import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
$: searchvalue = ""; $: searchvalue = "";
$: active_deletes = []; $: active_deletes = [];
$: sponsoring_contracts_show = current_organizations.some((r) => r.is_selected === true); $: sponsoring_contracts_show = current_organizations.some((r) => r.is_selected === true);
$: cards_show = current_organizations.some((r) => r.is_selected === true); $: cards_show = current_organizations.some((r) => r.is_selected === true);
$: generate_orgs = current_organizations.filter((r) => r.is_selected === true); $: generate_orgs = current_organizations.some((r) => r.is_selected === true);
$: certificates_show = current_organizations.some(
(r) => r.is_selected === true
);
export let current_organizations = []; export let current_organizations = [];
const promise = RunnerOrganizationService.runnerOrganizationControllerGetAll().then( const promise = RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
@@ -55,6 +59,9 @@
<GenerateRunnerCards <GenerateRunnerCards
bind:cards_show bind:cards_show
bind:generate_orgs /> bind:generate_orgs />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_orgs />
</div> </div>
<div <div
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"> class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">

View File

@@ -67,7 +67,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Runnercards.pdf"; a.download = `${$_('runnercards')}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -127,7 +127,12 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Runnercards.pdf"; if(generate_runners.length == 1){
a.download = `${$_('runnercards')}_${generate_runners[0].firstname}_${generate_runners[0].lastname}-${locale}.pdf`;
}
else{
a.download = `Runnercards-${locale}.pdf`;
}
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -149,7 +154,7 @@
}).showToast(); }).showToast();
let count = 0; let count = 0;
const current_cards = await RunnerCardService.runnerCardControllerGetAll(); const current_cards = await RunnerCardService.runnerCardControllerGetAll();
for await (const t of generate_teams) { for (const t of generate_teams) {
const runners = await RunnerTeamService.runnerTeamControllerGetRunners( const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id t.id
); );
@@ -191,7 +196,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsorings_" + t.name + ".pdf"; a.download = `${$_('runnercards')}_${t.name}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -216,7 +221,7 @@
}).showToast(); }).showToast();
let count = 0; let count = 0;
const current_cards = await RunnerCardService.runnerCardControllerGetAll(); const current_cards = await RunnerCardService.runnerCardControllerGetAll();
for await (const o of generate_orgs) { for (const o of generate_orgs) {
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners( const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(
o.id o.id
); );
@@ -258,7 +263,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsorings_" + o.name + ".pdf"; a.download = `${$_('runnercards')}_${o.name}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();

View File

@@ -0,0 +1,277 @@
<script>
import { _ } from "svelte-i18n";
import {
DonationService,
RunnerTeamService,
RunnerOrganizationService
} from "@odit/lfk-client-js";
import Toastify from "toastify-js";
export let certificates_show = false;
export let generate_runners = [];
export let generate_orgs = [];
export let generate_teams = [];
$: certificates_dropdown_open = false;
document.addEventListener("click", function (e) {
if (
e.target.parentNode?.parentNode?.id != "certificates:dropdown" &&
e.target.parentNode?.parentNode?.id != "certificates:dropdown:menu"
) {
certificates_dropdown_open = false;
}
});
function generateCertificates(locale) {
certificates_dropdown_open = false;
if (generate_orgs.length > 0) {
generateOrgCertificates(locale);
} else if (generate_teams.length > 0) {
generateTeamCertificates(locale);
} else {
generateRunnerCertificates(locale);
}
}
async function generateRunnerCertificates(locale) {
const toast = Toastify({
text: $_("generating-pdf"),
duration: -1,
}).showToast();
const current_donations = await DonationService.donationControllerGetAll();
let certificateRunners = [];
for (let runner of generate_runners) {
runner.distanceDonations = current_donations.find((d) => d.runner?.id == runner.id) || [];
certificateRunners.push(runner);
}
fetch(
`${config.baseurl}/documents/certificates?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(certificateRunners),
}
)
.then((response) => {
if (response.status != "200") {
toast.hideToast();
Toastify({
text: $_("pdf-generation-failed"),
duration: 3500,
backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast();
} else {
return response.blob();
}
})
.then((blob) => {
const url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
if(generate_runners.length == 1){
a.download = `${$_('certificates')}_${generate_runners[0].firstname}_${generate_runners[0].lastname}-${locale}.pdf`;
}
else{
a.download = `${$_('certificates')}-${locale}.pdf`;
}
document.body.appendChild(a);
a.click();
a.remove();
toast.hideToast();
Toastify({
text: $_("pdf-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
})
.catch((err) => {});
}
async function generateTeamCertificates(locale) {
const toast = Toastify({
text: $_("generating-pdfs"),
duration: -1,
}).showToast();
let count = 0;
const current_donations = await DonationService.donationControllerGetAll();
for (const t of generate_teams) {
const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id
);
let certificateRunners = [];
for (let runner of runners) {
runner.distanceDonations = current_donations.find((d) => d.runner?.id == runner.id) || [];
certificateRunners.push(runner);
}
fetch(
`${config.baseurl}/documents/certificates?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(certificateRunners),
}
)
.then((response) => {
if (response.status != "200") {
toast.hideToast();
Toastify({
text: $_("pdf-generation-failed"),
duration: 3500,
backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast();
} else {
return response.blob();
}
})
.then((blob) => {
count++;
const url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = `${$_('certificates')}_${t.name}-${locale}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
if (count === generate_teams.length) {
toast.hideToast();
Toastify({
text: $_("pdfs-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
})
.catch((err) => {});
}
}
async function generateOrgCertificates(locale) {
const toast = Toastify({
text: $_("generating-pdf"),
duration: -1,
}).showToast();
let count = 0;
const current_donations = await DonationService.donationControllerGetAll();
for (const o of generate_orgs) {
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(
o.id
);
let certificateRunners = [];
for (let runner of runners) {
runner.distanceDonations = current_donations.find((d) => d.runner?.id == runner.id) || [];
certificateRunners.push(runner);
}
fetch(
`${config.baseurl}/documents/certificates?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(certificateRunners),
}
)
.then((response) => {
if (response.status != "200") {
toast.hideToast();
Toastify({
text: $_("pdf-generation-failed"),
duration: 3500,
backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast();
} else {
return response.blob();
}
})
.then((blob) => {
count++;
const url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = `${$_('certificates')}_${o.name}-${locale}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
if (count === generate_orgs.length) {
toast.hideToast();
Toastify({
text: $_("pdfs-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
})
.catch((err) => {});
}
}
</script>
{#if certificates_show}
<div id="certificates:dropdown" class="relative inline-block">
<div>
<button
on:click={() => {
certificates_dropdown_open = !certificates_dropdown_open;
}}
type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-600 text-base font-medium text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex"
id="options-menu"
aria-haspopup="true"
aria-expanded="true">
{$_('generate-runner-certificates')}
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
class="-mr-1 ml-2 h-5 w-5"><path
fill="none"
d="M0 0h24v24H0z" />
<path
fill="currentColor"
d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z" /></svg>
</button>
</div>
{#if certificates_dropdown_open}
<div
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
id="certificates:dropdown:menu">
<div
class="py-1"
role="menu"
aria-orientation="vertical"
aria-labelledby="options-menu">
<span
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
<button
on:click={() => {
generateCertificates('de');
}}
type="submit"
class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900"
role="menuitem">
{$_('german')}
</button>
<button
on:click={() => {
generateCertificates('en');
}}
type="submit"
class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900"
role="menuitem">
{$_('english')}
</button>
</div>
</div>
{/if}
</div>
{/if}

View File

@@ -37,7 +37,7 @@
duration: -1, duration: -1,
}).showToast(); }).showToast();
let count = 0; let count = 0;
for await (const t of generate_teams) { for (const t of generate_teams) {
count++; count++;
const runners = await RunnerTeamService.runnerTeamControllerGetRunners( const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id t.id
@@ -69,7 +69,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsorings_" + t.name + ".pdf"; a.download = `${$_('sponsorings')}_${t.name}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -92,7 +92,7 @@
text: $_("generating-pdf"), text: $_("generating-pdf"),
duration: -1, duration: -1,
}).showToast(); }).showToast();
for await (const o of generate_orgs) { for (const o of generate_orgs) {
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners( const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(
o.id o.id
); );
@@ -124,7 +124,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsorings_" + o.name + ".pdf"; a.download = `${$_('sponsorings')}_${o.name}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -174,7 +174,10 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsoring.pdf"; if(generate_runners.length == 1){
a.download = `${$_('sponsorings')}_${generate_runners[0].firstname}_${generate_runners[0].lastname}-${locale}.pdf`;
}
a.download = `${$_('sponsorings')}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();

View File

@@ -34,7 +34,7 @@
document.onkeydown = (e) => { document.onkeydown = (e) => {
e = e || window.event; e = e || window.event;
if (e.key === "Escape") { if (e.key === "Escape") {
import_modal_open = false; cancelModal();
} }
if (e.keyCode === 13) { if (e.keyCode === 13) {
// //
@@ -281,6 +281,16 @@
bind:files bind:files
type="file" /> type="file" />
</div> </div>
<div class="overflow-hidden relative mt-4 mb-4">
<button
on:click={() => {
cancelModal();
}}
type="button"
class="w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 md:ml-40 mr-0 sm:ml-0 sm:w-auto sm:text-sm">
{$_('cancel')}
</button>
</div>
{/if} {/if}
{#if json_output.length > 0} {#if json_output.length > 0}
{#if opened_from === 'OrgOverview'} {#if opened_from === 'OrgOverview'}

View File

@@ -2,6 +2,7 @@
import { getLocaleFromNavigator, _ } from "svelte-i18n"; import { getLocaleFromNavigator, _ } from "svelte-i18n";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
import store from "../../store"; import store from "../../store";
import { import {
RunnerService, RunnerService,
@@ -36,6 +37,7 @@
editable.group != null; editable.group != null;
$: sponsoring_contracts_show = true; $: sponsoring_contracts_show = true;
$: cards_show = true; $: cards_show = true;
$: certificates_show = true;
$: generate_runners = [original_data_pdf]; $: generate_runners = [original_data_pdf];
runner_promise.then((data) => { runner_promise.then((data) => {
data_loaded = true; data_loaded = true;
@@ -158,7 +160,10 @@
bind:sponsoring_contracts_show bind:sponsoring_contracts_show
bind:generate_runners /> bind:generate_runners />
<GenerateRunnerCards <GenerateRunnerCards
bind:sponsoring_contracts_show bind:cards_show
bind:generate_runners />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_runners /> bind:generate_runners />
{#if !delete_triggered} {#if !delete_triggered}
<button <button

View File

@@ -10,6 +10,7 @@
import Select from "svelte-select"; import Select from "svelte-select";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
$: searchvalue = ""; $: searchvalue = "";
$: active_deletes = []; $: active_deletes = [];
export let current_runners = []; export let current_runners = [];
@@ -27,6 +28,9 @@
$: cards_show = current_runners.some( $: cards_show = current_runners.some(
(r) => r.is_selected === true (r) => r.is_selected === true
); );
$: certificates_show = current_runners.some(
(r) => r.is_selected === true
);
$: generate_runners = current_runners.filter((r) => r.is_selected === true); $: generate_runners = current_runners.filter((r) => r.is_selected === true);
$: teams = []; $: teams = [];
$: orgs = []; $: orgs = [];
@@ -92,6 +96,9 @@
<GenerateRunnerCards <GenerateRunnerCards
bind:cards_show bind:cards_show
bind:generate_runners /> bind:generate_runners />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_runners />
</div> </div>
<div <div
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"> class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
@@ -190,7 +197,7 @@
{#if runner.group.responseType === 'RUNNERTEAM'} {#if runner.group.responseType === 'RUNNERTEAM'}
<a <a
href="../teams/{runner.group.id}" href="../teams/{runner.group.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{runner.group.name}</a> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{runner.group.parentGroup.name} &gt; {runner.group.name}</a>
{/if} {/if}
{#if runner.group.responseType === 'RUNNERORGANIZATION'} {#if runner.group.responseType === 'RUNNERORGANIZATION'}
<a <a

View File

@@ -14,6 +14,7 @@
import Teams from "./Teams.svelte"; import Teams from "./Teams.svelte";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
let [teamdata, original, delete_team, orgs, contacts, modal_open] = [ let [teamdata, original, delete_team, orgs, contacts, modal_open] = [
{}, {},
{}, {},
@@ -30,6 +31,7 @@
$: data_changed = JSON.stringify(teamdata) === JSON.stringify(original); $: data_changed = JSON.stringify(teamdata) === JSON.stringify(original);
$: sponsoring_contracts_show = true; $: sponsoring_contracts_show = true;
$: cards_show = true; $: cards_show = true;
$: certificates_show = true;
$: generate_teams = [original]; $: generate_teams = [original];
$: group = {}; $: group = {};
$: contact = {}; $: contact = {};
@@ -122,6 +124,9 @@
<GenerateRunnerCards <GenerateRunnerCards
bind:cards_show bind:cards_show
bind:generate_teams /> bind:generate_teams />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_teams />
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')} {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
<button <button
on:click={() => { on:click={() => {

View File

@@ -9,6 +9,7 @@
import { clickOutside } from "../base/outsideclick"; import { clickOutside } from "../base/outsideclick";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
$: searchvalue = ""; $: searchvalue = "";
$: active_deletes = []; $: active_deletes = [];
$: sponsoring_contracts_show = current_teams.some( $: sponsoring_contracts_show = current_teams.some(
@@ -17,6 +18,9 @@
$: cards_show = current_teams.some( $: cards_show = current_teams.some(
(r) => r.is_selected === true (r) => r.is_selected === true
); );
$: certificates_show = current_teams.some(
(r) => r.is_selected === true
);
$: generate_teams = current_teams.filter((r) => r.is_selected === true); $: generate_teams = current_teams.filter((r) => r.is_selected === true);
export let current_teams = []; export let current_teams = [];
let modal_open = false; let modal_open = false;
@@ -61,6 +65,9 @@
<GenerateRunnerCards <GenerateRunnerCards
bind:cards_show bind:cards_show
bind:generate_teams /> bind:generate_teams />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_teams />
</div> </div>
<div <div
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"> class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">

View File

@@ -1,14 +0,0 @@
import App from './App.svelte';
const app = new App({
target: document.body
});
export default app;
// HMR
if (import.meta.hot) {
import.meta.hot.accept();
import.meta.hot.dispose(() => {
app.$destroy();
});
}

View File

@@ -1,427 +1,432 @@
{ {
"404message": "Die gesuchte Seite wurde leider nicht gefunden.", "404message": "Die gesuchte Seite wurde leider nicht gefunden.",
"404title": "Fehler 404", "404title": "Fehler 404",
"about": "Über", "about": "Über",
"action": "Aktionen", "action": "Aktionen",
"active": "Aktiv", "active": "Aktiv",
"add-card": "Karte erstellen", "add-card": "Karte erstellen",
"add-donation": "Sponsoring erstellen", "add-donation": "Sponsoring erstellen",
"add-donor": "Sponsor:in erstellen", "add-donor": "Sponsor:in erstellen",
"add-scan": "Scan erstellen", "add-scan": "Scan erstellen",
"add-the-first-scanstation": "Erstelle deine erste Scannerstation.", "add-the-first-scanstation": "Erstelle deine erste Scannerstation.",
"add-user-group": "Neue Gruppe erstellen", "add-user-group": "Neue Gruppe erstellen",
"add-your-first-card": "Erstelle deine erste Läuferkarte", "add-your-first-card": "Erstelle deine erste Läuferkarte",
"add-your-first-contact": "Erstelle den ersten Kontakt", "add-your-first-contact": "Erstelle den ersten Kontakt",
"add-your-first-donor": "Erstelle die erste Sponsor:in", "add-your-first-donor": "Erstelle die erste Sponsor:in",
"add-your-first-group": "Erstelle die erste Gruppe", "add-your-first-group": "Erstelle die erste Gruppe",
"add-your-first-organization": "Erstelle die erste Organisation", "add-your-first-organization": "Erstelle die erste Organisation",
"add-your-first-runner": "Erstelle die erste Läufer:in", "add-your-first-runner": "Erstelle die erste Läufer:in",
"add-your-first-team": "Erstelle das erste Team", "add-your-first-team": "Erstelle das erste Team",
"add-your-first-track": "Erstelle den ersten Track (Laufstrecke).", "add-your-first-track": "Erstelle den ersten Track (Laufstrecke).",
"add-your-first-user": "Erstelle die erste Benutzer:in", "add-your-first-user": "Erstelle die erste Benutzer:in",
"add-your-fist-donation": "Erstelle dein erstes Sponsoring", "add-your-fist-donation": "Erstelle dein erstes Sponsoring",
"add-your-fist-scan": "Füge deinen ersten Scan hinzu", "add-your-fist-scan": "Füge deinen ersten Scan hinzu",
"adding-card": "Karte wird erstellt", "adding-card": "Karte wird erstellt",
"adding-scan": "Scan wird hinzugefügt", "adding-scan": "Scan wird hinzugefügt",
"address": "Adresse", "address": "Adresse",
"address-is-required": "Du musst eine Adresse angeben", "address-is-required": "Du musst eine Adresse angeben",
"after-deletion-we-cant-restore-your-old-profile": "Nach der Löschung können auch die Admins dein Profil nicht wiederherstellen!", "after-deletion-we-cant-restore-your-old-profile": "Nach der Löschung können auch die Admins dein Profil nicht wiederherstellen!",
"after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that": "Nach der Änderung wirst du abgemeldet - bitte melde dich dann mit deinem neuen Passwort an.", "after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that": "Nach der Änderung wirst du abgemeldet - bitte melde dich dann mit deinem neuen Passwort an.",
"all-associated-donations-will-get-deleted-as-well": "Alle Sponsorings dieser Sponsor:in werden ebenfalls gelöscht", "all-associated-donations-will-get-deleted-as-well": "Alle Sponsorings dieser Sponsor:in werden ebenfalls gelöscht",
"all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!", "all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!",
"all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!", "all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!",
"amount": "Anzahl", "amount": "Anzahl",
"amount-per-kilometer": "Betrag pro Kilometer", "amount-per-kilometer": "Betrag pro Kilometer",
"apartment-suite-etc": "Apartment, Wohnung, etc.", "apartment-suite-etc": "Apartment, Wohnung, etc.",
"application_name": "Lauf für Kaya! - Admin", "application_name": "Lauf für Kaya! - Admin",
"applying-changes": "Änderungen anwenden", "applying-changes": "Änderungen anwenden",
"attention": "Achtung!", "attention": "Achtung!",
"author": "Autor:in", "author": "Autor:in",
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer:innen für den Import bestätigen.", "bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer:innen für den Import bestätigen.",
"by": "von", "by": "von",
"cancel": "Abbrechen", "cancel": "Abbrechen",
"cancel-delete": "Löschen abbrechen", "cancel-delete": "Löschen abbrechen",
"cancel-keep-donor": "Abbrechen, Sponsor:in behalten", "cancel-keep-donor": "Abbrechen, Sponsor:in behalten",
"cancel-keep-my-profile": "Abbrechen, mein Profil behalten", "cancel-keep-my-profile": "Abbrechen, mein Profil behalten",
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten", "cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
"cancel-keep-team": "Abbrechen, Team behalten", "cancel-keep-team": "Abbrechen, Team behalten",
"cannot-reset-your-password-directly": "Schade. \nWir können das Passwort leider nicht direkt zurücksetzen.\nBitte sende uns eine Mail in der du deine Identität bestätigst.", "cannot-reset-your-password-directly": "Schade. \nWir können das Passwort leider nicht direkt zurücksetzen.\nBitte sende uns eine Mail in der du deine Identität bestätigst.",
"card-added": "Karte wurde hinzugefügt", "card-added": "Karte wurde hinzugefügt",
"card-deleted": "Karte gelöscht", "card-deleted": "Karte gelöscht",
"card-updated": "Karte aktualisiert", "card-updated": "Karte aktualisiert",
"cards": "Läuferkarten", "cards": "Läuferkarten",
"change-your-password-here": "Hier kannst du dein Passwort ändern", "certificates": "Urkunden",
"changing-your-password": "Passwort wird geändert", "change-your-password-here": "Hier kannst du dein Passwort ändern",
"city": "Stadt", "changing-your-password": "Passwort wird geändert",
"click-to-copy-the-link-into-your-clipboard": "Klicke auf den Link, um ihn in deine Zwischenablage zu kopieren", "city": "Stadt",
"click-to-copy-token-to-clipboard": "Klicke auf den Token, um ihn in deine Zwischenablage zu kopieren", "click-to-copy-the-link-into-your-clipboard": "Klicke auf den Link, um ihn in deine Zwischenablage zu kopieren",
"close": "Schließen", "click-to-copy-token-to-clipboard": "Klicke auf den Token, um ihn in deine Zwischenablage zu kopieren",
"code": "Code", "close": "Schließen",
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit", "code": "Code",
"confirm": "Bestätigen", "configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
"confirm-delete": "Löschung Bestätigen", "confirm": "Bestätigen",
"confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen", "confirm-delete": "Löschung Bestätigen",
"confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil löschen", "confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen",
"confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.", "confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil löschen",
"confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.", "confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.",
"confirm-deletion": "Löschung Bestätigen", "confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.",
"confirm-the-new-password": "Neues Passwort bestätigen", "confirm-deletion": "Löschung Bestätigen",
"contact": "Kontakt", "confirm-the-new-password": "Neues Passwort bestätigen",
"contact-deleted": "Kontakt gelöscht", "contact": "Kontakt",
"contact-information": "Kontaktinformation", "contact-deleted": "Kontakt gelöscht",
"contact-is-being-updated": "Kontakt wird aktualisiert ...", "contact-information": "Kontaktinformation",
"contact-is-not-a-member-in-any-group": "Kontakt gehört zu keiner Gruppe", "contact-is-being-updated": "Kontakt wird aktualisiert ...",
"contacts": "Kontakte", "contact-is-not-a-member-in-any-group": "Kontakt gehört zu keiner Gruppe",
"contacts-are-being-loaded": "Kontakte werden geladen ...", "contacts": "Kontakte",
"copied-link-to-clipboard": "Link wurde in die Zwischenablage kopiert", "contacts-are-being-loaded": "Kontakte werden geladen ...",
"copied-token-to-clipboard": "Token wurde in die Zwischenablage kopiert", "copied-link-to-clipboard": "Link wurde in die Zwischenablage kopiert",
"count_organizations": "Organisationen (Anzahl)", "copied-token-to-clipboard": "Token wurde in die Zwischenablage kopiert",
"count_teams": "Teams (Anzahl)", "count_organizations": "Organisationen (Anzahl)",
"create": "Erstellen", "count_teams": "Teams (Anzahl)",
"create-a-new": "Erstelle eine neue", "create": "Erstellen",
"create-a-new-card": "Neue Läuferkarte erstellen", "create-a-new": "Erstelle eine neue",
"create-a-new-contact": "Kontakt erstellen", "create-a-new-card": "Neue Läuferkarte erstellen",
"create-a-new-distance-donation": "Erstelle ein neues Sponsoring", "create-a-new-contact": "Kontakt erstellen",
"create-a-new-donor": "Neue Sponsor:in erstellen", "create-a-new-distance-donation": "Erstelle ein neues Sponsoring",
"create-a-new-fixed-donation": "Erstelle eine neue Festbetragsspende", "create-a-new-donor": "Neue Sponsor:in erstellen",
"create-a-new-organization": "Neue Organisation anlegen", "create-a-new-fixed-donation": "Erstelle eine neue Festbetragsspende",
"create-a-new-runner": "Neue Läufer:in erstellen", "create-a-new-organization": "Neue Organisation anlegen",
"create-a-new-scan-fixed-only": "Neuen Scan erstellen (nur mit Festdistanz)", "create-a-new-runner": "Neue Läufer:in erstellen",
"create-a-new-scanstation": "Neue Station erstellen", "create-a-new-scan-fixed-only": "Neuen Scan erstellen (nur mit Festdistanz)",
"create-a-new-team": "Erstelle ein neues Team", "create-a-new-scanstation": "Neue Station erstellen",
"create-a-new-track": "Neuen Track erstellen", "create-a-new-team": "Erstelle ein neues Team",
"create-a-new-user": "Neue Benutzer:in anlegen", "create-a-new-track": "Neuen Track erstellen",
"create-a-new-user-group": "Erstelle eine neue Gruppe", "create-a-new-user": "Neue Benutzer:in anlegen",
"create-bulk-blanco-cards": "Blankokarten erstellen", "create-a-new-user-group": "Erstelle eine neue Gruppe",
"create-bulk-cards": "Blankokarten erstellen", "create-and-generate-pdf": "Erstellen und PDF herunterladen",
"create-organization": "Organisation erstellen", "create-bulk-blanco-cards": "Blankokarten erstellen",
"create-team": "Team erstellen", "create-bulk-cards": "Blankokarten erstellen",
"create-track": "Track erstellen", "create-organization": "Organisation erstellen",
"create-user": "Benutzer anlegen", "create-team": "Team erstellen",
"created-blanco-cards": "Blankokarten wurden erstellt", "create-track": "Track erstellen",
"creating-blanco-cards": "Erstelle Blankokarten", "create-user": "Benutzer anlegen",
"credits": "Credits", "create-without-pdf": "Ohne PDF erstellen",
"csv_import__class": "Klasse", "created-blanco-cards": "Blankokarten wurden erstellt",
"csv_import__firstname": "Vorname", "creating-blanco-cards": "Erstelle Blankokarten",
"csv_import__lastname": "Nachname", "credits": "Credits",
"csv_import__middlename": "Mittelname", "csv_import__class": "Klasse",
"csv_import__team": "Team", "csv_import__firstname": "Vorname",
"danger-zone": "Gefahrenzone", "csv_import__lastname": "Nachname",
"dashboard-greeting": "Hallo", "csv_import__middlename": "Mittelname",
"dashboard-title": "Dashboard", "csv_import__team": "Team",
"datatable": { "danger-zone": "Gefahrenzone",
"search": "🔍 Suche ...", "dashboard-greeting": "Hallo",
"an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten", "dashboard-title": "Dashboard",
"loading": "Wird geladen...", "datatable": {
"next": "Nächste", "search": "🔍 Suche ...",
"of": "von", "an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten",
"previous": "Vorherige", "loading": "Wird geladen...",
"to": "bis", "next": "Nächste",
"showing": "Zeige", "of": "von",
"no_matching_records_found": "Keine passenden Einträge gefunden", "previous": "Vorherige",
"page": "Seite", "to": "bis",
"records": "Einträge", "showing": "Zeige",
"sort_column_ascending": "Spalte aufsteigend sortieren", "no_matching_records_found": "Keine passenden Einträge gefunden",
"sort_column_descending": "Spalte absteigend sortieren" "page": "Seite",
}, "records": "Einträge",
"delete": "Löschen", "sort_column_ascending": "Spalte aufsteigend sortieren",
"delete-contact": "Kontakt löschen", "sort_column_descending": "Spalte absteigend sortieren"
"delete-donation": "Sponsporing löschen", },
"delete-donor": "Sponsor:in löschen", "delete": "Löschen",
"delete-group": "Gruppe löschen", "delete-contact": "Kontakt löschen",
"delete-organization": "Organisation löschen", "delete-donation": "Sponsporing löschen",
"delete-profile": "Profil löschen", "delete-donor": "Sponsor:in löschen",
"delete-runner": "Läufer:in löschen", "delete-group": "Gruppe löschen",
"delete-scan": "Scan löschen", "delete-organization": "Organisation löschen",
"delete-station": "Station löschen", "delete-profile": "Profil löschen",
"delete-team": "Team Löschen", "delete-runner": "Läufer:in löschen",
"delete-user": "Benutzer:in löschen", "delete-scan": "Scan löschen",
"deleted-scan": "Scan wurde gelöscht", "delete-station": "Station löschen",
"dependency_name": "Name", "delete-team": "Team Löschen",
"description": "Beschreibung", "delete-user": "Benutzer:in löschen",
"description-optional": "Beschreibung (optional)", "deleted-scan": "Scan wurde gelöscht",
"deselect-all": "Alle abwählen", "dependency_name": "Name",
"details": "Details", "description": "Beschreibung",
"disabled": "deaktiviert", "description-optional": "Beschreibung (optional)",
"distance": "Distanz", "deselect-all": "Alle abwählen",
"distance-donation": "Sponsoring", "details": "Details",
"distance-in-km": "Distanz (in KM)", "disabled": "deaktiviert",
"distance-track": "Distanz (+Track)", "distance": "Distanz",
"do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?", "distance-donation": "Sponsoring",
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?", "distance-in-km": "Distanz (in KM)",
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?", "distance-track": "Distanz (+Track)",
"do-you-want-to-delete-this-donor-with-all-related-donations": "Möchtest du diese Sponsor:in mit all ihren Sponsorings löschen?", "do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?",
"documentation": "Dokumentation", "do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
"donation-amount": "Sponsoringbetrag", "do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?",
"donation-amount-must-be-greater-that-0-00eur": "Der Sponsoringbetrag muss größer als 0.00€ sein.", "do-you-want-to-delete-this-donor-with-all-related-donations": "Möchtest du diese Sponsor:in mit all ihren Sponsorings löschen?",
"donations": "Sponsorings", "documentation": "Dokumentation",
"donor": "Sponsor:in", "donation-amount": "Sponsoringbetrag",
"donor-added": "Sponsor:in hinzugefügt", "donation-amount-must-be-greater-that-0-00eur": "Der Sponsoringbetrag muss größer als 0.00€ sein.",
"donor-deleted": "Sponsor:in gelöscht", "donations": "Sponsorings",
"donor-has-no-associated-donations": "Zur Sponsor:in gibt es noch keine Sponsorings", "donor": "Sponsor:in",
"donor-is-being-added": "Sponsor:in wird hinzugefügt...", "donor-added": "Sponsor:in hinzugefügt",
"donor-is-being-updated": "Sponsor:in wird aktualisiert", "donor-deleted": "Sponsor:in gelöscht",
"donors": "Sponsor:innen", "donor-has-no-associated-donations": "Zur Sponsor:in gibt es noch keine Sponsorings",
"donors-are-being-loaded": "Sponsor:innen werden geladen", "donor-is-being-added": "Sponsor:in wird hinzugefügt...",
"dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?", "donor-is-being-updated": "Sponsor:in wird aktualisiert",
"dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌", "donors": "Sponsor:innen",
"e-mail-adress": "E-Mail-Adresse", "donors-are-being-loaded": "Sponsor:innen werden geladen",
"edit": "Bearbeiten", "dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?",
"edit-a-card": "Läuferkarte bearbeiten", "dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌",
"edit-permissions": "Berechtigungen bearbeiten", "e-mail-adress": "E-Mail-Adresse",
"email_address_or_username": "E-Mail-Adresse/ Benutzername", "edit": "Bearbeiten",
"enabled": "aktiviert", "edit-a-card": "Läuferkarte bearbeiten",
"enabled_large": "Aktiviert", "edit-permissions": "Berechtigungen bearbeiten",
"english": "Englisch", "email_address_or_username": "E-Mail-Adresse/ Benutzername",
"error-during-import": "Fehler beim Importieren", "enabled": "aktiviert",
"error-whyile-copying-to-clipboard": "Fehler beim Kopieren in die Zwischenablage", "enabled_large": "Aktiviert",
"error_on_login": "😢Fehler beim Login", "english": "Englisch",
"erteilte": "Direkt erteilte", "error-during-import": "Fehler beim Importieren",
"everything-concerning-your-profile": "Alles zu deinem Profil", "error-whyile-copying-to-clipboard": "Fehler beim Kopieren in die Zwischenablage",
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃‍♂️🏃‍♀️🏃‍♂️", "error_on_login": "😢Fehler beim Login",
"faq": "FAQ", "erteilte": "Direkt erteilte",
"filter-by-organization-team": "Filtern nach Organisation / Team", "everything-concerning-your-profile": "Alles zu deinem Profil",
"first-name": "Vorname", "everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃‍♂️🏃‍♀️🏃‍♂️",
"first-name-is-required": "Vorname muss angegeben werden", "faq": "FAQ",
"first-scan-of-the-day": "Erster Scan des Tages", "filter-by-organization-team": "Filtern nach Organisation / Team",
"fixed-donation": "Festbetragsspende", "first-name": "Vorname",
"forgot_password": "Passwort vergessen?", "first-name-is-required": "Vorname muss angegeben werden",
"geerbte": "geerbte", "first-scan-of-the-day": "Erster Scan des Tages",
"general-stats": "Allgemeine Statistiken", "fixed-donation": "Festbetragsspende",
"general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten", "forgot_password": "Passwort vergessen?",
"generate-runnercards": "Läuferkarten generieren", "geerbte": "geerbte",
"generate-sponsoring-contract": "Sponsoringvertrag generieren", "general-stats": "Allgemeine Statistiken",
"generate-sponsoring-contracts": "Sponsoringverträge generieren", "general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten",
"generating-pdf": "Pdf wird generiert...", "generate-runner-certificate": "Urkunde generieren",
"generating-pdfs": "PDFs werden generiert...", "generate-runner-certificates": "Urkunden generieren",
"generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.", "generate-runnercards": "Läuferkarten generieren",
"german": "Deutsch", "generate-sponsoring-contract": "Sponsoringvertrag generieren",
"go-to-login": "Zum Login", "generate-sponsoring-contracts": "Sponsoringverträge generieren",
"goback": "Zur Startseite", "generating-pdf": "PDF wird generiert...",
"granted": "Gewährt", "generating-pdfs": "PDFs werden generiert...",
"group": "Gruppe", "generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.",
"group-added": "Gruppe hinzugefügt", "german": "Deutsch",
"group-is-being-added": "Gruppe wird erstellt", "go-to-login": "Zum Login",
"group-name-is-required": "Der Gruppenname muss angegeben werden.", "goback": "Zur Startseite",
"group-updated": "Gruppe aktualisiert", "granted": "Gewährt",
"groups": "Gruppen", "group": "Gruppe",
"groups-are-being-loaded": "Gruppen werden geladen", "group-added": "Gruppe hinzugefügt",
"home": "Start", "group-is-being-added": "Gruppe wird erstellt",
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:", "group-name-is-required": "Der Gruppenname muss angegeben werden.",
"if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button": "Wenn du mehrere Blankokarten erstellen willst, nutze doch den \"Blankokarten erstellen\" Knopf.", "group-updated": "Gruppe aktualisiert",
"import-finished": "Import abgeschlossen", "groups": "Gruppen",
"import-runners": "Läufer:innen importieren", "groups-are-being-loaded": "Gruppen werden geladen",
"import__target-organization": "Ziel Organisation", "home": "Start",
"imprint": "Impressum ", "icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
"imprint-loading": "Impressum lädt...", "if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button": "Wenn du mehrere Blankokarten erstellen willst, nutze doch den \"Blankokarten erstellen\" Knopf.",
"inactive": "Inaktiv", "import-finished": "Import abgeschlossen",
"installed-version": "Installierte Version", "import-runners": "Läufer:innen importieren",
"internal-error": "Interner Fehler", "import__target-organization": "Ziel Organisation",
"invalid": "Ungültig", "imprint": "Impressum ",
"invalid-mail-reset": "Das ist keine gültige E-Mail", "imprint-loading": "Impressum lädt...",
"just-enter-how-many-you-want-and-the-system-will-create-them": "Gebe einfach ein, wie viele Blankokarten das System erstellen soll.", "inactive": "Inaktiv",
"laeufer-hinzufuegen": "Läufer:in hinzufügen", "installed-version": "Installierte Version",
"laeufer-importieren": "Läufer:innen importieren", "internal-error": "Interner Fehler",
"laptime": "Rundenzeit", "invalid": "Ungültig",
"last-name": "Nachname", "invalid-mail-reset": "Das ist keine gültige E-Mail",
"last-name-is-required": "Nachname muss angegeben werden", "just-enter-how-many-you-want-and-the-system-will-create-them": "Gebe einfach ein, wie viele Blankokarten das System erstellen soll.",
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.", "laeufer-hinzufuegen": "Läufer:in hinzufügen",
"license": "Lizenz", "laeufer-importieren": "Läufer:innen importieren",
"licenses-are-being-loaded": "Lizenzen werden geladen...", "laptime": "Rundenzeit",
"loading-cards": "Läuferkarten werden geladen", "last-name": "Nachname",
"loading-contact-details": "Kontaktdaten werden geladen ...", "last-name-is-required": "Nachname muss angegeben werden",
"loading-donation-details": "Lade Sponsoringdetails", "lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
"loading-donor-details": "Lade Details", "license": "Lizenz",
"loading-group-detail": "Lade Gruppendetails...", "licenses-are-being-loaded": "Lizenzen werden geladen...",
"loading-profile-data": "Lade Profildaten", "loading-cards": "Läuferkarten werden geladen",
"loading-runners": "Läufer:innen werden geladen...", "loading-contact-details": "Kontaktdaten werden geladen ...",
"loading-station-details": "Lade Scanstation-Details ...", "loading-donation-details": "Lade Sponsoringdetails",
"log_in": "Anmelden", "loading-donor-details": "Lade Details",
"log_in_to_your_account": "Bitte melde dich an", "loading-group-detail": "Lade Gruppendetails...",
"login_is_checked": "Login wird überprüft", "loading-profile-data": "Lade Profildaten",
"logout": "Abmelden", "loading-runners": "Läufer:innen werden geladen...",
"mail-validation-in-progress": "E-Mail Verifizierung läuft... ", "loading-station-details": "Lade Scanstation-Details ...",
"manage-admin-users": "Nutzer verwalten", "log_in": "Anmelden",
"middle-name": "Mittelname", "log_in_to_your_account": "Bitte melde dich an",
"minimum-lap-time-in-s": "Minimale Rundenzeit (in Sekunden)", "login_is_checked": "Login wird überprüft",
"minimum-lap-time-must-be-a-positive-number-or-0": "Die minimale Rundenzeit muss eine positive Zahl oder 0 sein", "logout": "Abmelden",
"must-be-at-least-10-characters-long": "Passwort muss mindestens 10 Zeichen lang sein!", "mail-validation-in-progress": "E-Mail Verifizierung läuft... ",
"must-contain-a-lowercase-letter": "Passwort muss einen Großbuchstaben enthalten!", "manage-admin-users": "Nutzer verwalten",
"must-contain-a-number": "Passwort muss eine Zahl enthalten!", "middle-name": "Mittelname",
"must-contain-a-uppercase-letter": "Passwort muss einen Kleinbuchstaben enthalten!", "minimum-lap-time-in-s": "Minimale Rundenzeit (in Sekunden)",
"name": "Name", "minimum-lap-time-must-be-a-positive-number-or-0": "Die minimale Rundenzeit muss eine positive Zahl oder 0 sein",
"name-is-required": "Der Gruppenname muss angegeben werden", "must-be-at-least-10-characters-long": "Passwort muss mindestens 10 Zeichen lang sein!",
"new-password": "Neues Passwort", "must-contain-a-lowercase-letter": "Passwort muss einen Großbuchstaben enthalten!",
"no-contact-found": "Keine Kontakte gefunden", "must-contain-a-number": "Passwort muss eine Zahl enthalten!",
"no-contact-selected": "Kein Kontakt ausgewählt", "must-contain-a-uppercase-letter": "Passwort muss einen Kleinbuchstaben enthalten!",
"no-contact-specified": "Kein Kontakt angegeben", "name": "Name",
"no-donors-found": "Keine Spender:innen gefunden", "name-is-required": "Der Gruppenname muss angegeben werden",
"no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢", "new-password": "Neues Passwort",
"no-organization-or-team-found": "Keine Organisationen oder Teams gefunden", "no-contact-found": "Keine Kontakte gefunden",
"no-organization-specified": "Keine Organisation angegeben", "no-contact-selected": "Kein Kontakt ausgewählt",
"no-organizations-found": "Keine Organisationen gefunden", "no-contact-specified": "Kein Kontakt angegeben",
"no-runners-found": "Keine Läufer:innen gefunden", "no-donors-found": "Keine Spender:innen gefunden",
"no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.", "no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢",
"non-blanko": "Keine/Blankokarte", "no-organization-or-team-found": "Keine Organisationen oder Teams gefunden",
"organization": "Organisation", "no-organization-specified": "Keine Organisation angegeben",
"organization-added": "Organisation hinzugefügt", "no-organizations-found": "Keine Organisationen gefunden",
"organization-deleted": "Organisation gelöscht", "no-runners-found": "Keine Läufer:innen gefunden",
"organization-detail-is-being-loaded": "Organisationsdetails werden geladen ...", "no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.",
"organization-is-being-added": "Organisation wird hinzugefügt ...", "non-blanko": "Keine/Blankokarte",
"organization-name-is-required": "Der Name muss angegeben werden", "organization": "Organisation",
"organizations": "Organisationen", "organization-added": "Organisation hinzugefügt",
"organizations-are-being-loaded": "Organisationen werden geladen ...", "organization-deleted": "Organisation gelöscht",
"orgs": "Organisationen", "organization-detail-is-being-loaded": "Organisationsdetails werden geladen ...",
"oss_credit_description": "Wir verwenden eine Menge Open Source-Software bei diesen Projekten und möchten uns bei den folgenden Projekten und Mitwirkenden bedanken, die dazu beitragen, Open Source großartig zu machen!", "organization-is-being-added": "Organisation wird hinzugefügt ...",
"password": "Passwort", "organization-name-is-required": "Der Name muss angegeben werden",
"password-changed": "Passwort wurde aktualisiert!", "organizations": "Organisationen",
"password-is-required": "Passwort muss angegeben werden", "organizations-are-being-loaded": "Organisationen werden geladen ...",
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!", "orgs": "Organisationen",
"password-reset-in-progress": "Passwort wird zurückgesetzt...", "oss_credit_description": "Wir verwenden eine Menge Open Source-Software bei diesen Projekten und möchten uns bei den folgenden Projekten und Mitwirkenden bedanken, die dazu beitragen, Open Source großartig zu machen!",
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.", "password": "Passwort",
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!", "password-changed": "Passwort wurde aktualisiert!",
"passwords-dont-match": "Die Passwörter stimmen nicht überein!", "password-is-required": "Passwort muss angegeben werden",
"pdf-generation-failed": "PDF Generierung fehlgeschlagen!", "password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
"pdf-successfully-generated": "PDF wurde erfolgreich generiert!", "password-reset-in-progress": "Passwort wird zurückgesetzt...",
"pdfs-successfully-generated": "Alle PDFs wurden generiert!", "password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
"per-kilometer": "pro Kilometer", "password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
"permissions": "Berechtigungen", "passwords-dont-match": "Die Passwörter stimmen nicht überein!",
"permissions-updated": "Berechtigungen aktualisiert!", "pdf-generation-failed": "PDF Generierung fehlgeschlagen!",
"phone": "Telefon", "pdf-successfully-generated": "PDF wurde erfolgreich generiert!",
"please-copy-the-token-and-store-it-somewhere-save": "Bitte kopiere dir den Token und bewahre ihn gut auf.", "pdfs-successfully-generated": "Alle PDFs wurden generiert!",
"please-provide-a-password": "Bitte gebe ein Passwort an...", "per-kilometer": "pro Kilometer",
"please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen", "permissions": "Berechtigungen",
"please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.", "permissions-updated": "Berechtigungen aktualisiert!",
"please-provide-the-nessecary-information-to-create-a-new-scan": "Bitte gebe alle notwendigen Informationen an, um einen neuen Scan zu erstellen.", "phone": "Telefon",
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.", "please-copy-the-token-and-store-it-somewhere-save": "Bitte kopiere dir den Token und bewahre ihn gut auf.",
"please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.", "please-provide-a-password": "Bitte gebe ein Passwort an...",
"please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.", "please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen",
"please-provide-the-required-information-to-add-a-new-organization": "Bitte gebe alle nötigen Informationen an, im die neue Organisation zu erstellen.", "please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.",
"please-provide-the-required-information-to-add-a-new-runner": "Bitte die benötigten Informationen angeben.", "please-provide-the-nessecary-information-to-create-a-new-scan": "Bitte gebe alle notwendigen Informationen an, um einen neuen Scan zu erstellen.",
"please-provide-the-required-information-to-add-a-new-team": "Bitte gebe alle nötigen Informationen an, im das neue Team zu erstellen.", "please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
"please-provide-the-required-information-to-add-a-new-track": "Bitte die benötigten Informationen angeben.", "please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.",
"please-provide-the-required-information-to-add-a-new-user": "Bitte gebe alle nötigen Informationen an, im die neue Benutzer:in zu erstellen.", "please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.",
"please-provide-the-required-information-to-create-a-new-scanstation": "Bitte gebe alle für eine Scannerstation notwendigen Informationen an", "please-provide-the-required-information-to-add-a-new-organization": "Bitte gebe alle nötigen Informationen an, im die neue Organisation zu erstellen.",
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...", "please-provide-the-required-information-to-add-a-new-runner": "Bitte die benötigten Informationen angeben.",
"privacy": "Datenschutz", "please-provide-the-required-information-to-add-a-new-team": "Bitte gebe alle nötigen Informationen an, im das neue Team zu erstellen.",
"privacy-loading": "Datenschutzerklärung lädt...", "please-provide-the-required-information-to-add-a-new-track": "Bitte die benötigten Informationen angeben.",
"profile": "Profil", "please-provide-the-required-information-to-add-a-new-user": "Bitte gebe alle nötigen Informationen an, im die neue Benutzer:in zu erstellen.",
"profile-picture": "Profilbild", "please-provide-the-required-information-to-create-a-new-scanstation": "Bitte gebe alle für eine Scannerstation notwendigen Informationen an",
"profile-updated": "Profil wurde aktualisiert!", "please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
"read-license": "Lizenz-Text lesen", "privacy": "Datenschutz",
"receipt-needed": "Spendenquittung benötigt", "privacy-loading": "Datenschutzerklärung lädt...",
"repo_link": "Link", "profile": "Profil",
"request-a-new-reset-mail": "Neue Reset-Mail anfordern", "profile-picture": "Profilbild",
"reset-my-password": "Passwort zurücksetzen", "profile-updated": "Profil wurde aktualisiert!",
"reset-password": "Passwort zurücksetzen", "read-license": "Lizenz-Text lesen",
"runner": "Läufer:in", "receipt-needed": "Spendenquittung benötigt",
"runner-added": "Läufer:in hinzugefügt", "repo_link": "Link",
"runner-import": "Läufer:innen Import", "request-a-new-reset-mail": "Neue Reset-Mail anfordern",
"runner-is-being-added": "Läufer:in wird hinzugefügt...", "reset-my-password": "Passwort zurücksetzen",
"runner-updated": "Läufer:in aktualisiert!", "reset-password": "Passwort zurücksetzen",
"runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen", "runner": "Läufer:in",
"runners": "Läufer", "runner-added": "Läufer:in hinzugefügt",
"runners-are-being-imported": "Läufer:innen werden importiert ...", "runner-import": "Läufer:innen Import",
"runners-are-being-loaded": "Läufer:innen werden geladen ...", "runner-is-being-added": "Läufer:in wird hinzugefügt...",
"save": "Speichern", "runner-updated": "Läufer:in aktualisiert!",
"save-changes": "Änderungen speichern", "runnercards": "Laeuferkarten",
"scan-added": "Scan hinzugefügt", "runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen",
"scan-is-being-updated": "Scan wird aktualisiert", "runners": "Läufer",
"scan-with-fixed-distance": "Scan mit Festdistanz", "runners-are-being-imported": "Läufer:innen werden importiert ...",
"scans": "Scans", "runners-are-being-loaded": "Läufer:innen werden geladen ...",
"scans-are-being-loaded": "Scans werden geladen", "save": "Speichern",
"scanstation": "Scanner Station", "save-changes": "Änderungen speichern",
"scanstation-added": "Station wurde erstellt", "scan-added": "Scan hinzugefügt",
"scanstation-is-being-added": "Scannerstation wird angelegt...", "scan-is-being-updated": "Scan wird aktualisiert",
"scanstations": "Scanner Stationen", "scan-with-fixed-distance": "Scan mit Festdistanz",
"scanstations-are-being-loaded": "Scannerstationen werden geladen...", "scans": "Scans",
"search-for-an-organization-by-name-or-id": "Suche eine Organisation (via Name oder Id)", "scans-are-being-loaded": "Scans werden geladen",
"search-for-an-organization-or-team-by-name-or-id": "Suche eine Organisation oder ein Team (via Name oder Id)", "scanstation": "Scanner Station",
"search-for-donor-name-or-id": "Suche eine Spender:in (via Name oder Id)", "scanstation-added": "Station wurde erstellt",
"search-for-permission": "Berechtigungen durchsuchen", "scanstation-is-being-added": "Scannerstation wird angelegt...",
"search-for-runner-by-name-or-id": "Suche eine Läufer:in (via Name oder Id)", "scanstations": "Scanner Stationen",
"select-all": "Alle auswählen", "scanstations-are-being-loaded": "Scannerstationen werden geladen...",
"select-language": "Sprache auswählen", "search-for-an-organization-by-name-or-id": "Suche eine Organisation (via Name oder Id)",
"selfservice-registration": "Selfservice Registrierung", "search-for-an-organization-or-team-by-name-or-id": "Suche eine Organisation oder ein Team (via Name oder Id)",
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services", "search-for-donor-name-or-id": "Suche eine Spender:in (via Name oder Id)",
"set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen", "search-for-permission": "Berechtigungen durchsuchen",
"settings": "Einstellungen", "search-for-runner-by-name-or-id": "Suche eine Läufer:in (via Name oder Id)",
"settings-for-your-profile": "Die Einstellungen deines Accounts", "select-all": "Alle auswählen",
"something-about-the-group": "Infos zur Gruppe", "select-language": "Sprache auswählen",
"stats-are-being-loaded": "Die Statistiken werden geladen...", "selfservice-registration": "Selfservice Registrierung",
"status": "Status", "send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können", "set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen",
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!", "settings": "Einstellungen",
"team": "Team", "settings-for-your-profile": "Die Einstellungen deines Accounts",
"team-detail-is-being-loaded": "Team wird geladen...", "something-about-the-group": "Infos zur Gruppe",
"team-name": "Teamname", "sponsorings": "Sponsoringerklaerungen",
"team-name-is-required": "Teamname ist erforderlich", "stats-are-being-loaded": "Die Statistiken werden geladen...",
"teams": "Teams", "status": "Status",
"teams-are-being-loaded": "Teams werden geladen ...", "stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
"the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "Die angegebene Telefonnummer ist nicht korrekt. <br /> Bitte gebe eine Telefonnummer im internationalen Format an...", "successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
"the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.", "team": "Team",
"the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again": "Der Scannerstation Token wird nur einmal angezeigt - du kannst ihn nicht ändern oder ihn dir nochmal anzeigen lassen!", "team-detail-is-being-loaded": "Team wird geladen...",
"there-are-no-cards-yet": "Es gibt noch keine Läuferkarten.", "team-name": "Teamname",
"there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.", "team-name-is-required": "Teamname ist erforderlich",
"there-are-no-donations-yet": "Es gibt noch keine Sponsorings", "teams": "Teams",
"there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen", "teams-are-being-loaded": "Teams werden geladen ...",
"there-are-no-groups-yet": "Es gibt noch keine Gruppen", "the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "Die angegebene Telefonnummer ist nicht korrekt. <br /> Bitte gebe eine Telefonnummer im internationalen Format an...",
"there-are-no-organizations-added-yet": "Es wurden noch keine Organisationen hinzugefügt.", "the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.",
"there-are-no-runners-added-yet": "Es wurden noch keine Läufer:innen hinzugefügt.", "the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again": "Der Scannerstation Token wird nur einmal angezeigt - du kannst ihn nicht ändern oder ihn dir nochmal anzeigen lassen!",
"there-are-no-scans-yet": "Es gibt noch keine Scans", "there-are-no-cards-yet": "Es gibt noch keine Läuferkarten.",
"there-are-no-teams-added-yet": "Es wurden noch keine Teams hinzugefügt.", "there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.",
"there-are-no-users-added-yet": "Es wurden noch keine Benutzer hinzugefügt.", "there-are-no-donations-yet": "Es gibt noch keine Sponsorings",
"this-card-is": "Diese Karte ist", "there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen",
"this-might-take-a-moment": "Das könnte einen kleinen Moment dauern", "there-are-no-groups-yet": "Es gibt noch keine Gruppen",
"this-scanstation-is": "Diese Station ist", "there-are-no-organizations-added-yet": "Es wurden noch keine Organisationen hinzugefügt.",
"token": "Token", "there-are-no-runners-added-yet": "Es wurden noch keine Läufer:innen hinzugefügt.",
"total-distance": "gelaufene Strecke", "there-are-no-scans-yet": "Es gibt noch keine Scans",
"total-donation-amount": "Gesamtbetrag", "there-are-no-teams-added-yet": "Es wurden noch keine Teams hinzugefügt.",
"total-donations": "Spendensumme", "there-are-no-users-added-yet": "Es wurden noch keine Benutzer hinzugefügt.",
"total-scans": "gesamte Scans", "this-card-is": "Diese Karte ist",
"track": "Track", "this-might-take-a-moment": "Das könnte einen kleinen Moment dauern",
"track-added": "Track hinzugefügt", "this-scanstation-is": "Diese Station ist",
"track-data-is-being-loaded": "Trackdaten werden geladen", "token": "Token",
"track-is-being-added": "Track wird hinzugefügt...", "total-distance": "gelaufene Strecke",
"track-length-in-m": "Tracklänge (in Metern)", "total-donation-amount": "Gesamtbetrag",
"track-length-must-be-greater-than-0": "Die Länge muss größer als 0 (Meter) sein", "total-donations": "Spendensumme",
"track-name": "Trackname", "total-scans": "gesamte Scans",
"track-name-must-not-be-empty": "Der Name muss angegeben werden", "track": "Track",
"tracks": "Tracks", "track-added": "Track hinzugefügt",
"update-password": "Passwort ändern", "track-data-is-being-loaded": "Trackdaten werden geladen",
"updated-contact": "Kontakt aktualisiert!", "track-is-being-added": "Track wird hinzugefügt...",
"updated-donor": "Sponsor:in wurde aktualisiert", "track-length-in-m": "Tracklänge (in Metern)",
"updated-organization": "Organisation wurde aktualisiert", "track-length-must-be-greater-than-0": "Die Länge muss größer als 0 (Meter) sein",
"updated-scan": "Scan wurde aktualisiert", "track-name": "Trackname",
"updateing-group": "Gruppe wird aktualisiert...", "track-name-must-not-be-empty": "Der Name muss angegeben werden",
"updating-card": "Karte wird aktualisiert", "tracks": "Tracks",
"updating-organization": "Organisation wird aktualisiert", "update-password": "Passwort ändern",
"updating-permissions": "Berechtigungen werden aktualisiert...", "updated-contact": "Kontakt aktualisiert!",
"updating-runner": "Läufer:in wird aktualisiert.", "updated-donor": "Sponsor:in wurde aktualisiert",
"updating-user": "Benutzer:in wird aktualisiert...", "updated-organization": "Organisation wurde aktualisiert",
"updating-your-profile": "Profil wird aktualisiert...", "updated-scan": "Scan wurde aktualisiert",
"user-added": "Benutzer hinzugefügt", "updateing-group": "Gruppe wird aktualisiert...",
"user-groups": "Benutzergruppen", "updating-card": "Karte wird aktualisiert",
"user-is-being-added": "Benutzer wird hinzugefügt ...", "updating-organization": "Organisation wird aktualisiert",
"user-updated": "Benutzer:in wurde aktualisiert", "updating-permissions": "Berechtigungen werden aktualisiert...",
"username": "Benutzername", "updating-runner": "Läufer:in wird aktualisiert.",
"users": "Benutzer", "updating-user": "Benutzer:in wird aktualisiert...",
"valid": "Gültig", "updating-your-profile": "Profil wird aktualisiert...",
"valid-city-is-required": "Du musst eine Stadt angeben", "user-added": "Benutzer hinzugefügt",
"valid-email-is-required": "Es wird eine valide E-Mail Adresse benötigt", "user-groups": "Benutzergruppen",
"valid-international-phone-number-is-required": "Du musst eine Telefonnummer im internationalen Format angeben...", "user-is-being-added": "Benutzer wird hinzugefügt ...",
"valid-zipcode-postal-code-is-required": "Du musst eine valide Postleitzahl angeben", "user-updated": "Benutzer:in wurde aktualisiert",
"verfuegbare": "Verfügbar", "username": "Benutzername",
"welcome_wavinghand": "Willkommen 👋", "users": "Benutzer",
"yes-i-copied-the-token": "Ja, ich habe den Token kopiert", "valid": "Gültig",
"you-are-going-to-loose-all-permissions-and-access-to-the-runner-system": "Du wirst all deine Berechtigungen und den Zugriff aufs Läufersystem verlieren!", "valid-city-is-required": "Du musst eine Stadt angeben",
"you-can-now-use-your-new-password-to-log-in-to-your-account": "Du kannst dich jetzt mit deinem neuen Passwort anmelden! 🎉", "valid-email-is-required": "Es wird eine valide E-Mail Adresse benötigt",
"you-can-provide-a-runner-but-you-dont-have-to": "Du kannst eine Läufer:in angeben, musst aber nicht.", "valid-international-phone-number-is-required": "Du musst eine Telefonnummer im internationalen Format angeben...",
"you-dont-have-any-scanstations-yet": "Es gibt noch keine Scannerstationen", "valid-zipcode-postal-code-is-required": "Du musst eine valide Postleitzahl angeben",
"you-have-to-provide-an-organization": "Du musst eine Organisation angeben", "verfuegbare": "Verfügbar",
"you-have-to-save-your-changes-to-generate-a-link": "Du musst deine Änderungen speichern, um einen Link zu generieren.", "welcome_wavinghand": "Willkommen 👋",
"you-must-create-at-least-one-card-or-cancel": "Du musst mindestens eine Blankokarte erstellen (oder abbrechen).", "yes-i-copied-the-token": "Ja, ich habe den Token kopiert",
"zip-postal-code": "Postleitzahl", "you-are-going-to-loose-all-permissions-and-access-to-the-runner-system": "Du wirst all deine Berechtigungen und den Zugriff aufs Läufersystem verlieren!",
"create-and-generate-pdf": "Erstellen und PDF herunterladen", "you-can-now-use-your-new-password-to-log-in-to-your-account": "Du kannst dich jetzt mit deinem neuen Passwort anmelden! 🎉",
"create-without-pdf": "Ohne PDF erstellen" "you-can-provide-a-runner-but-you-dont-have-to": "Du kannst eine Läufer:in angeben, musst aber nicht.",
} "you-dont-have-any-scanstations-yet": "Es gibt noch keine Scannerstationen",
"you-have-to-provide-an-organization": "Du musst eine Organisation angeben",
"you-have-to-save-your-changes-to-generate-a-link": "Du musst deine Änderungen speichern, um einen Link zu generieren.",
"you-must-create-at-least-one-card-or-cancel": "Du musst mindestens eine Blankokarte erstellen (oder abbrechen).",
"zip-postal-code": "Postleitzahl"
}

View File

@@ -1,428 +1,433 @@
{ {
"404message": "Sorry, the page you are looking for could not be found.", "404message": "Sorry, the page you are looking for could not be found.",
"404title": "Error 404", "404title": "Error 404",
"about": "About", "about": "About",
"action": "Action", "action": "Action",
"active": "Active", "active": "Active",
"add-card": "Add Card", "add-card": "Add Card",
"add-donation": "Add donation", "add-donation": "Add donation",
"add-donor": "add donor", "add-donor": "add donor",
"add-scan": "Add scan", "add-scan": "Add scan",
"add-the-first-scanstation": "Add your first scanstation.", "add-the-first-scanstation": "Add your first scanstation.",
"add-user-group": "Add User Group", "add-user-group": "Add User Group",
"add-your-first-card": "Add your first card", "add-your-first-card": "Add your first card",
"add-your-first-contact": "Add your first contact", "add-your-first-contact": "Add your first contact",
"add-your-first-donor": "add your first donor", "add-your-first-donor": "add your first donor",
"add-your-first-group": "Add your first group", "add-your-first-group": "Add your first group",
"add-your-first-organization": "Add your first organization", "add-your-first-organization": "Add your first organization",
"add-your-first-runner": "Add your first runner", "add-your-first-runner": "Add your first runner",
"add-your-first-team": "Add your first team", "add-your-first-team": "Add your first team",
"add-your-first-track": "Add your first track.", "add-your-first-track": "Add your first track.",
"add-your-first-user": "Add your first user", "add-your-first-user": "Add your first user",
"add-your-fist-donation": "Add your fist donation", "add-your-fist-donation": "Add your fist donation",
"add-your-fist-scan": "Add your fist scan", "add-your-fist-scan": "Add your fist scan",
"adding-card": "Adding Card", "adding-card": "Adding Card",
"adding-scan": "Adding Scan", "adding-scan": "Adding Scan",
"address": "Address", "address": "Address",
"address-is-required": "Address is required", "address-is-required": "Address is required",
"after-deletion-we-cant-restore-your-old-profile": "After deletion we can't restore your old profile!", "after-deletion-we-cant-restore-your-old-profile": "After deletion we can't restore your old profile!",
"after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that": "After the update you'll get logged out - Please login with your new password after that.", "after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that": "After the update you'll get logged out - Please login with your new password after that.",
"all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well", "all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well",
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!", "all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!", "all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!",
"amount": "Amount", "amount": "Amount",
"amount-per-kilometer": "Amount per kilometer", "amount-per-kilometer": "Amount per kilometer",
"apartment-suite-etc": "Apartment, suite, etc.", "apartment-suite-etc": "Apartment, suite, etc.",
"application_name": "Lauf für Kaya! - Admin", "application_name": "Lauf für Kaya! - Admin",
"applying-changes": "Applying Changes", "applying-changes": "Applying Changes",
"attention": "Attention!", "attention": "Attention!",
"author": "Author", "author": "Author",
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.", "bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.",
"by": "by", "by": "by",
"cancel": "Cancel", "cancel": "Cancel",
"cancel-delete": "Cancel Delete", "cancel-delete": "Cancel Delete",
"cancel-keep-donor": "Cancel, keep donor", "cancel-keep-donor": "Cancel, keep donor",
"cancel-keep-my-profile": "Cancel, keep my profile", "cancel-keep-my-profile": "Cancel, keep my profile",
"cancel-keep-organization": "Cancel, keep organization", "cancel-keep-organization": "Cancel, keep organization",
"cancel-keep-team": "Cancel, keep team", "cancel-keep-team": "Cancel, keep team",
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity", "cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
"card-added": "Card added", "card-added": "Card added",
"card-deleted": "Card deleted", "card-deleted": "Card deleted",
"card-updated": "Card updated", "card-updated": "Card updated",
"cards": "Cards", "cards": "Cards",
"change-your-password-here": "Change your password here", "certificates": "Certificates",
"changing-your-password": "Changing your password", "change-your-password-here": "Change your password here",
"city": "City", "changing-your-password": "Changing your password",
"click-to-copy-the-link-into-your-clipboard": "Click to copy the link into your clipboard", "city": "City",
"click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard", "click-to-copy-the-link-into-your-clipboard": "Click to copy the link into your clipboard",
"close": "Close", "click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard",
"code": "Code", "close": "Close",
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times", "code": "Code",
"confirm": "Confirm", "configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
"confirm-delete": "Confirm Delete", "confirm": "Confirm",
"confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations", "confirm-delete": "Confirm Delete",
"confirm-delete-my-user-profile": "Confirm, delete my user profile", "confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations",
"confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.", "confirm-delete-my-user-profile": "Confirm, delete my user profile",
"confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.", "confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.",
"confirm-deletion": "Confirm Deletion", "confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.",
"confirm-the-new-password": "Confirm the new password", "confirm-deletion": "Confirm Deletion",
"contact": "Contact", "confirm-the-new-password": "Confirm the new password",
"contact-deleted": "Contact deleted", "contact": "Contact",
"contact-information": "Contact Information", "contact-deleted": "Contact deleted",
"contact-is-being-updated": "Contact is being updated...", "contact-information": "Contact Information",
"contact-is-not-a-member-in-any-group": "Contact is not a member in any group", "contact-is-being-updated": "Contact is being updated...",
"contacts": "Contacts", "contact-is-not-a-member-in-any-group": "Contact is not a member in any group",
"contacts-are-being-loaded": "contacts are being loaded...", "contacts": "Contacts",
"copied-link-to-clipboard": "Copied link to clipboard", "contacts-are-being-loaded": "contacts are being loaded...",
"copied-token-to-clipboard": "Copied token to clipboard", "copied-link-to-clipboard": "Copied link to clipboard",
"count_organizations": "# Organizations", "copied-token-to-clipboard": "Copied token to clipboard",
"count_teams": "# Teams", "count_organizations": "# Organizations",
"create": "Create", "count_teams": "# Teams",
"create-a-new": "Create a new", "create": "Create",
"create-a-new-card": "Create a new card", "create-a-new": "Create a new",
"create-a-new-contact": "Create a new contact", "create-a-new-card": "Create a new card",
"create-a-new-distance-donation": "Create a new distance donation", "create-a-new-contact": "Create a new contact",
"create-a-new-donor": "Create a new donor", "create-a-new-distance-donation": "Create a new distance donation",
"create-a-new-fixed-donation": "Create a new fixed donation", "create-a-new-donor": "Create a new donor",
"create-a-new-organization": "Create a new Organization", "create-a-new-fixed-donation": "Create a new fixed donation",
"create-a-new-runner": "Create a new Runner", "create-a-new-organization": "Create a new Organization",
"create-a-new-scan-fixed-only": "Create a new scan (fixed only)", "create-a-new-runner": "Create a new Runner",
"create-a-new-scanstation": "Create a new station", "create-a-new-scan-fixed-only": "Create a new scan (fixed only)",
"create-a-new-team": "Create a new team", "create-a-new-scanstation": "Create a new station",
"create-a-new-track": "Create a new Track", "create-a-new-team": "Create a new team",
"create-a-new-user": "Create a new User", "create-a-new-track": "Create a new Track",
"create-a-new-user-group": "Create a new user group", "create-a-new-user": "Create a new User",
"create-bulk-blanco-cards": "Create bulk blanco cards", "create-a-new-user-group": "Create a new user group",
"create-bulk-cards": "Add blanco cards", "create-and-generate-pdf": "Create and generate PDF",
"create-organization": "Create Organization", "create-bulk-blanco-cards": "Create bulk blanco cards",
"create-team": "Create Team", "create-bulk-cards": "Add blanco cards",
"create-track": "Create Track", "create-organization": "Create Organization",
"create-user": "Create User", "create-team": "Create Team",
"created-blanco-cards": "Created blanco cards", "create-track": "Create Track",
"creating-blanco-cards": "Creating blanco cards", "create-user": "Create User",
"credits": "Credits", "create-without-pdf": "Create without PDF",
"csv_import__class": "Class", "created-blanco-cards": "Created blanco cards",
"csv_import__firstname": "Firstname", "creating-blanco-cards": "Creating blanco cards",
"csv_import__lastname": "Lastname", "credits": "Credits",
"csv_import__middlename": "Middlename", "csv_import__class": "Class",
"csv_import__team": "Team", "csv_import__firstname": "Firstname",
"danger-zone": "Danger zone", "csv_import__lastname": "Lastname",
"dashboard-greeting": "Hello", "csv_import__middlename": "Middlename",
"dashboard-title": "Dashboard", "csv_import__team": "Team",
"datatable": { "danger-zone": "Danger zone",
"search": "🔍 Search...", "dashboard-greeting": "Hello",
"sort_column_ascending": "Sort column ascending", "dashboard-title": "Dashboard",
"sort_column_descending": "Sort column descending", "datatable": {
"previous": "Previous", "search": "🔍 Search...",
"next": "Next", "sort_column_ascending": "Sort column ascending",
"page": "Page", "sort_column_descending": "Sort column descending",
"showing": "Showing", "previous": "Previous",
"records": "Records", "next": "Next",
"of": "of", "page": "Page",
"to": "to", "showing": "Showing",
"loading": "Loading...", "records": "Records",
"no_matching_records_found": "No matching records found", "of": "of",
"an_error_happened_while_fetching_the_data": "An error happened while fetching the data" "to": "to",
}, "loading": "Loading...",
"delete": "Delete", "no_matching_records_found": "No matching records found",
"delete-contact": "Delete Contact", "an_error_happened_while_fetching_the_data": "An error happened while fetching the data"
"delete-donation": "Delete Donation", },
"delete-donor": "Delete donor", "delete": "Delete",
"delete-group": "Delete Group", "delete-contact": "Delete Contact",
"delete-organization": "Delete Organization", "delete-donation": "Delete Donation",
"delete-profile": "Delete Profile", "delete-donor": "Delete donor",
"delete-runner": "Delete Runner", "delete-group": "Delete Group",
"delete-scan": "Delete scan", "delete-organization": "Delete Organization",
"delete-station": "Delete station", "delete-profile": "Delete Profile",
"delete-team": "Delete Team", "delete-runner": "Delete Runner",
"delete-user": "Delete User", "delete-scan": "Delete scan",
"deleted-scan": "Deleted scan", "delete-station": "Delete station",
"dependency_name": "Name", "delete-team": "Delete Team",
"description": "description", "delete-user": "Delete User",
"description-optional": "Description (optional)", "deleted-scan": "Deleted scan",
"deselect-all": "deselect all", "dependency_name": "Name",
"details": "Details", "description": "description",
"disabled": "disabled", "description-optional": "Description (optional)",
"distance": "Distance", "deselect-all": "deselect all",
"distance-donation": "distance donation", "details": "Details",
"distance-in-km": "Distance in km", "disabled": "disabled",
"distance-track": "Distance (+Track)", "distance": "Distance",
"do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?", "distance-donation": "distance donation",
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?", "distance-in-km": "Distance in km",
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?", "distance-track": "Distance (+Track)",
"do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations", "do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?",
"documentation": "Documentation", "do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
"donation-amount": "Donation amount", "do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
"donation-amount-must-be-greater-that-0-00eur": "Donation amount must be greater that 0.00€", "do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations",
"donations": "Donations", "documentation": "Documentation",
"donor": "Donor", "donation-amount": "Donation amount",
"donor-added": "Donor added", "donation-amount-must-be-greater-that-0-00eur": "Donation amount must be greater that 0.00€",
"donor-deleted": "donor deleted", "donations": "Donations",
"donor-has-no-associated-donations": "Donor has no associated donations.", "donor": "Donor",
"donor-is-being-added": "Donor is being added...", "donor-added": "Donor added",
"donor-is-being-updated": "Donor is being updated", "donor-deleted": "donor deleted",
"donors": "Donors", "donor-has-no-associated-donations": "Donor has no associated donations.",
"donors-are-being-loaded": "donors are being loaded", "donor-is-being-added": "Donor is being added...",
"dont-have-your-email-connected": "Don't have your email connected?", "donor-is-being-updated": "Donor is being updated",
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌", "donors": "Donors",
"e-mail-adress": "E-Mail Adress", "donors-are-being-loaded": "donors are being loaded",
"edit": "Edit", "dont-have-your-email-connected": "Don't have your email connected?",
"edit-a-card": "Edit a card", "dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
"edit-permissions": "edit permissions", "e-mail-adress": "E-Mail Adress",
"email_address_or_username": "Email / username", "edit": "Edit",
"enabled": "enabled", "edit-a-card": "Edit a card",
"enabled_large": "Enabled", "edit-permissions": "edit permissions",
"english": "English", "email_address_or_username": "Email / username",
"error-during-import": "Error during import", "enabled": "enabled",
"error-whyile-copying-to-clipboard": "Error while copying to clipboard", "enabled_large": "Enabled",
"error_on_login": "Error on login", "english": "English",
"erteilte": "Directly granted", "error-during-import": "Error during import",
"everything-concerning-your-profile": "Everything concerning your profile", "error-whyile-copying-to-clipboard": "Error while copying to clipboard",
"everything-is-more-fun-together": "everything is more fun together 🏃‍♂️🏃‍♀️🏃‍♂️", "error_on_login": "Error on login",
"faq": "FAQ", "erteilte": "Directly granted",
"filter-by-organization-team": "Filter by Organization/ Team", "everything-concerning-your-profile": "Everything concerning your profile",
"first-name": "First name", "everything-is-more-fun-together": "everything is more fun together 🏃‍♂️🏃‍♀️🏃‍♂️",
"first-name-is-required": "First Name is required", "faq": "FAQ",
"first-scan-of-the-day": "First scan of the day.", "filter-by-organization-team": "Filter by Organization/ Team",
"fixed-donation": "fixed donation", "first-name": "First name",
"forgot_password": "Forgot your password?", "first-name-is-required": "First Name is required",
"geerbte": "inherited", "first-scan-of-the-day": "First scan of the day.",
"general-stats": "General Stats", "fixed-donation": "fixed donation",
"general_promise_error": "😢 Error", "forgot_password": "Forgot your password?",
"generate-runnercards": "Generate Runnercards", "geerbte": "inherited",
"generate-sponsoring-contract": "generate sponsoring contract", "general-stats": "General Stats",
"generate-sponsoring-contracts": "generate sponsoring contracts", "general_promise_error": "😢 Error",
"generating-pdf": "generating PDF...", "generate-runner-certificate": "Generate runner certificate",
"generating-pdfs": "generating PDFs...", "generate-runner-certificates": "Generate runner certificates",
"generic-ui-logic-error": "Something went wrong in the UI logic", "generate-runnercards": "Generate Runnercards",
"german": "German", "generate-sponsoring-contract": "generate sponsoring contract",
"go-to-login": "Go To Login", "generate-sponsoring-contracts": "generate sponsoring contracts",
"goback": "Go Home", "generating-pdf": "generating PDF...",
"granted": "granted", "generating-pdfs": "generating PDFs...",
"group": "Group", "generic-ui-logic-error": "Something went wrong in the UI logic",
"group-added": "Group added", "german": "German",
"group-is-being-added": "Group is being added...", "go-to-login": "Go To Login",
"group-name-is-required": "Group name is required", "goback": "Go Home",
"group-updated": "group updated", "granted": "granted",
"groups": "Groups", "group": "Group",
"groups-are-being-loaded": "Groups are being loaded", "group-added": "Group added",
"home": "Home", "group-is-being-added": "Group is being added...",
"icon-image-credits": "We also want to thank these projects for illustrations and icons:", "group-name-is-required": "Group name is required",
"if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button": "If you want to create multiple blanco cards: Try the 'Add blanco cards' button.", "group-updated": "group updated",
"import-finished": "Import finished", "groups": "Groups",
"import-runners": "Import runners", "groups-are-being-loaded": "Groups are being loaded",
"import__target-organization": "Target Organization", "home": "Home",
"imprint": "Imprint", "icon-image-credits": "We also want to thank these projects for illustrations and icons:",
"imprint-loading": "Imprint loading...", "if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button": "If you want to create multiple blanco cards: Try the 'Add blanco cards' button.",
"inactive": "Inactive", "import-finished": "Import finished",
"installed-version": "Installed version", "import-runners": "Import runners",
"internal-error": "Internal Error", "import__target-organization": "Target Organization",
"invalid": "Invalid", "imprint": "Imprint",
"invalid-mail-reset": "the provided email is invalid", "imprint-loading": "Imprint loading...",
"just-enter-how-many-you-want-and-the-system-will-create-them": "Just enter how many you want and the system will create them", "inactive": "Inactive",
"laeufer-hinzufuegen": "Add runner", "installed-version": "Installed version",
"laeufer-importieren": "Läufer importieren", "internal-error": "Internal Error",
"laptime": "Laptime", "invalid": "Invalid",
"last-name": "Last name", "invalid-mail-reset": "the provided email is invalid",
"last-name-is-required": "Last Name is required", "just-enter-how-many-you-want-and-the-system-will-create-them": "Just enter how many you want and the system will create them",
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.", "laeufer-hinzufuegen": "Add runner",
"license": "License", "laeufer-importieren": "Läufer importieren",
"licenses-are-being-loaded": "Licenses are being loaded...", "laptime": "Laptime",
"loading-cards": "Loading cards", "last-name": "Last name",
"loading-contact-details": "Loading contact details...", "last-name-is-required": "Last Name is required",
"loading-donation-details": "Loading donation details", "lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
"loading-donor-details": "Loading donor details", "license": "License",
"loading-group-detail": "Loading group detail...", "licenses-are-being-loaded": "Licenses are being loaded...",
"loading-profile-data": "Loading profile data", "loading-cards": "Loading cards",
"loading-runners": "loading runners...", "loading-contact-details": "Loading contact details...",
"loading-station-details": "Loading station details", "loading-donation-details": "Loading donation details",
"log_in": "Log in", "loading-donor-details": "Loading donor details",
"log_in_to_your_account": "Log in to your account", "loading-group-detail": "Loading group detail...",
"login_is_checked": "Login is being checked...", "loading-profile-data": "Loading profile data",
"logout": "Logout", "loading-runners": "loading runners...",
"mail-validation-in-progress": "mail validation in progress...", "loading-station-details": "Loading station details",
"manage-admin-users": "manage admin users", "log_in": "Log in",
"middle-name": "Middle name", "log_in_to_your_account": "Log in to your account",
"minimum-lap-time-in-s": "minimum lap time in s", "login_is_checked": "Login is being checked...",
"minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0", "logout": "Logout",
"must-be-at-least-10-characters-long": "Must be at least 10 characters long!", "mail-validation-in-progress": "mail validation in progress...",
"must-contain-a-lowercase-letter": "Must contain a lowercase letter!", "manage-admin-users": "manage admin users",
"must-contain-a-number": "Must contain a number!", "middle-name": "Middle name",
"must-contain-a-uppercase-letter": "Must contain a uppercase letter!", "minimum-lap-time-in-s": "minimum lap time in s",
"name": "Name", "minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0",
"name-is-required": "Name is required", "must-be-at-least-10-characters-long": "Must be at least 10 characters long!",
"new-password": "New password", "must-contain-a-lowercase-letter": "Must contain a lowercase letter!",
"no-contact-found": "No contacts found", "must-contain-a-number": "Must contain a number!",
"no-contact-selected": "No contact selected", "must-contain-a-uppercase-letter": "Must contain a uppercase letter!",
"no-contact-specified": "no contact specified", "name": "Name",
"no-donors-found": "No donors found", "name-is-required": "Name is required",
"no-license-text-could-be-found": "No license text could be found 😢", "new-password": "New password",
"no-organization-or-team-found": "No organization or team found", "no-contact-found": "No contacts found",
"no-organization-specified": "no organization specified", "no-contact-selected": "No contact selected",
"no-organizations-found": "No organizations found", "no-contact-specified": "no contact specified",
"no-runners-found": "No runners found", "no-donors-found": "No donors found",
"no-tracks-added-yet": "there are no tracks added yet.", "no-license-text-could-be-found": "No license text could be found 😢",
"non-blanko": "Non/Blanko", "no-organization-or-team-found": "No organization or team found",
"organization": "Organization", "no-organization-specified": "no organization specified",
"organization-added": "Organization added", "no-organizations-found": "No organizations found",
"organization-deleted": "Organization deleted", "no-runners-found": "No runners found",
"organization-detail-is-being-loaded": "organization detail is being loaded...", "no-tracks-added-yet": "there are no tracks added yet.",
"organization-is-being-added": "Organization is being added...", "non-blanko": "Non/Blanko",
"organization-name-is-required": "Organization name is required", "organization": "Organization",
"organizations": "Organizations", "organization-added": "Organization added",
"organizations-are-being-loaded": "organizations are being loaded...", "organization-deleted": "Organization deleted",
"orgs": "Organizations", "organization-detail-is-being-loaded": "organization detail is being loaded...",
"oss_credit_description": "We use a lot of open source software on these projects, and would like to thank the following projects and contributors who help make open source great!", "organization-is-being-added": "Organization is being added...",
"password": "Password", "organization-name-is-required": "Organization name is required",
"password-changed": "Password changed!", "organizations": "Organizations",
"password-is-required": "Password is required", "organizations-are-being-loaded": "organizations are being loaded...",
"password-reset-failed": "Password reset failed!", "orgs": "Organizations",
"password-reset-in-progress": "Password Reset in Progress...", "oss_credit_description": "We use a lot of open source software on these projects, and would like to thank the following projects and contributors who help make open source great!",
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".", "password": "Password",
"password-reset-successful": "Password Reset successful!", "password-changed": "Password changed!",
"passwords-dont-match": "Passwords don't match!", "password-is-required": "Password is required",
"pdf-generation-failed": "PDF generation failed!", "password-reset-failed": "Password reset failed!",
"pdf-successfully-generated": "PDF successfully generated!", "password-reset-in-progress": "Password Reset in Progress...",
"pdfs-successfully-generated": "PDFs successfully generated!", "password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
"per-kilometer": "per Kilometer", "password-reset-successful": "Password Reset successful!",
"permissions": "Permissions", "passwords-dont-match": "Passwords don't match!",
"permissions-updated": "Permissions updated!", "pdf-generation-failed": "PDF generation failed!",
"phone": "Phone", "pdf-successfully-generated": "PDF successfully generated!",
"please-copy-the-token-and-store-it-somewhere-save": "Please copy the token and store it somewhere safe.", "pdfs-successfully-generated": "PDFs successfully generated!",
"please-provide-a-password": "Please provide a password...", "per-kilometer": "per Kilometer",
"please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor", "permissions": "Permissions",
"please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation", "permissions-updated": "Permissions updated!",
"please-provide-the-nessecary-information-to-create-a-new-scan": "Please provide the nessecary information to create a new scan.", "phone": "Phone",
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file", "please-copy-the-token-and-store-it-somewhere-save": "Please copy the token and store it somewhere safe.",
"please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.", "please-provide-a-password": "Please provide a password...",
"please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.", "please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor",
"please-provide-the-required-information-to-add-a-new-organization": "Please provide the required information to add a new organization.", "please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation",
"please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.", "please-provide-the-nessecary-information-to-create-a-new-scan": "Please provide the nessecary information to create a new scan.",
"please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.", "please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.", "please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.",
"please-provide-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.", "please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.",
"please-provide-the-required-information-to-create-a-new-scanstation": "Please provide the required information to create a new scanstation", "please-provide-the-required-information-to-add-a-new-organization": "Please provide the required information to add a new organization.",
"please-request-a-new-reset-mail": "Please request a new reset mail...", "please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.",
"privacy": "Privacy", "please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.",
"privacy-loading": "Privacy loading...", "please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
"profile": "Profile", "please-provide-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.",
"profile-picture": "Profile Picture", "please-provide-the-required-information-to-create-a-new-scanstation": "Please provide the required information to create a new scanstation",
"profile-updated": "Profile updated!", "please-request-a-new-reset-mail": "Please request a new reset mail...",
"read-license": "Read License", "privacy": "Privacy",
"receipt-needed": "Receipt needed", "privacy-loading": "Privacy loading...",
"repo_link": "Link", "profile": "Profile",
"request-a-new-reset-mail": "Request a new reset mail", "profile-picture": "Profile Picture",
"reset-my-password": "Reset my password", "profile-updated": "Profile updated!",
"reset-password": "Reset your password", "read-license": "Read License",
"runner": "Runner", "receipt-needed": "Receipt needed",
"runner-added": "Runner added", "repo_link": "Link",
"runner-import": "Runner Import", "request-a-new-reset-mail": "Request a new reset mail",
"runner-is-being-added": "Runner is being added...", "reset-my-password": "Reset my password",
"runner-updated": "Runner updated!", "reset-password": "Reset your password",
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"", "runner": "Runner",
"runners": "Runners", "runner-added": "Runner added",
"runners-are-being-imported": "Runners are being imported...", "runner-import": "Runner Import",
"runners-are-being-loaded": "runners are being loaded...", "runner-is-being-added": "Runner is being added...",
"save": "Save", "runner-updated": "Runner updated!",
"save-changes": "Save Changes", "runnercards": "Runnercards",
"scan-added": "Scan added", "runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
"scan-is-being-updated": "Scan is being updated", "runners": "Runners",
"scan-with-fixed-distance": "Scan with fixed distance", "runners-are-being-imported": "Runners are being imported...",
"scans": "Scans", "runners-are-being-loaded": "runners are being loaded...",
"scans-are-being-loaded": "Scans are being loaded", "save": "Save",
"scanstation": "Scanstation", "save-changes": "Save Changes",
"scanstation-added": "Scanstation added", "scan-added": "Scan added",
"scanstation-is-being-added": "Adding scanstation...", "scan-is-being-updated": "Scan is being updated",
"scanstations": "Scanstations", "scan-with-fixed-distance": "Scan with fixed distance",
"scanstations-are-being-loaded": "Loading scanstations...", "scans": "Scans",
"search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)", "scans-are-being-loaded": "Scans are being loaded",
"search-for-an-organization-or-team-by-name-or-id": "Search for an organization or team (by name or id)", "scanstation": "Scanstation",
"search-for-donor-name-or-id": "Search for donor (by name or id)", "scanstation-added": "Scanstation added",
"search-for-permission": "Search for permission", "scanstation-is-being-added": "Adding scanstation...",
"search-for-runner-by-name-or-id": "Search for runner (by name or id)", "scanstations": "Scanstations",
"select-all": "select all", "scanstations-are-being-loaded": "Loading scanstations...",
"select-language": "Select language", "search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)",
"selfservice-registration": "Selfservice registration", "search-for-an-organization-or-team-by-name-or-id": "Search for an organization or team (by name or id)",
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services", "search-for-donor-name-or-id": "Search for donor (by name or id)",
"set-the-user-active-inactive": "set the user active/ inactive", "search-for-permission": "Search for permission",
"settings": "Settings", "search-for-runner-by-name-or-id": "Search for runner (by name or id)",
"settings-for-your-profile": "Settings for your profile", "select-all": "select all",
"something-about-the-group": "Something about the group...", "select-language": "Select language",
"stats-are-being-loaded": "stats are being loaded...", "selfservice-registration": "Selfservice registration",
"status": "Status", "send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile", "set-the-user-active-inactive": "set the user active/ inactive",
"successful-password-reset": "Successful password reset!", "settings": "Settings",
"team": "Team", "settings-for-your-profile": "Settings for your profile",
"team-detail-is-being-loaded": "team detail is being loaded...", "something-about-the-group": "Something about the group...",
"team-name": "Team name", "sponsorings": "Sponsorings",
"team-name-is-required": "team name is required", "stats-are-being-loaded": "stats are being loaded...",
"teams": "Teams", "status": "Status",
"teams-are-being-loaded": "teams are being loaded...", "stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
"the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "the provided phone number is invalid.<br />please enter a valid international number...", "successful-password-reset": "Successful password reset!",
"the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m", "team": "Team",
"the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again": "The scanstation api token will only get displayed once - you won't be able to change or view it again!", "team-detail-is-being-loaded": "team detail is being loaded...",
"there-are-no-cards-yet": "There are no cards yet.", "team-name": "Team name",
"there-are-no-contacts-added-yet": "There are no contacts added yet.", "team-name-is-required": "team name is required",
"there-are-no-donations-yet": "There are no donations yet", "teams": "Teams",
"there-are-no-donors-yet": "There are no donors yet", "teams-are-being-loaded": "teams are being loaded...",
"there-are-no-groups-yet": "There are no groups yet", "the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "the provided phone number is invalid.<br />please enter a valid international number...",
"there-are-no-organizations-added-yet": "There are no organizations added yet.", "the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m",
"there-are-no-runners-added-yet": "There are no runners added yet.", "the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again": "The scanstation api token will only get displayed once - you won't be able to change or view it again!",
"there-are-no-scans-yet": "There are no scans yet", "there-are-no-cards-yet": "There are no cards yet.",
"there-are-no-teams-added-yet": "There are no teams added yet.", "there-are-no-contacts-added-yet": "There are no contacts added yet.",
"there-are-no-users-added-yet": "There are no users added yet.", "there-are-no-donations-yet": "There are no donations yet",
"this-card-is": "This card is", "there-are-no-donors-yet": "There are no donors yet",
"this-might-take-a-moment": "This might take a moment 👀", "there-are-no-groups-yet": "There are no groups yet",
"this-scanstation-is": "This scanstation is", "there-are-no-organizations-added-yet": "There are no organizations added yet.",
"token": "Token", "there-are-no-runners-added-yet": "There are no runners added yet.",
"total-distance": "total distance", "there-are-no-scans-yet": "There are no scans yet",
"total-donation-amount": "total donation amount", "there-are-no-teams-added-yet": "There are no teams added yet.",
"total-donations": "total donations", "there-are-no-users-added-yet": "There are no users added yet.",
"total-scans": "total scans", "this-card-is": "This card is",
"track": "Track", "this-might-take-a-moment": "This might take a moment 👀",
"track-added": "Track added", "this-scanstation-is": "This scanstation is",
"track-data-is-being-loaded": "Track data is being loaded", "token": "Token",
"track-is-being-added": "Track is being added...", "total-distance": "total distance",
"track-length-in-m": "Track Length in m", "total-donation-amount": "total donation amount",
"track-length-must-be-greater-than-0": "Track length must be greater than 0", "total-donations": "total donations",
"track-name": "Track name", "total-scans": "total scans",
"track-name-must-not-be-empty": "Track name must not be empty", "track": "Track",
"tracks": "Tracks", "track-added": "Track added",
"update-card": "Update Card", "track-data-is-being-loaded": "Track data is being loaded",
"update-password": "Update password", "track-is-being-added": "Track is being added...",
"updated-contact": "Updated contact!", "track-length-in-m": "Track Length in m",
"updated-donor": "updated donor", "track-length-must-be-greater-than-0": "Track length must be greater than 0",
"updated-organization": "updated organization", "track-name": "Track name",
"updated-scan": "updated scan", "track-name-must-not-be-empty": "Track name must not be empty",
"updateing-group": "updateing group...", "tracks": "Tracks",
"updating-card": "Updating card", "update-card": "Update Card",
"updating-organization": "updating organization", "update-password": "Update password",
"updating-permissions": "updating permissions...", "updated-contact": "Updated contact!",
"updating-runner": "Updating runner...", "updated-donor": "updated donor",
"updating-user": "updating user...", "updated-organization": "updated organization",
"updating-your-profile": "Updating your profile...", "updated-scan": "updated scan",
"user-added": "User added", "updateing-group": "updateing group...",
"user-groups": "User Groups", "updating-card": "Updating card",
"user-is-being-added": "User is being added...", "updating-organization": "updating organization",
"user-updated": "User updated", "updating-permissions": "updating permissions...",
"username": "Username", "updating-runner": "Updating runner...",
"users": "Users", "updating-user": "updating user...",
"valid": "Valid", "updating-your-profile": "Updating your profile...",
"valid-city-is-required": "Valid city is required", "user-added": "User added",
"valid-email-is-required": "valid email is required", "user-groups": "User Groups",
"valid-international-phone-number-is-required": "valid international phone number is required...", "user-is-being-added": "User is being added...",
"valid-zipcode-postal-code-is-required": "Valid zipcode/ postal code is required", "user-updated": "User updated",
"verfuegbare": "availdable", "username": "Username",
"welcome_wavinghand": "Welcome 👋", "users": "Users",
"yes-i-copied-the-token": "Yes, I copied the token", "valid": "Valid",
"you-are-going-to-loose-all-permissions-and-access-to-the-runner-system": "You are going to loose all permissions and access to the runner system!", "valid-city-is-required": "Valid city is required",
"you-can-now-use-your-new-password-to-log-in-to-your-account": "You can now use your new password to log in to your account! 🎉", "valid-email-is-required": "valid email is required",
"you-can-provide-a-runner-but-you-dont-have-to": "You can provide a runner, but you don't have to.", "valid-international-phone-number-is-required": "valid international phone number is required...",
"you-dont-have-any-scanstations-yet": "You don't have any scanstations yet", "valid-zipcode-postal-code-is-required": "Valid zipcode/ postal code is required",
"you-have-to-provide-an-organization": "You have to provide an organization", "verfuegbare": "availdable",
"you-have-to-save-your-changes-to-generate-a-link": "You have to save your changes to generate a link.", "welcome_wavinghand": "Welcome 👋",
"you-must-create-at-least-one-card-or-cancel": "You must create at least one card (or cancel).", "yes-i-copied-the-token": "Yes, I copied the token",
"zip-postal-code": "ZIP/ postal code", "you-are-going-to-loose-all-permissions-and-access-to-the-runner-system": "You are going to loose all permissions and access to the runner system!",
"create-and-generate-pdf": "Create and generate PDF", "you-can-now-use-your-new-password-to-log-in-to-your-account": "You can now use your new password to log in to your account! 🎉",
"create-without-pdf": "Create without PDF" "you-can-provide-a-runner-but-you-dont-have-to": "You can provide a runner, but you don't have to.",
} "you-dont-have-any-scanstations-yet": "You don't have any scanstations yet",
"you-have-to-provide-an-organization": "You have to provide an organization",
"you-have-to-save-your-changes-to-generate-a-link": "You have to save your changes to generate a link.",
"you-must-create-at-least-one-card-or-cancel": "You must create at least one card (or cancel).",
"zip-postal-code": "ZIP/ postal code"
}

9
src/main.js Normal file
View File

@@ -0,0 +1,9 @@
import 'windi.css';
import "toastify-js/src/toastify.css";
import "gridjs/dist/theme/mermaid.css";
import App from './App.svelte';
const app = new App({
target: document.body
});
export default app;

View File

@@ -1,14 +0,0 @@
export const register = () => {
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then(
(registration) => {
// console.log(`sw successful with scope: ${registration.scope}`);
},
(err) => {
// console.log(`sw failed: ${err}`);
}
);
});
}
};

View File

@@ -1,14 +1,13 @@
module.exports = { module.exports = {
purge: {
content: [ './src/**/*.svelte' ]
},
// darkMode: 'media',
variants: {},
plugins: [],
theme: { theme: {
container: { extend: {
center: true, colors: {
padding: '1.5rem' reepolee: {
500: '#b40000',
600: '#9c0000',
700: '#750000'
}
}
} }
} }
}; };

View File

@@ -1,19 +0,0 @@
const fs = require('fs');
let content_svelteconfig = fs.readFileSync('./s-config.template.js', { encoding: 'utf8' });
let content_html = fs.readFileSync('./index.template.html', { encoding: 'utf8' });
if (process.env.NODE_ENV_ODIT == 'development_fast') {
content_html = content_html.replace(
'__TAILWIND_INSERT__',
'<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss@2.0.2/dist/tailwind.min.css">'
);
content_svelteconfig = content_svelteconfig.replace('__insert__', '{postcss:{}}');
} else {
content_html = content_html.replace('__TAILWIND_INSERT__', '');
content_svelteconfig = content_svelteconfig.replace(
'__insert__',
"{postcss:{plugins:[require('tailwindcss'),require('autoprefixer')]}}"
);
}
fs.writeFileSync('./public/index.html', content_html);
fs.writeFileSync('./svelte.config.js', content_svelteconfig);
console.info('dev setup script done');

View File

@@ -1,5 +1,5 @@
const fs = require('fs'); const fs = require('fs');
const package = JSON.parse(fs.readFileSync(`./package.json`, { encoding: 'utf-8' })); const package = JSON.parse(fs.readFileSync(`./package.json`, { encoding: 'utf-8' }));
const original = fs.readFileSync(`./index.template.html`, { encoding: 'utf-8' }); const original = fs.readFileSync(`./index.html`, { encoding: 'utf-8' });
let out = original.replace(/RELEASE_INFO-(\S)+-RELEASE_INFO/gi, 'RELEASE_INFO-' + package.version + '-RELEASE_INFO'); let out = original.replace(/RELEASE_INFO-(\S)+-RELEASE_INFO/gi, 'RELEASE_INFO-' + package.version + '-RELEASE_INFO');
fs.writeFileSync(`./index.template.html`, out); fs.writeFileSync(`./index.html`, out);

50
vite.config.js Normal file
View File

@@ -0,0 +1,50 @@
import svelte from '@sveltejs/vite-plugin-svelte';
import windiCSS from 'vite-plugin-windicss';
import { minify } from 'html-minifier';
import { defineConfig } from 'vite';
//
const indexReplace = () => {
return {
name: 'html-transform',
transformIndexHtml(html) {
return minify(html, {
collapseWhitespace: true
});
}
};
};
export default defineConfig(({ command, mode }) => {
const isProduction = mode === 'production';
return {
// base: './',
build: {
polyfillDynamicImport: false,
cssCodeSplit: false,
minify: isProduction
},
plugins: [
windiCSS({
//@ts-ignore
verbose: true,
silent: false,
debug: true,
config: 'tailwind.config.js', // tailwind config file path (optional)
compile: false, // false: interpretation mode; true: compilation mode
prefix: 'windi-', // set compilation mode style prefix
globalPreflight: true, // set preflight style is global or scoped
globalUtility: true // set utility style is global or scoped
}),
svelte({
//@ts-ignore
hot: !isProduction,
emitCss: true,
extensions: [ '.md', '.svx', '.svelte' ],
preprocess: [
//
]
}),
indexReplace()
]
};
});

View File

@@ -1,9 +0,0 @@
module.exports = {
globDirectory: 'public',
globPatterns: [ '**/*.{js,ico,png,svg,html,webmanifest,txt,json}' ],
globIgnores: [ 'env.js', 'env.sample.js' ],
swDest: 'public/sw.js',
cleanupOutdatedCaches: true,
mode: 'production',
sourcemap: false
};