Compare commits

..

72 Commits

Author SHA1 Message Date
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
97e338f9d4 Added button (including translations
ref #116
2021-03-29 17:46:51 +02:00
636f018daa Added comment
ref #116
2021-03-29 17:44:59 +02:00
c8d639024a Added function for generating cards with pdf
ref #116
2021-03-29 17:44:30 +02:00
6be2ee626a package cleanup 2021-03-26 21:22:46 +01:00
f7fc1967a5 🚀RELEASE v0.10.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-26 20:07:14 +01:00
aedb8a765b new license file version [CI SKIP] 2021-03-26 19:06:59 +00:00
cf58bd15c3 Bumped lfk-client version 🔝
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-26 20:05:26 +01:00
34f4f68524 new license file version [CI SKIP] 2021-03-26 19:04:28 +00:00
09b8144080 Merge pull request 'Implemented password strength test feature/106-password_strength' (#115) from feature/106-password_strength into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #115
2021-03-26 19:03:03 +00:00
f1e6fb4ce7 Merge branch 'dev' into feature/106-password_strength 2021-03-26 19:59:47 +01:00
4167819e7a Formatting🛠
ref #106
2021-03-26 19:52:31 +01:00
5bd3a463f0 Sorted translations 🌍
ref #106
2021-03-26 19:51:57 +01:00
79c447b4c6 Added translations
ref #106
2021-03-26 19:51:27 +01:00
540304f947 User creation can now only be triggered if pw is strong enoug
ref #106
2021-03-26 19:48:42 +01:00
75d8f7331b Reset can now only be triggered if pw is strong enoug
ref #106
2021-03-26 19:47:26 +01:00
b2509e9e53 Module now exports functions that check if a password is strong enough and equal to a potential confirmation field
ref #106
2021-03-26 19:45:53 +01:00
7862f44653 Now using pw strength component for user creation
ref #106
2021-03-26 19:31:21 +01:00
962dd0c1bb Added missing exports
ref #106
2021-03-26 19:29:47 +01:00
5d5f7c7f5c Now using pw strength component for reset
ref #106
2021-03-26 19:29:37 +01:00
6aaf838451 Now using pw strength component
ref #106
2021-03-26 19:29:25 +01:00
ad3bd312e9 Added a password strength verification
ref #106
2021-03-26 19:26:26 +01:00
5fa9939696 Added more cirteria to the password strength component
ref #106
2021-03-26 19:02:09 +01:00
4956bb0e9c Implemented a custom password strength component
ref #106
2021-03-26 18:47:24 +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
39 changed files with 2233 additions and 1739 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,8 +2,47 @@
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.11.0](https://git.odit.services/lfk/frontend/compare/0.10.0...0.11.0)
- 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 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)
- 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)
- 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)
> 26 March 2021
- Added translations [`79c447b`](https://git.odit.services/lfk/frontend/commit/79c447b4c65e55ebb5af71fb0b09174c36e2cecf)
- 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)
- 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)
- 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)
- Implemented a custom password strength component [`4956bb0`](https://git.odit.services/lfk/frontend/commit/4956bb0e9c3c1d22d60e849aea5664e35330f897)
- User creation can now only be triggered if pw is strong enoug [`540304f`](https://git.odit.services/lfk/frontend/commit/540304f947f60a7072c592ca8088996ce7e95cb4)
- Now using pw strength component for user creation [`7862f44`](https://git.odit.services/lfk/frontend/commit/7862f446532903f1a2eac7b21d5c80c3245785e5)
- Added missing exports [`962dd0c`](https://git.odit.services/lfk/frontend/commit/962dd0c1bbc0df7f20bcec5b4247188c8935c87e)
- new license file version [CI SKIP] [`aedb8a7`](https://git.odit.services/lfk/frontend/commit/aedb8a765ba053545adbba9eb014b3bb0e5aac8c)
- Bumped lfk-client version 🔝 [`cf58bd1`](https://git.odit.services/lfk/frontend/commit/cf58bd15c3541c417ab2be83d96135e931a2b6f6)
- new license file version [CI SKIP] [`34f4f68`](https://git.odit.services/lfk/frontend/commit/34f4f68524918fd3d1963966a1e259d5b60efaca)
- Merge pull request 'Implemented password strength test feature/106-password_strength' (#115) from feature/106-password_strength into dev [`09b8144`](https://git.odit.services/lfk/frontend/commit/09b81440804cf98303fcb723a9717d6d0f432da8)
- Formatting🛠 [`4167819`](https://git.odit.services/lfk/frontend/commit/4167819e7a864d3b1dd95ba48ab1525a454f7f30)
- Now using pw strength component for reset [`5d5f7c7`](https://git.odit.services/lfk/frontend/commit/5d5f7c7f5c6a69146f41996f4facfeff95791be0)
#### [0.9.1](https://git.odit.services/lfk/frontend/compare/0.9.0...0.9.1) #### [0.9.1](https://git.odit.services/lfk/frontend/compare/0.9.0...0.9.1)
> 26 March 2021
- 🚀RELEASE v0.9.1 [`2ca63fd`](https://git.odit.services/lfk/frontend/commit/2ca63fd1f675f0da2b18ba43095074dd4823991d)
- Merge pull request 'Org selfservice Link feature/112-org_registration_links' (#114) from feature/112-org_registration_links into dev [`a5d25e7`](https://git.odit.services/lfk/frontend/commit/a5d25e7d92c7c37e90dbb4ba74b787873f920c6b) - Merge pull request 'Org selfservice Link feature/112-org_registration_links' (#114) from feature/112-org_registration_links into dev [`a5d25e7`](https://git.odit.services/lfk/frontend/commit/a5d25e7d92c7c37e90dbb4ba74b787873f920c6b)
- Added checkbox to enable registration [`f9fe793`](https://git.odit.services/lfk/frontend/commit/f9fe79357317653b46c09eb95b0db13845cddcf9) - Added checkbox to enable registration [`f9fe793`](https://git.odit.services/lfk/frontend/commit/f9fe79357317653b46c09eb95b0db13845cddcf9)
- Sorted translations [`c074c12`](https://git.odit.services/lfk/frontend/commit/c074c12be75f285612f7a732c106404d9fb4538a) - Sorted translations [`c074c12`](https://git.odit.services/lfk/frontend/commit/c074c12be75f285612f7a732c106404d9fb4538a)

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.9.1-RELEASE_INFO</span> <span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.8.4-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,45 +1,40 @@
{ {
"name": "@odit/lfk-frontend", "name": "@odit/lfk-frontend",
"version": "0.9.1", "version": "0.8.4",
"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.7.0",
"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.5",
"@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.0.4",
"tinro": "0.6.1",
"toastify-js": "1.10.0",
"validator": "13.5.2",
"vite": "2.1.5",
"vite-plugin-windicss": "0.12.2",
"xlsx": "0.16.9"
}, },
"release-it": { "release-it": {
"git": { "git": {
@@ -55,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,5 +1,4 @@
<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";
@@ -53,7 +52,6 @@
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 { register as registerSW } from "./swmodule";
import TeamDetail from "./components/teams/TeamDetail.svelte"; import TeamDetail from "./components/teams/TeamDetail.svelte";
import UserPermissions from "./components/users/UserPermissions.svelte"; import UserPermissions from "./components/users/UserPermissions.svelte";
import GroupPermissions from "./components/groups/GroupPermissions.svelte"; import GroupPermissions from "./components/groups/GroupPermissions.svelte";
@@ -75,7 +73,6 @@
import ScanDetail from "./components/scans/ScanDetail.svelte"; import ScanDetail from "./components/scans/ScanDetail.svelte";
import Cards from "./components/cards/Cards.svelte"; import Cards from "./components/cards/Cards.svelte";
store.init(); store.init();
registerSW();
</script> </script>
<Route> <Route>

View File

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

View File

@@ -0,0 +1,52 @@
<script context="module">
import { passwordStrength } from "check-password-strength";
export function password_strong_enough(password_change) {
let strength = passwordStrength(password_change);
return (
strength?.contains.includes("lowercase") &&
strength?.contains.includes("uppercase") &&
strength?.contains.includes("number") &&
strength?.length > 9
);
}
export function password_strong_enough_and_equal(
password_change,
password_confirm
) {
return (
password_strong_enough(password_change) &&
password_change === password_confirm
);
}
</script>
<script>
import { getLocaleFromNavigator, _ } from "svelte-i18n";
import { passwordStrength as Strength } from "check-password-strength";
export let password_change;
export let password_confirm;
$: strength = Strength(password_change);
$: passwords_match =
!password_confirm || password_confirm === password_change;
</script>
<div class="ml-4">
<ul class="list-disc font-medium tracking-wide text-red-500 text-xs">
{#if !strength.contains.includes('lowercase')}
<li>{$_('must-contain-a-lowercase-letter')}</li>
{/if}
{#if !strength.contains.includes('uppercase')}
<li>{$_('must-contain-a-uppercase-letter')}</li>
{/if}
{#if !strength.contains.includes('number')}
<li>{$_('must-contain-a-number')}</li>
{/if}
{#if !(strength.length > 9)}
<li>{$_('must-be-at-least-10-characters-long')}</li>
{/if}
{#if !(passwords_match == true)}
<li>{$_('passwords-dont-match')}</li>
{/if}
</ul>
</div>

View File

@@ -1,38 +1,43 @@
<script> <script>
import { AuthService } from "@odit/lfk-client-js"; import { AuthService } from "@odit/lfk-client-js";
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import "toastify-js/src/toastify.css"; import "toastify-js/src/toastify.css";
import PasswordStrength, {
password_strong_enough,
} from "../auth/PasswordStrength.svelte";
let state = "reset_in_progress"; let state = "reset_in_progress";
let password = ""; let password = "";
export let params; export let params;
function set_new_password() { function set_new_password() {
if(password.trim() !== ""){ if (password.trim() !== "") {
Toastify({ Toastify({
text: $_('password-reset-in-progress'), text: $_("password-reset-in-progress"),
duration: 3500, duration: 3500,
}).showToast(); }).showToast();
AuthService.authControllerResetPassword(atob(params.resetkey),{ password }) AuthService.authControllerResetPassword(atob(params.resetkey), {
password,
})
.then((resp) => { .then((resp) => {
Toastify({ Toastify({
text: $_('password-reset-successful'), text: $_("password-reset-successful"),
duration: 3500, duration: 3500,
}).showToast(); }).showToast();
state="reset_success"; state = "reset_success";
}) })
.catch((err) => { .catch((err) => {
state="reset_error"; state = "reset_error";
}); });
} else { } else {
Toastify({ Toastify({
text: $_('please-provide-a-password'), text: $_("please-provide-a-password"),
duration: 3500, duration: 3500,
}).showToast(); }).showToast();
} }
} }
</script> </script>
{#if state==="reset_success"} {#if state === 'reset_success'}
<div class="min-h-screen flex items-center justify-center bg-gray-100"> <div class="min-h-screen flex items-center justify-center bg-gray-100">
<div class="max-w-md w-full py-12 px-6"> <div class="max-w-md w-full py-12 px-6">
<img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" /> <img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" />
@@ -56,31 +61,31 @@
</div> </div>
</div> </div>
</div> </div>
{:else if state==="reset_error"} {:else if state === 'reset_error'}
<div class="min-h-screen flex items-center justify-center bg-gray-100"> <div class="min-h-screen flex items-center justify-center bg-gray-100">
<div class="max-w-md w-full py-12 px-6"> <div class="max-w-md w-full py-12 px-6">
<img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" /> <img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" />
<p class="mt-6 text-lg text-center font-bold text-gray-900"> <p class="mt-6 text-lg text-center font-bold text-gray-900">
{$_('application_name')} {$_('application_name')}
</p> </p>
<p class="mt-2 mb-2 text-sm text-center text-gray-900 font-bold"> <p class="mt-2 mb-2 text-sm text-center text-gray-900 font-bold">
{$_('password-reset-failed')} {$_('password-reset-failed')}
</p> </p>
<p class="mt-2 mb-2 text-sm text-center text-gray-900"> <p class="mt-2 mb-2 text-sm text-center text-gray-900">
{$_('please-request-a-new-reset-mail')} {$_('please-request-a-new-reset-mail')}
</p> </p>
<div class="mt-6">
<div class="mt-6"> <div class="mt-6">
<a <div class="mt-6">
href="/forgot_password/" <a
class="text-center relative block w-full py-2 px-3 border border-transparent rounded-md text-white font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm"> href="/forgot_password/"
{$_('request-a-new-reset-mail')} class="text-center relative block w-full py-2 px-3 border border-transparent rounded-md text-white font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm">
</a> {$_('request-a-new-reset-mail')}
</a>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> {:else if state === 'reset_in_progress'}
{:else if state==="reset_in_progress"}
<div class="min-h-screen flex items-center justify-center bg-gray-100"> <div class="min-h-screen flex items-center justify-center bg-gray-100">
<div class="max-w-md w-full py-12 px-6"> <div class="max-w-md w-full py-12 px-6">
<img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" /> <img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" />
@@ -102,11 +107,14 @@
placeholder={$_('new-password')} placeholder={$_('new-password')}
bind:value={password} /> bind:value={password} />
</div> </div>
<PasswordStrength bind:password_change={password} />
</div> </div>
<div class="mt-5"> <div class="mt-5">
<button <button
on:click={set_new_password} on:click={set_new_password}
disabled={!password_strong_enough(password)}
class:opacity-50={!password_strong_enough(password)}
type="submit" type="submit"
class="relative block w-full py-2 px-3 border border-transparent rounded-md text-white font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm"> class="relative block w-full py-2 px-3 border border-transparent rounded-md text-white font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm">
<span class="absolute left-0 inset-y pl-3"> <span class="absolute left-0 inset-y pl-3">

View File

@@ -22,19 +22,19 @@
if (e.keyCode === 13) { if (e.keyCode === 13) {
if (createbtnenabled === true) { if (createbtnenabled === true) {
createbtnenabled = false; createbtnenabled = false;
submit(); submit_with_print();
} }
} }
}; };
})(); })();
function submit() { function submit_without_print() {
if (processed_last_submit === true) { if (processed_last_submit === true) {
processed_last_submit = false; processed_last_submit = false;
const toast = Toastify({ const toast = Toastify({
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;
// //
@@ -54,6 +54,80 @@
}); });
} }
} }
function submit_with_print() {
if (processed_last_submit === true) {
processed_last_submit = false;
const toast = Toastify({
text: $_("creating-blanco-cards"),
duration: -1,
}).showToast();
RunnerCardService.runnerCardControllerPostBlancoBulk(card_count, true)
.then((result) => {
bulk_modal_open = false;
//
Toastify({
text: $_("created-blanco-cards"),
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
current_cards = current_cards.concat(result);
const toast = Toastify({
text: $_("generating-pdf"),
duration: -1,
}).showToast();
fetch(
`${config.baseurl}/documents/cards?&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(result),
}
)
.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;
a.download = "Bulkcards.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) => {
console.error(err);
});
})
.catch((err) => {
//
})
.finally(() => {
processed_last_submit = true;
//
toast.hideToast();
});
}
}
</script> </script>
{#if bulk_modal_open} {#if bulk_modal_open}
@@ -75,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"
@@ -138,17 +212,25 @@
<button <button
disabled={!createbtnenabled} disabled={!createbtnenabled}
class:opacity-50={!createbtnenabled} class:opacity-50={!createbtnenabled}
on:click={submit} 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')} {$_('create-and-generate-pdf')}
</button>
<button
disabled={!createbtnenabled}
class:opacity-50={!createbtnenabled}
on:click={submit_without_print}
type="button"
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')}
</button> </button>
<button <button
on:click={() => { on:click={() => {
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

@@ -149,7 +149,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
); );
@@ -216,7 +216,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
); );

View File

@@ -0,0 +1,273 @@
<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;
a.download = "Certificates.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);
}
console.log(certificateRunners)
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 + ".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 + ".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

@@ -1,6 +1,9 @@
<script> <script>
import { getLocaleFromNavigator, _ } from "svelte-i18n"; import { getLocaleFromNavigator, _ } from "svelte-i18n";
import { RunnerOrganizationService, RunnerTeamService } from "@odit/lfk-client-js"; import {
RunnerOrganizationService,
RunnerTeamService,
} from "@odit/lfk-client-js";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
export let sponsoring_contracts_show = false; export let sponsoring_contracts_show = false;
export let generate_runners = []; export let generate_runners = [];
@@ -34,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
@@ -89,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
); );

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">

View File

@@ -4,6 +4,9 @@
import { MeService } from "@odit/lfk-client-js"; import { MeService } from "@odit/lfk-client-js";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import ConfirmProfileDeletion from "./ConfirmProfileDeletion.svelte"; import ConfirmProfileDeletion from "./ConfirmProfileDeletion.svelte";
import PasswordStrength, {
password_strong_enough_and_equal,
} from "../auth/PasswordStrength.svelte";
$: data_loaded = false; $: data_loaded = false;
$: delete_triggered = false; $: delete_triggered = false;
$: original_data = {}; $: original_data = {};
@@ -15,8 +18,10 @@
JSON.stringify(editable) === JSON.stringify(original_data) JSON.stringify(editable) === JSON.stringify(original_data)
); );
$: save_enabled = changes_performed && isEmail(editable.email); $: save_enabled = changes_performed && isEmail(editable.email);
$: update_password_enabled = $: update_password_enabled = password_strong_enough_and_equal(
password_change.length > 0 && password_change === password_confirm; password_change,
password_confirm
);
const user_promise = MeService.meControllerGet().then((data) => { const user_promise = MeService.meControllerGet().then((data) => {
data_loaded = true; data_loaded = true;
data.groups = data.groups.map((g) => g.id); data.groups = data.groups.map((g) => g.id);
@@ -45,7 +50,7 @@
function changePassword() { function changePassword() {
if (data_loaded === true && update_password_enabled) { if (data_loaded === true && update_password_enabled) {
Toastify({ Toastify({
text: $_('changing-your-password'), text: $_("changing-your-password"),
duration: 2500, duration: 2500,
}).showToast(); }).showToast();
let postdata = Object.assign({}, original_data); let postdata = Object.assign({}, original_data);
@@ -56,7 +61,7 @@
password_change = ""; password_change = "";
postdata = {}; postdata = {};
Toastify({ Toastify({
text: $_('password-changed'), text: $_("password-changed"),
duration: 2500, duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
@@ -242,10 +247,7 @@
class="border-gray-300 placeholder-gray-500 appearance-none rounded-md relative block w-full px-3 py-2 border focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm" class="border-gray-300 placeholder-gray-500 appearance-none rounded-md relative block w-full px-3 py-2 border focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
placeholder={$_('password')} /> placeholder={$_('password')} />
</div> </div>
{#if password_change != password_confirm && password_change.length > 0} <PasswordStrength bind:password_change bind:password_confirm />
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">{$_('passwords-dont-match')}</span>
{/if}
</div> </div>
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6"> <div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<button <button
@@ -257,9 +259,9 @@
{$_('update-password')} {$_('update-password')}
</button> </button>
{#if update_password_enabled} {#if update_password_enabled}
<p> <p>
{$_('after-the-update-youll-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')}
</p> </p>
{/if} {/if}
</div> </div>
</div> </div>

View File

@@ -5,6 +5,9 @@
import { UserService } from "@odit/lfk-client-js"; import { UserService } from "@odit/lfk-client-js";
import isEmail from "validator/es/lib/isEmail"; import isEmail from "validator/es/lib/isEmail";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import PasswordStrength, {
password_strong_enough,
} from "../auth/PasswordStrength.svelte";
export let modal_open; export let modal_open;
export let current_users; export let current_users;
let firstname_input; let firstname_input;
@@ -28,7 +31,10 @@
$: isLastnameValid = lastname_input_value.trim().length !== 0; $: isLastnameValid = lastname_input_value.trim().length !== 0;
$: isFirstnameValid = firstname_input_value.trim().length !== 0; $: isFirstnameValid = firstname_input_value.trim().length !== 0;
$: createbtnenabled = $: createbtnenabled =
isFirstnameValid && isLastnameValid && isPasswordValid && isEmailValid; isFirstnameValid &&
isLastnameValid &&
password_strong_enough(password_input_value) &&
isEmailValid;
(function () { (function () {
document.onkeydown = function (e) { document.onkeydown = function (e) {
e = e || window.event; e = e || window.event;
@@ -203,12 +209,8 @@
type="password" type="password"
name="password" name="password"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
{#if !isPasswordValid} <PasswordStrength
<span bind:password_change={password_input_value} />
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('password-is-required')}
</span>
{/if}
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label <label

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

View File

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

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
};