Compare commits

...

149 Commits

Author SHA1 Message Date
9add6c8ff1 🚀RELEASE v0.15.2
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-16 18:10:50 +02:00
7a63d4eed1 Merge branch 'dev' of https://git.odit.services/lfk/frontend into dev
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-16 18:09:37 +02:00
e54a4807f7 NGINX cache assets 2021-04-16 18:09:30 +02:00
cee04c1d6f Footer - noopener link 2021-04-16 18:09:22 +02:00
cbec78589d Hotfix: Team change recognition 🐞
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-16 18:06:53 +02:00
a85db7cb3f 🚀RELEASE v0.15.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-16 17:53:38 +02:00
2bd3779839 Merge pull request '🐞🐳 fix Dockerfile' (#138) from bugfix/136-opacity_reactivity into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #138
2021-04-16 15:51:37 +00:00
303e33cafb 🐞🐳 fix Dockerfile
ref #136
2021-04-16 17:46:15 +02:00
b4e689dddf Dockerfile now uses selfhosted registry
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-15 19:50:37 +02:00
98a0b036c5 new license file version [CI SKIP] 2021-04-15 17:46:04 +00:00
fb3f30fb10 Merge pull request 'Opacity import fix bugfix/136-opacity_reactivity' (#137) from bugfix/136-opacity_reactivity into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #137
2021-04-15 17:44:49 +00:00
6213952007 Added bs import fix
ref #136
2021-04-15 19:43:43 +02:00
07ac041d69 🚚 move to tailwind
ref #136
2021-04-15 19:22:57 +02:00
5c02028841 🚀RELEASE v0.15.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-15 18:30:38 +02:00
c561b53670 Merge pull request 'Mark donations as payed feature/133-donation_payments' (#135) from feature/133-donation_payments into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #135
2021-04-15 16:29:39 +00:00
dcd0d5a362 Merge branch 'feature/133-donation_payments' of https://git.odit.services/lfk/frontend into feature/133-donation_payments 2021-04-15 18:27:47 +02:00
18acac83bc AddDonationModal - vertical alignment for paid status
ref #133
2021-04-15 18:27:35 +02:00
d7d44470bb DonationsOverview contrast on action
ref #133
2021-04-15 18:25:52 +02:00
0f0aae7ba4 Fixed chante recognition bug for fixed donation
ref #133
2021-04-15 18:21:23 +02:00
4c0886a5d9 Fixed typo
ref #133
2021-04-15 18:04:03 +02:00
04a3038369 Added missing updated comparison
ref #133
2021-04-15 16:56:03 +02:00
bdcf5d3fc0 Added payment updating via detail
ref #133
2021-04-15 15:54:14 +02:00
c7a858eed7 Sorted translations
ref #133
2021-04-15 15:42:47 +02:00
de5aa9237d Added **all** missing toast translations
ref #133
2021-04-15 15:42:29 +02:00
d015f97395 Added translations 🌎
ref #113
2021-04-15 15:34:36 +02:00
57618156b4 Added msiisng runner id conversion
ref #133
2021-04-15 15:30:23 +02:00
865254d646 Fixed styling
ref #133
2021-04-15 15:25:17 +02:00
1dbab03fe7 You can now add payments from the donation overview
ref #133
2021-04-15 15:24:31 +02:00
a943aaf5fc You can now open a modal to add a payment to a donation from the donation overview
ref #133
2021-04-15 15:05:05 +02:00
6e6e8b2617 Added Add Payment button to donor overview
ref #133
2021-04-15 14:40:46 +02:00
4c2c24af2c Changed top info style for donation overview
ref #133
2021-04-15 14:33:35 +02:00
3d3a10aafb You can now mark fixed donations as already paid on creation
ref #133
2021-04-15 14:31:24 +02:00
000fc97beb Changed top info style for donation detail
ref #133
2021-04-15 14:18:28 +02:00
5645eeaafa Added paid donation amount and status to donation detail
ref #133
2021-04-15 14:17:28 +02:00
961477d522 Added total donation amount to donation overview
ref #133
2021-04-15 14:12:11 +02:00
a5f71015a6 Added total donation amount to donor detail
ref #133
2021-04-15 14:10:35 +02:00
e42ea943b7 Added total donation amount to donor overview
ref #133
2021-04-15 14:09:23 +02:00
9c5fc6b61c 🚀RELEASE v0.14.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-14 19:28:00 +02:00
302caf015f new license file version [CI SKIP] 2021-04-14 17:27:30 +00:00
e11296071a Merge pull request 'added donor receipt list download to DonorsOverview' (#134) from feature/132-export-donors-receipt-list into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #134
close #132
2021-04-14 17:26:10 +00:00
112eb29f93 Switched to selfhosted images
ref #132
2021-04-14 19:24:06 +02:00
c6c97516b3 Sorted translations 🌎
ref #132
2021-04-14 19:23:26 +02:00
03676b2894 Fixed typos in translations
ref #132
2021-04-14 19:23:07 +02:00
9ca57fac2e bump @odit/lfk-client-js@0.11.0
ref #132
2021-04-14 18:58:57 +02:00
18f151c1fb general version bump
ref #132
2021-04-14 18:57:14 +02:00
e90e56d8b2 replace donationAmount with paidDonationAmount
ref #132
2021-04-14 18:54:05 +02:00
d241ca5698 added donor receipt list download to DonorsOverview
ref #132
2021-04-14 18:43:51 +02:00
b512cf8667 🚀RELEASE v0.13.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-11 21:14:03 +02:00
a24d2923c6 For await fix
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-11 21:13:44 +02:00
467808abef 🚀RELEASE v0.13.0
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-11 21:08:58 +02:00
861f1f2216 Merge pull request 'Better org pdf generation feature/130-org_doc_splitting' (#131) from feature/130-org_doc_splitting into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #131
2021-04-11 19:07:53 +00:00
509b22bea0 Org certificate generation now runs in sequence
ref #130
2021-04-11 21:00:33 +02:00
7447b2f4c1 Fixed const -> let
ref #130
2021-04-11 20:54:38 +02:00
fef14b6e4f Org card generation now runs in sequence
ref #130
2021-04-11 20:53:58 +02:00
01d2a7e6aa Org contract generation now runs in sequence
ref #130
2021-04-11 20:48:20 +02:00
ac586fec5a Hotfix: Org * generation🐞
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-11 20:17:34 +02:00
5476808683 Emergency document server url change
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-11 20:10:08 +02:00
331d737796 🚀RELEASE v0.12.5
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-08 19:30:20 +02:00
ef81b8adf9 Merge pull request 'Added runner team's parentorg name to runenr overciew' (#129) from feature/128-runner_orgs into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #129
2021-04-08 17:29:27 +00:00
8a7d635cef Switched to html entity
ref #128
2021-04-08 18:00:47 +02:00
4c259c1eef Added runner team's parentorg name to runenr overciew
ref #128
2021-04-08 17:58:49 +02:00
5b4ede5e2f 🚀RELEASE v0.12.4
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-08 17:34:32 +02:00
d0ab3dda78 🚑 [HOTFIX] - drop "svelte-infinite-loading"
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-08 17:34:04 +02:00
d9cf51b4bb 🚀RELEASE v0.12.3
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-08 17:30:23 +02:00
aa17f24220 new license file version [CI SKIP] 2021-04-08 15:28:50 +00:00
cf60edf7d4 Merge pull request 'fix' (#126) from bugfix/125-mobile into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #126
close #125
2021-04-08 15:27:22 +00:00
ffbc243194 custom css fix for collapsed_navigation
ref #125
2021-04-07 21:44:29 +02:00
b6b07cf30c 🐞 bugfix for svelte x tailwind class names
ref #125
2021-04-07 21:35:01 +02:00
495a6b22bd almost fixed... 2021-04-07 21:28:21 +02:00
0acaffbdfa fix
ref #125
2021-04-07 20:25:04 +02:00
6043bc4517 🚀RELEASE v0.12.2
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-07 20:11:21 +02:00
e6ed066e3f Merge pull request 'feature/110-virtual_list' (#124) from feature/110-virtual_list into dev
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #124
2021-04-07 18:10:02 +00:00
ee4e8655b8 Merge branch 'dev' into feature/110-virtual_list 2021-04-07 20:09:35 +02:00
37970d2be6 pre-merge fixes
ref #110
2021-04-07 18:59:46 +02:00
1376788016 updated virtual scroll list 2021-04-07 18:38:52 +02:00
4cad86cf85 fixed height table 2021-04-07 18:19:58 +02:00
6304116edb wip on virtuallist 2021-04-06 22:16:24 +02:00
834ff8fa63 🚀RELEASE v0.12.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-06 16:47:37 +02:00
1f428a535e Merge pull request 'ImportRunnerModal Cancel Button feature/122-import_cancel' (#123) from feature/112-import_cancel into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #123
2021-04-06 14:42:37 +00:00
0c40966970 Added cancel button for the first stage of runner import
ref #112
2021-04-05 16:23:24 +02:00
9da071fe9b Escape now triggers foll modal close (including reset) instead of just hiding th modal
ref #112
2021-04-05 16:14:43 +02:00
892a04f289 🚀RELEASE v0.12.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-05 16:09:17 +02:00
27cc9727f1 Fixed package version
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-05 16:08:41 +02:00
f0738d451b Merge pull request 'Implmented certificate generation feature/119-Certificate_generation' (#120) from feature/119-Certificate_generation into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #120
2021-04-05 14:05:38 +00:00
9e6a8daf2c Sorted translations 🌍
ref #119
2021-04-05 16:04:44 +02:00
bfacfec765 The PFS Prefixes now get translated via i18n
ref #119
2021-04-05 16:04:26 +02:00
0bae5bf32b sponsoring pdf names now include their locale
ref #119
2021-04-05 15:37:12 +02:00
22b09d16d0 Cleaned up generation strings and added the schem for single runner generations for sponsoring contracts
ref #119
2021-04-05 15:36:01 +02:00
9c867e106e Cleaned up generation strings and added the schem for single runner generations for cards
ref #119
2021-04-05 15:33:55 +02:00
304f28a3c1 certificate pdf names now include their locale
ref #119
2021-04-05 15:31:52 +02:00
d65d3793de Changed the basic nameing generation for runenr certificate files
ref #119
2021-04-05 15:31:01 +02:00
3638d87bd2 Runnercard pdfs now include their locale
ref #119
2021-04-05 15:28:13 +02:00
b97a92860d Fixed wrong permissiong getting checked
ref #119
2021-04-05 15:24:42 +02:00
7c86a5eeb3 added missing/ wrong translations + formatting!
ref #119
2021-04-05 12:02:18 +02:00
d23dbaaf69 Removed useless console.log
ref #119
2021-04-03 20:05:27 +02:00
e6ffc371e1 Certificate generation from org detail
ref #119
2021-04-03 20:03:57 +02:00
3177c6eaa3 Certificate generation from org overview
ref #119
2021-04-03 20:02:52 +02:00
acd2f0519d Certificate generation from team detail
ref #119
2021-04-03 20:00:51 +02:00
18ec100c33 Certificate generation from team overview
ref #119
2021-04-03 19:59:34 +02:00
fa55fce76e Merge branch 'feature/119-Certificate_generation' of git.odit.services:lfk/frontend into feature/119-Certificate_generation 2021-04-03 19:59:20 +02:00
f47d5e347d Copy-paste fix
ref #119
2021-04-03 19:59:18 +02:00
7488a8b597 Copy-paste fix
ref #119
2021-04-03 19:58:24 +02:00
2e3ac154be Implemented generation for orgs
ref #119
2021-04-03 19:52:41 +02:00
2472640755 Implemented generation for teams
ref #119
2021-04-03 19:51:01 +02:00
7b685d6cad Added certificate generation from runner overview and detail
ref #119
2021-04-03 19:48:31 +02:00
17f6f4e616 Added i18n
ref #119
2021-04-03 19:46:17 +02:00
48cfc15cfb Removed useless console log
ref #119
2021-04-03 19:44:57 +02:00
bb9b779cee You can now generate certificates from the runner overview
ref #119
2021-04-03 19:44:26 +02:00
af63ce67ae Added basic certificate generation component
ref #119
2021-04-03 19:38:54 +02:00
5cc4871ec4 new license file version [CI SKIP] 2021-04-03 17:18:28 +00:00
c8cfe669b8 Merge pull request 'feature/108_vite_migration' (#118) from feature/108_vite_migration into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #118
close #108
2021-04-03 17:17:23 +00:00
8b74d6d759 bump @odit/lfk-client-js@0.10.1
ref #108
2021-04-03 19:16:53 +02:00
a9227768de 🐞 fix await for esNext
ref #108
2021-04-03 19:13:05 +02:00
d966e1d4de Merge branch 'dev' into feature/108_vite_migration
# Conflicts:
#	index.html
#	package.json
#	public/licenses.json
#	src/App.svelte
#	src/components/orgs/OrgOverview.svelte
#	src/components/teams/TeamsOverview.svelte
2021-04-03 19:10:10 +02:00
ceb2146c1b 🔨 dev container open
ref #108
2021-04-03 18:31:03 +02:00
8d006d8c74 version bump: vite-plugin-windicss@0.12.2
ref #108
2021-04-03 18:22:00 +02:00
777304f259 🔨🔥 alpine based devcontainer with working yarn PnP
ref #108
2021-04-02 21:57:56 +02:00
12433f7c23 🧹 reorder + fix package
ref #108
2021-04-02 21:56:57 +02:00
44b53da345 🚚 move @svitejs/vite-plugin-svelte to @sveltejs/vite-plugin-svelte
ref #108
2021-04-02 21:47:43 +02:00
ab45fc144e upgrade vite-plugin-windicss@0.12.1
ref #108
2021-04-02 21:20:48 +02:00
e99e9e0708 update licenses.json
ref #108
2021-04-02 21:20:05 +02:00
467404bfc8 🐞 fix main.js linking
ref #108
2021-04-02 21:19:49 +02:00
ce50fa2a62 🧹 drop unused dependencies
ref #108
2021-04-02 21:19:29 +02:00
10a011d842 🐞 fix vite config for production system
ref #108
2021-04-02 21:07:16 +02:00
5352410d0c 🐞 fix NGINX config
ref #108
2021-04-02 21:06:57 +02:00
c5d155396a 💾 prevent env.js from being cached
ref #108
2021-04-01 19:35:27 +02:00
93187099d3 🔨 re-added VS Code devcontainer config
ref #108
2021-04-01 19:35:10 +02:00
aa24b1dce5 📃 added readme
ref #108
2021-04-01 19:32:10 +02:00
eb3ede9593 fix dev script
ref #108
2021-04-01 19:30:31 +02:00
d7fecfbd0b version bumps
ref #108
2021-04-01 19:30:15 +02:00
b065b4ff21 📍 version bump + pin
ref #108
2021-03-30 18:36:20 +02:00
87370d24be Merge branch 'dev' of git.odit.services:lfk/frontend into dev
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-30 18:29:03 +02:00
8f8b9988ad new license file version [CI SKIP] 2021-03-30 16:29:19 +00:00
f8ccf4f5d8 🚀RELEASE v0.11.0 2021-03-30 18:28:53 +02:00
25d8b86efd Merge pull request 'Generate and print bulk blank cards feature/116-download_blanc_cards' (#117) from feature/116-download_blanc_cards into dev
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #117
2021-03-30 16:27:48 +00:00
0cd3e937d8 bump vite to 2.1.3
ref #108
2021-03-30 18:21:18 +02:00
89bb9c215e Sorted translations
ref #116
2021-03-29 18:52:25 +02:00
2d18686ce7 Bumped lfk client js version
ref #116
2021-03-29 18:52:10 +02:00
1d999d4910 Now returning cards on creation with pdf
ref #116
2021-03-29 18:23:17 +02:00
7dfaa7579a Bumped lfk-client-js
ref #116
2021-03-29 18:15:00 +02:00
08cb079e97 Fixed button styling
ref #116
2021-03-29 17:57:34 +02:00
450aa83592 Merge branch 'feature/116-download_blanc_cards' of git.odit.services:lfk/frontend into feature/116-download_blanc_cards
# Conflicts:
#	src/components/cards/AddCardBulkModal.svelte
2021-03-29 17:47:18 +02:00
0614c76e92 Added button (including translations
ref #116
2021-03-29 17:46:56 +02:00
6be2ee626a package cleanup 2021-03-26 21:22:46 +01:00
008027db0e added windicss settings for VSCode
ref #108
2021-03-25 18:57:33 +01:00
aec5e3473e for await fix - ViteJS
ref #108
2021-03-25 18:56:18 +01:00
95c8fde72f updated default entrypoint
ref #108
2021-03-25 18:56:02 +01:00
0f32968fae 🐳 new Dockerfiles
ref #108
2021-03-25 18:55:43 +01:00
ae79e9fea1 basic ViteJS migration
ref #108
2021-03-25 18:55:24 +01:00
62 changed files with 2721 additions and 1505 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

View File

@@ -27,7 +27,7 @@ name: build:dev
steps: steps:
- name: run full license export - name: run full license export
depends_on: ["clone"] depends_on: ["clone"]
image: node:alpine image: registry.odit.services/hub/library/node:alpine
commands: commands:
- yarn - yarn
- yarn licenses:export - yarn licenses:export

9
.gitignore vendored
View File

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

View File

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

View File

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

View File

@@ -2,12 +2,222 @@
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.15.2](https://git.odit.services/lfk/frontend/compare/0.15.1...0.15.2)
- Footer - noopener link [`cee04c1`](https://git.odit.services/lfk/frontend/commit/cee04c1d6fb6005cefe77fb95855ab6fe2cc448f)
- Hotfix: Team change recognition 🐞 [`cbec785`](https://git.odit.services/lfk/frontend/commit/cbec78589d2fa21f12ce87e71bff2b49c3a7d345)
- NGINX cache assets [`e54a480`](https://git.odit.services/lfk/frontend/commit/e54a4807f70bc333396885f81d3dcc7ae6c115d9)
#### [0.15.1](https://git.odit.services/lfk/frontend/compare/0.15.0...0.15.1)
> 16 April 2021
- 🚀RELEASE v0.15.1 [`a85db7c`](https://git.odit.services/lfk/frontend/commit/a85db7cb3f89881794e37a66ecd822f8ad5873f1)
- Merge pull request '🐞🐳 fix Dockerfile' (#138) from bugfix/136-opacity_reactivity into dev [`2bd3779`](https://git.odit.services/lfk/frontend/commit/2bd3779839de16a89b91a3da93033e2a2b742ab7)
- 🚚 move to tailwind [`07ac041`](https://git.odit.services/lfk/frontend/commit/07ac041d69b3b1810e5db538b53fe62084490f7a)
- 🐞🐳 fix Dockerfile [`303e33c`](https://git.odit.services/lfk/frontend/commit/303e33cafb4a1be01e4c4b43f46ff0c651cb4620)
- Dockerfile now uses selfhosted registry [`b4e689d`](https://git.odit.services/lfk/frontend/commit/b4e689dddf0b93a2794aa30ea83e8c6505d6bbfd)
- new license file version [CI SKIP] [`98a0b03`](https://git.odit.services/lfk/frontend/commit/98a0b036c5490b4bc4992e83f3bca02be39927fa)
- Merge pull request 'Opacity import fix bugfix/136-opacity_reactivity' (#137) from bugfix/136-opacity_reactivity into dev [`fb3f30f`](https://git.odit.services/lfk/frontend/commit/fb3f30fb1024de61ce1c541dae90374454f6ef96)
- Added bs import fix [`6213952`](https://git.odit.services/lfk/frontend/commit/621395200751c2d42b9ad44c77e84bda03b62e83)
#### [0.15.0](https://git.odit.services/lfk/frontend/compare/0.14.0...0.15.0)
> 15 April 2021
- 🚀RELEASE v0.15.0 [`5c02028`](https://git.odit.services/lfk/frontend/commit/5c02028841c68d9a284bf6971eec2b6bc2fdf1f3)
- Merge pull request 'Mark donations as payed feature/133-donation_payments' (#135) from feature/133-donation_payments into dev [`c561b53`](https://git.odit.services/lfk/frontend/commit/c561b536705a68215d9c0a6b320587d1647bf57f)
- Sorted translations [`c7a858e`](https://git.odit.services/lfk/frontend/commit/c7a858eed7962294bc9df3c92ce2e46b0a354796)
- Added total donation amount to donor overview [`e42ea94`](https://git.odit.services/lfk/frontend/commit/e42ea943b7821d433fe21599edbd9f76c3128ef2)
- Added Add Payment button to donor overview [`6e6e8b2`](https://git.odit.services/lfk/frontend/commit/6e6e8b26171f16542c101520800b4b6ea7c023d3)
- You can now open a modal to add a payment to a donation from the donation overview [`a943aaf`](https://git.odit.services/lfk/frontend/commit/a943aaf5fce8f113dd967d3842e2b0d7d50604e9)
- You can now add payments from the donation overview [`1dbab03`](https://git.odit.services/lfk/frontend/commit/1dbab03fe73b5e0fc011f9b0af7199bd71bc79c5)
- Added payment updating via detail [`bdcf5d3`](https://git.odit.services/lfk/frontend/commit/bdcf5d3fc08d250377226a253642d79b2e82d624)
- Added **all** missing toast translations [`de5aa92`](https://git.odit.services/lfk/frontend/commit/de5aa9237d261b5d47a8def35afa7f8e0089aea6)
- You can now mark fixed donations as already paid on creation [`3d3a10a`](https://git.odit.services/lfk/frontend/commit/3d3a10aafb16d371be9471eb5172f9251fb2583f)
- Added translations 🌎 [`d015f97`](https://git.odit.services/lfk/frontend/commit/d015f9739570c44a7a2fe6ba248c9a45c3047c62)
- Changed top info style for donation overview [`4c2c24a`](https://git.odit.services/lfk/frontend/commit/4c2c24af2ca5c2874a583b0fd93bee147a17f449)
- Added paid donation amount and status to donation detail [`5645eea`](https://git.odit.services/lfk/frontend/commit/5645eeaafaa4254edf1a81bc597ce0c7a9b03ff0)
- Added total donation amount to donation overview [`961477d`](https://git.odit.services/lfk/frontend/commit/961477d5224bc44b552d2fc2851d8514116f4e20)
- Fixed chante recognition bug for fixed donation [`0f0aae7`](https://git.odit.services/lfk/frontend/commit/0f0aae7ba4cf5dfab15d56ce48edbdbc7cb7e403)
- Added total donation amount to donor detail [`a5f7101`](https://git.odit.services/lfk/frontend/commit/a5f71015a6557d664e9d3f505613352792fc38cb)
- Added msiisng runner id conversion [`5761815`](https://git.odit.services/lfk/frontend/commit/57618156b49b2b0f0274f2126fef36a017d90022)
- AddDonationModal - vertical alignment for paid status [`18acac8`](https://git.odit.services/lfk/frontend/commit/18acac83bc6532e14d36b3399d867e026d0c88ac)
- Added missing updated comparison [`04a3038`](https://git.odit.services/lfk/frontend/commit/04a3038369f2717c43459318b7b5754ebbaa9e45)
- DonationsOverview contrast on action [`d7d4447`](https://git.odit.services/lfk/frontend/commit/d7d44470bb08ac06594bc400608c17eeacb0434b)
- Fixed typo [`4c0886a`](https://git.odit.services/lfk/frontend/commit/4c0886a5d9b91439967bc8f66b09a57177f967d0)
- Fixed styling [`865254d`](https://git.odit.services/lfk/frontend/commit/865254d646b5f7de15720551c67ae649601cbcd2)
- Changed top info style for donation detail [`000fc97`](https://git.odit.services/lfk/frontend/commit/000fc97beb14427f69d421ff2c96975dbbdc7a3a)
#### [0.14.0](https://git.odit.services/lfk/frontend/compare/0.13.1...0.14.0)
> 14 April 2021
- Merge pull request 'added donor receipt list download to DonorsOverview' (#134) from feature/132-export-donors-receipt-list into dev [`#132`](https://git.odit.services/lfk/frontend/issues/132)
- Sorted translations 🌎 [`c6c9751`](https://git.odit.services/lfk/frontend/commit/c6c97516b3981ef580d620c0c8a6fcc42f26facd)
- Fixed typos in translations [`03676b2`](https://git.odit.services/lfk/frontend/commit/03676b2894892c3559118b93e969c063b53b081e)
- added donor receipt list download to DonorsOverview [`d241ca5`](https://git.odit.services/lfk/frontend/commit/d241ca569838abbe9581fbd319f7f3b563cb7dcc)
- 🚀RELEASE v0.14.0 [`9c5fc6b`](https://git.odit.services/lfk/frontend/commit/9c5fc6b61c0bb2a6d831d4a23ef8679c6e68c6a1)
- ⏫ general version bump [`18f151c`](https://git.odit.services/lfk/frontend/commit/18f151c1fb878a74c3d1a2c2a2debf7913739417)
- new license file version [CI SKIP] [`302caf0`](https://git.odit.services/lfk/frontend/commit/302caf015f88f77e2b2ae2b67680e79f987ad81e)
- Switched to selfhosted images [`112eb29`](https://git.odit.services/lfk/frontend/commit/112eb29f932cd936f1d6c2308dcaeaf8cb642490)
- ⏫ bump @odit/lfk-client-js@0.11.0 [`9ca57fa`](https://git.odit.services/lfk/frontend/commit/9ca57fac2eeabbf25142a507fb9c0fa3c90b4e74)
- replace donationAmount with paidDonationAmount [`e90e56d`](https://git.odit.services/lfk/frontend/commit/e90e56d8b26aef23aba2bbb0c3942ba4d7feb224)
#### [0.13.1](https://git.odit.services/lfk/frontend/compare/0.13.0...0.13.1)
> 11 April 2021
- 🚀RELEASE v0.13.1 [`b512cf8`](https://git.odit.services/lfk/frontend/commit/b512cf86674f1c60b5ac790985ededdfd6554185)
- For await fix [`a24d292`](https://git.odit.services/lfk/frontend/commit/a24d2923c6e6da90d610c05183d29d47eaf2ed30)
#### [0.13.0](https://git.odit.services/lfk/frontend/compare/0.12.5...0.13.0)
> 11 April 2021
- 🚀RELEASE v0.13.0 [`467808a`](https://git.odit.services/lfk/frontend/commit/467808abefe127dac66a2837fcce3197dddb140f)
- Merge pull request 'Better org pdf generation feature/130-org_doc_splitting' (#131) from feature/130-org_doc_splitting into dev [`861f1f2`](https://git.odit.services/lfk/frontend/commit/861f1f221653283e7586aa2c67b205337fd44398)
- Org card generation now runs in sequence [`fef14b6`](https://git.odit.services/lfk/frontend/commit/fef14b6e4fb47ad92da61de91fedce96aea26b2c)
- Org certificate generation now runs in sequence [`509b22b`](https://git.odit.services/lfk/frontend/commit/509b22bea0dd3e4446e6ecc37d27644e9bf2ad50)
- Org contract generation now runs in sequence [`01d2a7e`](https://git.odit.services/lfk/frontend/commit/01d2a7e6aa709b3f2d71575f705fc962e97e2742)
- Emergency document server url change [`5476808`](https://git.odit.services/lfk/frontend/commit/5476808683a919bc34dbaea1f1ed276d49750096)
- Fixed const -> let [`7447b2f`](https://git.odit.services/lfk/frontend/commit/7447b2f4c134a585905db6733093eab13e6f7c47)
- Hotfix: Org * generation🐞 [`ac586fe`](https://git.odit.services/lfk/frontend/commit/ac586fec5abd324d590ba99cdfe8ddddefbf95e6)
#### [0.12.5](https://git.odit.services/lfk/frontend/compare/0.12.4...0.12.5)
> 8 April 2021
- 🚀RELEASE v0.12.5 [`331d737`](https://git.odit.services/lfk/frontend/commit/331d737796c82454b1c19fa1840ccc20e36d2626)
- Merge pull request 'Added runner team's parentorg name to runenr overciew' (#129) from feature/128-runner_orgs into dev [`ef81b8a`](https://git.odit.services/lfk/frontend/commit/ef81b8adf9bef685a55936d7544bf645c0d6ecbe)
- Switched to html entity [`8a7d635`](https://git.odit.services/lfk/frontend/commit/8a7d635cef2d465e70c84e1f7a7b90b98a8dbab1)
- Added runner team's parentorg name to runenr overciew [`4c259c1`](https://git.odit.services/lfk/frontend/commit/4c259c1eef2b0166ce6a8493d0c9e9d5ede11146)
#### [0.12.4](https://git.odit.services/lfk/frontend/compare/0.12.3...0.12.4)
> 8 April 2021
- 🚀RELEASE v0.12.4 [`5b4ede5`](https://git.odit.services/lfk/frontend/commit/5b4ede5e2f6a26b475a7a4b430a4146d21fb9671)
- 🚑 [HOTFIX] - drop "svelte-infinite-loading" [`d0ab3dd`](https://git.odit.services/lfk/frontend/commit/d0ab3dda78bbad2cea18a2491056530897d56607)
#### [0.12.3](https://git.odit.services/lfk/frontend/compare/0.12.2...0.12.3)
> 8 April 2021
- Merge pull request 'fix' (#126) from bugfix/125-mobile into dev [`#125`](https://git.odit.services/lfk/frontend/issues/125)
- almost fixed... [`495a6b2`](https://git.odit.services/lfk/frontend/commit/495a6b22bd8036593f390bdb862d325524cefbcc)
- 🐞 bugfix for svelte x tailwind class names [`b6b07cf`](https://git.odit.services/lfk/frontend/commit/b6b07cf30cc6533bd5dbfec1f813c16fde85634d)
- fix [`0acaffb`](https://git.odit.services/lfk/frontend/commit/0acaffbdfa359e52654a5afe2788aa59fe6f9036)
- 🚀RELEASE v0.12.3 [`d9cf51b`](https://git.odit.services/lfk/frontend/commit/d9cf51b4bbc2136594a03c5d0eeb8cb3f3440b2a)
- custom css fix for collapsed_navigation [`ffbc243`](https://git.odit.services/lfk/frontend/commit/ffbc243194c7faeb4fe61c12711a1c441c3994ef)
- new license file version [CI SKIP] [`aa17f24`](https://git.odit.services/lfk/frontend/commit/aa17f242209f7e7cecff774ace7a35b581adec1f)
#### [0.12.2](https://git.odit.services/lfk/frontend/compare/0.12.1...0.12.2)
> 7 April 2021
- 🚀RELEASE v0.12.2 [`6043bc4`](https://git.odit.services/lfk/frontend/commit/6043bc45174d51ab110b0ed10a8679d96127ab87)
- Merge pull request 'feature/110-virtual_list' (#124) from feature/110-virtual_list into dev [`e6ed066`](https://git.odit.services/lfk/frontend/commit/e6ed066e3ffabba6519f94d801d21a27819d0492)
- wip on virtuallist [`6304116`](https://git.odit.services/lfk/frontend/commit/6304116edb7f5e3c7b67c15e0b1740d34c513155)
- fixed height table [`4cad86c`](https://git.odit.services/lfk/frontend/commit/4cad86cf852468428d77103d052c6974b17c34c3)
- pre-merge fixes [`37970d2`](https://git.odit.services/lfk/frontend/commit/37970d2be6b6502701914e41e5bfe2c418438480)
- updated virtual scroll list [`1376788`](https://git.odit.services/lfk/frontend/commit/1376788016e767f006661f8c9e6747781f2dce55)
#### [0.12.1](https://git.odit.services/lfk/frontend/compare/0.12.0...0.12.1)
> 6 April 2021
- 🚀RELEASE v0.12.1 [`834ff8f`](https://git.odit.services/lfk/frontend/commit/834ff8fa63178f36dcacf931c128ba67a3e7bd1b)
- Merge pull request 'ImportRunnerModal Cancel Button feature/122-import_cancel' (#123) from feature/112-import_cancel into dev [`1f428a5`](https://git.odit.services/lfk/frontend/commit/1f428a535e3ae619cbf8db51d04255aac8dd8614)
- Added cancel button for the first stage of runner import [`0c40966`](https://git.odit.services/lfk/frontend/commit/0c409669700d3a8096cc04716154b0fdca458fe5)
- Escape now triggers foll modal close (including reset) instead of just hiding th modal [`9da071f`](https://git.odit.services/lfk/frontend/commit/9da071fe9ba067160334682bf00163e3630fe919)
#### [0.12.0](https://git.odit.services/lfk/frontend/compare/0.11.0...0.12.0)
> 5 April 2021
- Merge pull request 'feature/108_vite_migration' (#118) from feature/108_vite_migration into dev [`#108`](https://git.odit.services/lfk/frontend/issues/108)
- 🚀RELEASE v0.12.0 [`892a04f`](https://git.odit.services/lfk/frontend/commit/892a04f28930481715eb486b1ef4efeb98a6e999)
- Fixed package version [`27cc972`](https://git.odit.services/lfk/frontend/commit/27cc9727f1d02d186c3ccadb06e5b4b1b1d6202d)
- Merge pull request 'Implmented certificate generation feature/119-Certificate_generation' (#120) from feature/119-Certificate_generation into dev [`f0738d4`](https://git.odit.services/lfk/frontend/commit/f0738d451b02e4a298b5f9cb8ab0be16aed10a38)
- The PFS Prefixes now get translated via i18n [`bfacfec`](https://git.odit.services/lfk/frontend/commit/bfacfec76511cae3015f52698fdcbd80a7a15981)
- Sorted translations 🌍 [`9e6a8da`](https://git.odit.services/lfk/frontend/commit/9e6a8daf2c394cf17da532382ec7d049a0f89577)
- added missing/ wrong translations + formatting! [`7c86a5e`](https://git.odit.services/lfk/frontend/commit/7c86a5eeb370a43451d180a09a501066b023b9a0)
- Added i18n [`17f6f4e`](https://git.odit.services/lfk/frontend/commit/17f6f4e616bf57424ee12ad53b939429c02a0171)
- Added basic certificate generation component [`af63ce6`](https://git.odit.services/lfk/frontend/commit/af63ce67ae7d8f8a70706c3bd6755197908996ff)
- basic ViteJS migration [`ae79e9f`](https://git.odit.services/lfk/frontend/commit/ae79e9fea1963e977ef468e8e56f87d68916fadd)
- Implemented generation for orgs [`2e3ac15`](https://git.odit.services/lfk/frontend/commit/2e3ac154be0bf0776cd00f7d510f41ec676ae690)
- Implemented generation for teams [`2472640`](https://git.odit.services/lfk/frontend/commit/2472640755e3e41259a44127a875d00517a25842)
- updated default entrypoint [`95c8fde`](https://git.odit.services/lfk/frontend/commit/95c8fde72fca5cd5a644d51a33dc88e0b59fce92)
- ⏫📍 version bump + pin [`b065b4f`](https://git.odit.services/lfk/frontend/commit/b065b4ff218d07952fa45989e6e2ee7df13e07c1)
- 🧹 reorder + fix package [`12433f7`](https://git.odit.services/lfk/frontend/commit/12433f7c236906fe2b29848a0acaa6be1724da56)
- 🔨 re-added VS Code devcontainer config [`9318709`](https://git.odit.services/lfk/frontend/commit/93187099d32c506329b1437642aae985f2850689)
- 🐳 new Dockerfiles [`0f32968`](https://git.odit.services/lfk/frontend/commit/0f32968fae8b55a13d387918211983d0e61f85ab)
- 📃 added readme [`aa24b1d`](https://git.odit.services/lfk/frontend/commit/aa24b1dce5d6d73c8f42fc57f81b692350bf9665)
- Copy-paste fix [`f47d5e3`](https://git.odit.services/lfk/frontend/commit/f47d5e347d97ee127fa0380620138a9672665cd5)
- 🔨🔥 alpine based devcontainer with working yarn PnP [`777304f`](https://git.odit.services/lfk/frontend/commit/777304f2593df36f4e89d2ba7680add183ff062f)
- Copy-paste fix [`7488a8b`](https://git.odit.services/lfk/frontend/commit/7488a8b597a148c309e1b4499d277fed7f3bf9f4)
- You can now generate certificates from the runner overview [`bb9b779`](https://git.odit.services/lfk/frontend/commit/bb9b779cee909ab85ef52f13be0a917f1c0a9e62)
- Cleaned up generation strings and added the schem for single runner generations for cards [`9c867e1`](https://git.odit.services/lfk/frontend/commit/9c867e106edd68784e6d19743519c1952a0f0bc7)
- Changed the basic nameing generation for runenr certificate files [`d65d379`](https://git.odit.services/lfk/frontend/commit/d65d3793de869bcd6733a1bbdac378d0bc1128b3)
- ⏫ version bumps [`d7fecfb`](https://git.odit.services/lfk/frontend/commit/d7fecfbd0bc01f1cd44dea3c3837e0cc44afab12)
- Cleaned up generation strings and added the schem for single runner generations for sponsoring contracts [`22b09d1`](https://git.odit.services/lfk/frontend/commit/22b09d16d0acc2883e3448dad95ed0f4ea7c6aeb)
- Certificate generation from org overview [`3177c6e`](https://git.odit.services/lfk/frontend/commit/3177c6eaa31636ed4546f4797775a0f0a930f5d1)
- certificate pdf names now include their locale [`304f28a`](https://git.odit.services/lfk/frontend/commit/304f28a3c10bc4745aa5b7c80d7ba0e651540706)
- Runnercard pdfs now include their locale [`3638d87`](https://git.odit.services/lfk/frontend/commit/3638d87bd2ff83618eefda5af18ba19e38e3c2eb)
- 🐞 fix await for esNext [`a922776`](https://git.odit.services/lfk/frontend/commit/a9227768de29305b51d10c8a6e4fa1d39b7d998f)
- Certificate generation from team overview [`18ec100`](https://git.odit.services/lfk/frontend/commit/18ec100c33a1fbab526187e769dbae54d9db0867)
- Added certificate generation from runner overview and detail [`7b685d6`](https://git.odit.services/lfk/frontend/commit/7b685d6cad97d2f7f48c4b19bfc128e1355b70c4)
- package cleanup [`6be2ee6`](https://git.odit.services/lfk/frontend/commit/6be2ee626addaf5113b4b4821bd99a276bf4f329)
- sponsoring pdf names now include their locale [`0bae5bf`](https://git.odit.services/lfk/frontend/commit/0bae5bf32b8687057dca50cde21022ea8c3abee8)
- ✨ update licenses.json [`e99e9e0`](https://git.odit.services/lfk/frontend/commit/e99e9e07089520d5a48021e10d2af7739656641a)
- added windicss settings for VSCode [`008027d`](https://git.odit.services/lfk/frontend/commit/008027db0e2736a9bb9defd67178ab3fe580de04)
- Certificate generation from team detail [`acd2f05`](https://git.odit.services/lfk/frontend/commit/acd2f0519d62e55dad8e9c3c41e77b6967212502)
- ⚡💾 prevent env.js from being cached [`c5d1553`](https://git.odit.services/lfk/frontend/commit/c5d155396a92dfee6d592fb24a936ab521215f6d)
- for await fix - ViteJS [`aec5e34`](https://git.odit.services/lfk/frontend/commit/aec5e3473e687415fbfd69c550d9b012e1b1be43)
- Certificate generation from org detail [`e6ffc37`](https://git.odit.services/lfk/frontend/commit/e6ffc371e1ca2d4451e7dd4a3ca3c05564edb5fb)
- 🧹 drop unused dependencies [`ce50fa2`](https://git.odit.services/lfk/frontend/commit/ce50fa2a62f8ff98e8be9c66432caeebb3952019)
- 🐞 fix NGINX config [`5352410`](https://git.odit.services/lfk/frontend/commit/5352410d0c76fd14575d7beafc6a83f028062efe)
- Fixed wrong permissiong getting checked [`b97a928`](https://git.odit.services/lfk/frontend/commit/b97a92860d71eb0384170e245a67fa3ea3fd8e85)
- new license file version [CI SKIP] [`5cc4871`](https://git.odit.services/lfk/frontend/commit/5cc4871ec4be9f0af07738f6e3d44bdbe31cd25a)
- ⏫ bump @odit/lfk-client-js@0.10.1 [`8b74d6d`](https://git.odit.services/lfk/frontend/commit/8b74d6d759c8481f012c201e2ea0d12b29ddef90)
- 🔨 dev container open ⚡ [`ceb2146`](https://git.odit.services/lfk/frontend/commit/ceb2146c1b08bbe9250e4db7846e06bd89526c21)
- ⏫ version bump: vite-plugin-windicss@0.12.2 [`8d006d8`](https://git.odit.services/lfk/frontend/commit/8d006d8c74d71c43a9031d58f5a8c7fc55ed95fc)
- 🚚 move @svitejs/vite-plugin-svelte to @sveltejs/vite-plugin-svelte [`44b53da`](https://git.odit.services/lfk/frontend/commit/44b53da34516b00671b3e5060ba831e409ac3dd5)
- ⏫ upgrade vite-plugin-windicss@0.12.1 [`ab45fc1`](https://git.odit.services/lfk/frontend/commit/ab45fc144eaf14f63d86ee53c1db4eefd88f9c7f)
- 🐞 fix main.js linking [`467404b`](https://git.odit.services/lfk/frontend/commit/467404bfc87f3c08c5e227f194d71eea7cc48921)
- 🐞 fix vite config for production system [`10a011d`](https://git.odit.services/lfk/frontend/commit/10a011d8426e475105ff5d2d5cf4adca2ef7625c)
- fix dev script [`eb3ede9`](https://git.odit.services/lfk/frontend/commit/eb3ede9593e2e527df3e3a2f81c8e179bb555f51)
- ⏫ bump vite to 2.1.3 [`0cd3e93`](https://git.odit.services/lfk/frontend/commit/0cd3e937d852eeabe43eb6298bfabe20834240b2)
- Removed useless console.log [`d23dbaa`](https://git.odit.services/lfk/frontend/commit/d23dbaaf695a60fe5ebbc9945646a16b5fc45a16)
- Removed useless console log [`48cfc15`](https://git.odit.services/lfk/frontend/commit/48cfc15cfb09096db1bd5ddbe9138b1a604d581f)
#### [0.11.0](https://git.odit.services/lfk/frontend/compare/0.10.0...0.11.0)
> 30 March 2021
- Added button (including translations [`0614c76`](https://git.odit.services/lfk/frontend/commit/0614c76e924b18b512bab59933a26fec07cf483d)
- Added button (including translations [`97e338f`](https://git.odit.services/lfk/frontend/commit/97e338f9d4f388596d550990457254c7fa1a3492)
- Sorted translations [`89bb9c2`](https://git.odit.services/lfk/frontend/commit/89bb9c215e356e0940678f5cabd9e38bc203040e)
- Added function for generating cards with pdf [`c8d6390`](https://git.odit.services/lfk/frontend/commit/c8d639024a5f2f72d6e30d2ce990b08bd71a5471)
- 🚀RELEASE v0.11.0 [`f8ccf4f`](https://git.odit.services/lfk/frontend/commit/f8ccf4f5d8f68ecee31430029889b8ab1ecec682)
- Fixed button styling [`08cb079`](https://git.odit.services/lfk/frontend/commit/08cb079e9798392e26515d559af2637e74deea97)
- Now returning cards on creation with pdf [`1d999d4`](https://git.odit.services/lfk/frontend/commit/1d999d4910acb5efa21b3f9922cdb359babff404)
- new license file version [CI SKIP] [`8f8b998`](https://git.odit.services/lfk/frontend/commit/8f8b9988ad94ee9f3729a3fe6fdb4c558828d892)
- Merge pull request 'Generate and print bulk blank cards feature/116-download_blanc_cards' (#117) from feature/116-download_blanc_cards into dev [`25d8b86`](https://git.odit.services/lfk/frontend/commit/25d8b86efd89c442d1bf308a8743134820acfd1f)
- Added comment [`636f018`](https://git.odit.services/lfk/frontend/commit/636f018daa33b99468a257bfc33477e1e644d081)
- Bumped lfk client js version [`2d18686`](https://git.odit.services/lfk/frontend/commit/2d18686ce782a434ca7bd34c07c36a35b9497273)
- Bumped lfk-client-js [`7dfaa75`](https://git.odit.services/lfk/frontend/commit/7dfaa7579a22b13194fcdd1c02b4437958261472)
#### [0.10.0](https://git.odit.services/lfk/frontend/compare/0.9.1...0.10.0) #### [0.10.0](https://git.odit.services/lfk/frontend/compare/0.9.1...0.10.0)
> 26 March 2021
- Added translations [`79c447b`](https://git.odit.services/lfk/frontend/commit/79c447b4c65e55ebb5af71fb0b09174c36e2cecf) - Added translations [`79c447b`](https://git.odit.services/lfk/frontend/commit/79c447b4c65e55ebb5af71fb0b09174c36e2cecf)
- Sorted translations 🌍 [`5bd3a46`](https://git.odit.services/lfk/frontend/commit/5bd3a463f00abaf2c98ab554f88e5542d01f364a) - Sorted translations 🌍 [`5bd3a46`](https://git.odit.services/lfk/frontend/commit/5bd3a463f00abaf2c98ab554f88e5542d01f364a)
- Reset can now only be triggered if pw is strong enoug [`75d8f73`](https://git.odit.services/lfk/frontend/commit/75d8f7331b6ae78f3979bb62148188a16f83cb8d) - Reset can now only be triggered if pw is strong enoug [`75d8f73`](https://git.odit.services/lfk/frontend/commit/75d8f7331b6ae78f3979bb62148188a16f83cb8d)
- Module now exports functions that check if a password is strong enough and equal to a potential confirmation field [`b2509e9`](https://git.odit.services/lfk/frontend/commit/b2509e9e53ab6b51dfd55e26712e8928160cd64b) - Module now exports functions that check if a password is strong enough and equal to a potential confirmation field [`b2509e9`](https://git.odit.services/lfk/frontend/commit/b2509e9e53ab6b51dfd55e26712e8928160cd64b)
- 🚀RELEASE v0.10.0 [`f7fc196`](https://git.odit.services/lfk/frontend/commit/f7fc1967a50f302af1d8b668628be2f4ab2975a3)
- Added more cirteria to the password strength component [`5fa9939`](https://git.odit.services/lfk/frontend/commit/5fa9939696a35d60d762feb0cebef61d31869218) - Added more cirteria to the password strength component [`5fa9939`](https://git.odit.services/lfk/frontend/commit/5fa9939696a35d60d762feb0cebef61d31869218)
- Now using pw strength component [`6aaf838`](https://git.odit.services/lfk/frontend/commit/6aaf8384512185a3a319ce6b3e2505e910468e64) - Now using pw strength component [`6aaf838`](https://git.odit.services/lfk/frontend/commit/6aaf8384512185a3a319ce6b3e2505e910468e64)
- Added a password strength verification [`ad3bd31`](https://git.odit.services/lfk/frontend/commit/ad3bd312e9a5785f81029ea2b7e302ea1addd988) - Added a password strength verification [`ad3bd31`](https://git.odit.services/lfk/frontend/commit/ad3bd312e9a5785f81029ea2b7e302ea1addd988)

View File

@@ -1,18 +1,12 @@
FROM node:15.5.1-alpine3.12 FROM registry.odit.services/hub/library/node:15.14.0-alpine3.13
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 postcss.config.cjs 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 registry.odit.services/hub/fholzer/nginx-brotli:v1.19.1
COPY --from=0 /app/build /app COPY --from=0 /app/dist /usr/share/nginx/html
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
COPY --from=1 /app /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf COPY ./nginx.conf /etc/nginx/nginx.conf

22
README.md Normal file
View File

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

View File

@@ -10,14 +10,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Lauf Für Kaya! - Admin" /> <meta name="description" content="Lauf Für Kaya! - Admin" />
<title>Lauf für Kaya! - Admin</title> <title>Lauf für Kaya! - Admin</title>
__TAILWIND_INSERT__
</head> </head>
<body> <body>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.10.0-RELEASE_INFO</span> <span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.15.2-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,20 @@ http {
server { server {
error_page 404 /index.html; error_page 404 /index.html;
root /usr/share/nginx/html; root /usr/share/nginx/html;
location /assets {
expires 1y;
log_not_found off;
access_log off;
}
location = /index.html {
add_header Cache-Control 'no-store';
}
location = / {
add_header Cache-Control 'no-store';
}
location = /env.js {
add_header Cache-Control 'no-store';
}
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }

View File

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

6
postcss.config.cjs Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};

View File

@@ -1,5 +1,6 @@
const config = { const config = {
baseurl: 'http://localhost:4010', baseurl: 'http://localhost:4010',
baseurl_documentserver: 'http://localhost:4010/documents',
documentserver_key: 'NqZSYTy5AFQ7MppbLW5moqpTk7u7YrNUHKYhKYuThnnya2WpCOIU694hIZT1FzYe', documentserver_key: 'NqZSYTy5AFQ7MppbLW5moqpTk7u7YrNUHKYhKYuThnnya2WpCOIU694hIZT1FzYe',
// optional // optional
default_username: 'demo', default_username: 'demo',

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

@@ -76,7 +76,7 @@
// last login was not processed yet // last login was not processed yet
} else { } else {
Toastify({ Toastify({
text: "chill...", text: $_('please-wait-a-moment-your-login-is-still-being-processed'),
duration: 1500, duration: 1500,
backgroundColor: backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",

View File

@@ -0,0 +1,6 @@
<!--
Temporary tailwind import fixes for classes that wouldn't be directly used otherwise.
Or as others may call it: Real big bullshit time.
Issue: https://git.odit.services/lfk/frontend/issues/136
-->
<div class="opacity-50"></div>

View File

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

View File

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

View File

@@ -86,7 +86,7 @@
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: "Contact is being added...", text: $_('contact-is-being-added'),
duration: -1, duration: -1,
}).showToast(); }).showToast();
let address = {}; let address = {};
@@ -123,7 +123,7 @@
modal_open = false; modal_open = false;
// //
Toastify({ Toastify({
text: "Contact added", text: $_('contact-added'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();

View File

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

View File

@@ -9,6 +9,7 @@
} from "@odit/lfk-client-js"; } from "@odit/lfk-client-js";
import Select from "svelte-select"; import Select from "svelte-select";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import { is_promise } from "svelte/internal";
export let modal_open; export let modal_open;
export let current_donations; export let current_donations;
const getDonorLabel = (option) => const getDonorLabel = (option) =>
@@ -24,6 +25,7 @@
$: donors = []; $: donors = [];
$: runners = []; $: runners = [];
$: is_fixed = false; $: is_fixed = false;
$: is_paid = false;
DonorService.donorControllerGetAll().then((val) => { DonorService.donorControllerGetAll().then((val) => {
donors = val.map((r) => { donors = val.map((r) => {
return { label: getDonorLabel(r), value: r }; return { label: getDonorLabel(r), value: r };
@@ -57,14 +59,18 @@
let amount_cent = Math.floor(amount_input * 100); let amount_cent = Math.floor(amount_input * 100);
processed_last_submit = false; processed_last_submit = false;
const toast = Toastify({ const toast = Toastify({
text: "adding donation", text: $_('adding-donation'),
duration: -1, duration: -1,
}).showToast(); }).showToast();
if (is_fixed) { if (is_fixed) {
let postdata = { let postdata = {
donor, donor,
amount: amount_cent, amount: amount_cent,
paidAmount: 0
}; };
if(is_paid){
postdata.paidAmount = amount_cent;
}
DonationService.donationControllerPostFixed(postdata) DonationService.donationControllerPostFixed(postdata)
.then((result) => { .then((result) => {
donor = donors[0].id || 0; donor = donors[0].id || 0;
@@ -73,7 +79,7 @@
modal_open = false; modal_open = false;
// //
Toastify({ Toastify({
text: "donation_added", text: $_('donation_added'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
@@ -102,7 +108,7 @@
modal_open = false; modal_open = false;
// //
Toastify({ Toastify({
text: "donation_added", text: $_('donation_added'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
@@ -123,7 +129,7 @@
</script> </script>
<style> <style>
input:before { .toggle:before {
content: ""; content: "";
position: absolute; position: absolute;
width: 1.25rem; width: 1.25rem;
@@ -137,12 +143,12 @@
transition: 0.2s ease-in-out; transition: 0.2s ease-in-out;
} }
input:checked { .toggle:checked {
/* @apply: bg-indigo-400; */ /* @apply: bg-indigo-400; */
background-color: #7f9cf5; background-color: #7f9cf5;
} }
input:checked:before { .toggle:checked:before {
left: 1.25rem; left: 1.25rem;
} }
</style> </style>
@@ -195,7 +201,7 @@
class="ml-2 text-base" class="ml-2 text-base"
class:text-gray-300={is_fixed}>{$_('distance-donation')}</span> class:text-gray-300={is_fixed}>{$_('distance-donation')}</span>
<input <input
class="relative w-10 h-5 transition-all duration-200 ease-in-out bg-gray-400 rounded-full shadow-inner outline-none appearance-none align-middle" class="toggle relative w-10 h-5 transition-all duration-200 ease-in-out bg-gray-400 rounded-full shadow-inner outline-none appearance-none align-middle"
type="checkbox" type="checkbox"
bind:checked={is_fixed} /> bind:checked={is_fixed} />
<span <span
@@ -267,6 +273,29 @@
</span> </span>
{/if} {/if}
</div> </div>
{#if is_fixed}
<div class="col-span-6">
<label
for="paid"
class="block text-sm font-medium text-gray-700">{$_('already-paid')}</label>
<p class="text-gray-500">
<input
id="paid"
bind:checked={is_paid}
name="paid"
type="checkbox"
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" >
<span class="align-text-bottom">
{#if is_paid}
{$_('paid')}
{:else}
{$_('open')}
{/if}
</span>
</p>
</div>
{/if}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,202 @@
<script>
import { _ } from "svelte-i18n";
import { clickOutside } from "../base/outsideclick";
import { focusTrap } from "svelte-focus-trap";
import { DonationService } from "@odit/lfk-client-js";
import Toastify from "toastify-js";
export let payment_modal_open = false;
export let current_donations = [];
export let editable = {};
export let original_data = {};
export let paid_amount_input = 0;
$:processed_last_submit=true;
function focus(el) {
el.focus();
}
$: createbtnenabled = is_paid_amount_valid && !(paid_amount_input*100 == original_data.paidAmount)
$: is_paid_amount_valid = paid_amount_input > 0;
(() => {
document.onkeydown = (e) => {
e = e || window.event;
if (e.key === "Escape") {
payment_modal_open = false;
}
if (e.keyCode === 13) {
if (createbtnenabled === true) {
createbtnenabled = false;
submit();
}
}
};
})();
function submit() {
if (processed_last_submit === true) {
processed_last_submit = false;
const toast = Toastify({
text: $_('updating-donation'),
duration: -1,
}).showToast();
editable.donor = editable.donor.id;
editable.paidAmount = paid_amount_input*100;
if(editable.responseType == "DISTANCEDONATION" || editable.runner){
editable.runner = editable.runner.id;
DonationService.donationControllerPutDistance(original_data.id, editable)
.then((result) => {
let id = original_data.id;
editable = {};
original_data = {};
payment_modal_open = false;
//
Toastify({
text: $_('donation-updated'),
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
current_donations[current_donations.findIndex((c) => c.id === id)] = result;
current_donations = current_donations;
})
.catch((err) => {
//
})
.finally(() => {
processed_last_submit = true;
//
toast.hideToast();
});
}
else{
DonationService.donationControllerPutFixed(original_data.id, editable)
.then((result) => {
let id = original_data.id;
editable = {};
original_data = {};
payment_modal_open = false;
//
Toastify({
text: $_('donation-updated'),
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
current_donations[current_donations.findIndex((c) => c.id === id)] = result;
current_donations = current_donations;
})
.catch((err) => {
//
})
.finally(() => {
processed_last_submit = true;
//
toast.hideToast();
});
}
}
}
</script>
{#if payment_modal_open}
<div
class="fixed z-10 inset-0 overflow-y-auto"
use:focusTrap
use:clickOutside
on:click_outside={() => {
payment_modal_open = false;
}}>
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop" />
</div>
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span>
<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"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline">
<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="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">
<svg
class="h-6 w-6 text-blue-600"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"><path fill="none" d="M0 0h24v24H0z" />
<path
fill="currentColor"
d="M22 10v10a1 1 0 01-1 1H3a1 1 0 01-1-1V10h20zm0-2H2V4a1 1 0 011-1h18a1 1 0 011 1v4zm-7 8v2h4v-2h-4z" /></svg>
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900">
{$_('enter-payment')}
</h3>
<div class="mt-2 mb-6">
<p class="text-sm text-gray-500">
{$_('you-can-enter-the-donations-paid-amount-manually-or-use-the-max-button-to-use-the-donations-exact-amount')}
</p>
</div>
<div class="grid grid-cols gap-6">
<div class="w-full">
<label
for="token"
class="block text-sm font-medium text-gray-700">{$_('paid-amount')}</label>
<div class="inline-flex border-gray-300 border rounded-l-md rounded-r-md bg-gray-50 text-gray-500 w-full">
<input
autocomplete="off"
class:border-red-500={!is_paid_amount_valid}
class:focus:border-red-500={!is_paid_amount_valid}
class:focus:ring-red-500={!is_paid_amount_valid}
bind:value={paid_amount_input}
type="number"
step="0.01"
name="donation_amount_eur"
class="focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-l-md sm:text-sm p-2"
placeholder="2.00" />
<button
on:click={
()=>{
paid_amount_input=paid_amount_input = (original_data.amount/100).toFixed(2);
}
}
class="inline-flex items-center p-r-2 text-indigo-300 hover:text-indigo-700 text-sm">MAX</button>
<span
class="inline-flex items-center px-3 rounded-r-md border border-gray-300 bg-gray-50 text-gray-500 text-sm"></span>
</div>
{#if !is_paid_amount_valid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('payment-amount-must-be-greater-than-0-00eur')}
</span>
{/if}
</div>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button
disabled={!createbtnenabled}
class:opacity-50={!createbtnenabled}
on:click={submit}
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">
{$_('save-changes')}
</button>
<button
on:click={() => {
payment_modal_open = false;
}}
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">
{$_('cancel')}
</button>
</div>
</div>
</div>
</div>
{/if}

View File

@@ -20,6 +20,8 @@
$: current_runners = []; $: current_runners = [];
$: amount_input = 0; $: amount_input = 0;
$: is_amount_valid = amount_input > 0; $: is_amount_valid = amount_input > 0;
$: paid_amount_input = 0;
$: is_paid_amount_valid = paid_amount_input > 0;
$: is_everything_set = $: is_everything_set =
editable.donor != null && editable.donor != null &&
((original_data.responseType == "DISTANCEDONATION" && ((original_data.responseType == "DISTANCEDONATION" &&
@@ -30,15 +32,17 @@
(original_data.responseType == "DISTANCEDONATION" && (original_data.responseType == "DISTANCEDONATION" &&
!(Math.floor(amount_input * 100) === original_data.amountPerDistance)) || !(Math.floor(amount_input * 100) === original_data.amountPerDistance)) ||
(original_data.responseType !== "DISTANCEDONATION" && (original_data.responseType !== "DISTANCEDONATION" &&
!(Math.floor(amount_input * 100) === original_data.amount)); !(Math.floor(amount_input * 100) === original_data.amount)) ||
!(Math.floor(paid_amount_input * 100) === original_data.paidAmount);
$: save_enabled = changes_performed && is_amount_valid && is_everything_set; $: save_enabled = changes_performed && is_amount_valid && is_everything_set;
const promise = DonationService.donationControllerGetOne( const promise = DonationService.donationControllerGetOne(
params.donationid params.donationid
).then((data) => { ).then((data) => {
data_loaded = true; data_loaded = true;
original_data = Object.assign(original_data, data); original_data = Object.assign({}, data);
editable = Object.assign(editable, original_data); editable = Object.assign({}, original_data);
paid_amount_input = data.paidAmount / 100;
if (data.responseType == "DISTANCEDONATION") { if (data.responseType == "DISTANCEDONATION") {
amount_input = data.amountPerDistance / 100; amount_input = data.amountPerDistance / 100;
RunnerService.runnerControllerGetAll().then((val) => { RunnerService.runnerControllerGetAll().then((val) => {
@@ -66,10 +70,11 @@
function submit() { function submit() {
if (data_loaded === true && save_enabled) { if (data_loaded === true && save_enabled) {
Toastify({ Toastify({
text: "Donation is being updated", text: $_('updating-donation'),
duration: 2500, duration: 2500,
}).showToast(); }).showToast();
let postdata = {}; let postdata = {};
editable.paidAmount = paid_amount_input*100;
if (original_data.responseType === "DISTANCEDONATION") { if (original_data.responseType === "DISTANCEDONATION") {
editable.amountPerDistance = Math.floor(amount_input * 100); editable.amountPerDistance = Math.floor(amount_input * 100);
postdata = Object.assign(postdata, editable); postdata = Object.assign(postdata, editable);
@@ -83,7 +88,7 @@
Object.assign(original_data, editable); Object.assign(original_data, editable);
original_data = original_data; original_data = original_data;
Toastify({ Toastify({
text: "updated donation", text: $_('donation-updated'),
duration: 2500, duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
@@ -98,7 +103,7 @@
Object.assign(original_data, editable); Object.assign(original_data, editable);
original_data = original_data; original_data = original_data;
Toastify({ Toastify({
text: "updated donation", text: $_('donation-updated'),
duration: 2500, duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
@@ -112,7 +117,7 @@
DonationService.donationControllerRemove(original_data.id, false) DonationService.donationControllerRemove(original_data.id, false)
.then((resp) => { .then((resp) => {
Toastify({ Toastify({
text: "Donation delete", text: $_('donation-deleted'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
@@ -219,7 +224,24 @@
<span>{(editable.amount / 100) <span>{(editable.amount / 100)
.toFixed(2) .toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })}</span> .toLocaleString('de-DE', { valute: 'EUR' })}</span>
|
<span
class="font-medium text-gray-700">{$_('paid-amount')}:</span>
<span>{(editable.paidAmount / 100)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })}</span>
|
<span
class="font-medium text-gray-700">{$_('status')}:</span>
{#if editable.status =="PAID"}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('paid')}</span>
{:else}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('open')}</span>
{/if}
</div> </div>
<br>
<div class=" w-full"> <div class=" w-full">
<label <label
for="donor" for="donor"
@@ -232,7 +254,7 @@
placeholder={$_('search-for-donor-name-or-id')} placeholder={$_('search-for-donor-name-or-id')}
noOptionsMessage={$_('no-donors-found')} noOptionsMessage={$_('no-donors-found')}
bind:selectedValue={donor} bind:selectedValue={donor}
on:select={(selectedValue) => (editable.donor = selectedValue.detail.value)} on:select={(selectedValue) => {editable.donor = selectedValue.detail.value; editable.donor.donationAmount=original_data.donor.donationAmount; editable.donor.paidDonationAmount =original_data.donor.paidDonationAmount}}
on:clear={() => (editable.donor = null)} /> on:clear={() => (editable.donor = null)} />
</div> </div>
{#if original_data.responseType == 'DISTANCEDONATION'} {#if original_data.responseType == 'DISTANCEDONATION'}
@@ -280,6 +302,39 @@
</span> </span>
{/if} {/if}
</div> </div>
<div class="w-full">
<label
for="token"
class="block text-sm font-medium text-gray-700">{$_('paid-amount')}</label>
<div class="inline-flex border-gray-300 border rounded-l-md rounded-r-md bg-gray-50 text-gray-500 w-full">
<input
autocomplete="off"
class:border-red-500={!is_amount_valid}
class:focus:border-red-500={!is_amount_valid}
class:focus:ring-red-500={!is_amount_valid}
bind:value={paid_amount_input}
type="number"
step="0.01"
name="donation_amount_eur"
class="focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-l-md sm:text-sm p-2"
placeholder="2.00" />
<button
on:click={
()=>{
paid_amount_input=paid_amount_input = (original_data.amount/100).toFixed(2);
}
}
class="inline-flex items-center p-r-2 text-indigo-300 hover:text-indigo-700 text-sm">MAX</button>
<span
class="inline-flex items-center px-3 rounded-r-md border border-gray-300 bg-gray-50 text-gray-500 text-sm"></span>
</div>
{#if !is_paid_amount_valid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('payment-amount-must-be-greater-than-0-00eur')}
</span>
{/if}
</div>
</section> </section>
{:catch error} {:catch error}
<PromiseError {error} /> <PromiseError {error} />

View File

@@ -4,9 +4,14 @@
import store from "../../store"; import store from "../../store";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import DonationsEmptyState from "./DonationsEmptyState.svelte"; import DonationsEmptyState from "./DonationsEmptyState.svelte";
import AddDonationPaymentModal from "./AddDonationPaymentModal.svelte";
$: searchvalue = ""; $: searchvalue = "";
$: active_deletes = []; $: active_deletes = [];
export let current_donations = []; export let current_donations = [];
export let payment_modal_open = false;
export let editable = {};
export let original_data = {};
export let paid_amount_input = 0;
const donations_promise = DonationService.donationControllerGetAll().then( const donations_promise = DonationService.donationControllerGetAll().then(
(val) => { (val) => {
current_donations = val; current_donations = val;
@@ -18,8 +23,15 @@
} }
return id.toString() === searchvalue; return id.toString() === searchvalue;
} }
function open_payment_modal(donation) {
editable = Object.assign({}, donation);
original_data = Object.assign({}, donation);
paid_amount_input = (donation.paidAmount/100).toFixed(2);
payment_modal_open = true;
}
</script> </script>
<AddDonationPaymentModal bind:current_donations bind:original_data bind:editable bind:paid_amount_input bind:payment_modal_open />
{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')} {#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')}
{#await donations_promise} {#await donations_promise}
<div <div
@@ -63,6 +75,16 @@
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('donation-amount')} {$_('donation-amount')}
</th> </th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('paid-amount')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('status')}
</th>
<th scope="col" class="relative px-6 py-3"> <th scope="col" class="relative px-6 py-3">
<span class="sr-only">{$_('action')}</span> <span class="sr-only">{$_('action')}</span>
</th> </th>
@@ -132,6 +154,22 @@
.toLocaleString('de-DE', { valute: 'EUR' })} .toLocaleString('de-DE', { valute: 'EUR' })}
</div> </div>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-gray-900">
{(donation.paidAmount / 100)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
{#if donation.status =="PAID"}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('paid')}</span>
{:else}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('open')}</span>
{/if}
</td>
{#if active_deletes[donation.id] === true} {#if active_deletes[donation.id] === true}
<td <td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
@@ -149,7 +187,7 @@
(obj) => obj.id !== donation.id (obj) => obj.id !== donation.id
); );
Toastify({ Toastify({
text: 'Donation deleted', text: $_('donation-deleted'),
duration: 500, duration: 500,
backgroundColor: backgroundColor:
'linear-gradient(to right, #00b09b, #96c93d)', 'linear-gradient(to right, #00b09b, #96c93d)',
@@ -163,6 +201,9 @@
{:else} {:else}
<td <td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
on:click={() => {open_payment_modal(donation);}}
class="text-[#025a21] hover:text-green-900 mr-4">{$_('enter-payment')}</button>
<a <a
href="./{donation.id}" href="./{donation.id}"
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a> class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>

View File

@@ -19,7 +19,7 @@
) )
.then((resp) => { .then((resp) => {
Toastify({ Toastify({
text: "Donor deleted", text: $_('donor-deleted'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();

View File

@@ -193,6 +193,12 @@
<span>{(editable.donationAmount / 100) <span>{(editable.donationAmount / 100)
.toFixed(2) .toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })}</span> .toLocaleString('de-DE', { valute: 'EUR' })}</span>
|
<span
class="font-medium text-gray-700">{$_('total-paid-amount')}:</span>
<span>{(editable.paidDonationAmount / 100)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })}</span>
<br /> <br />
<span class="font-medium text-gray-700">{$_('donations')}:</span> <span class="font-medium text-gray-700">{$_('donations')}:</span>
{#if current_donations.filter((d) => d.donor.id == editable.id).length > 0} {#if current_donations.filter((d) => d.donor.id == editable.id).length > 0}

View File

@@ -20,6 +20,31 @@
{$_('add-donor')} {$_('add-donor')}
</button> </button>
{/if} {/if}
{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')}
<button
on:click={() => {
const data = (current_donors.filter(d=>d.receiptNeeded===true)).map(function (d) {
d.address.address2=d.address.address2===""?"":" "+d.address.address2;
const address=`${d.address.address1}${d.address.address2}, ${d.address.postalcode} ${d.address.city}, ${d.address.country}`;
return [d.firstname,d.middlename,d.lastname,d.paidDonationAmount,address];
})
let csv = `${$_('csv_import__firstname')};${$_('csv_import__middlename')};${$_('csv_import__lastname')};${$_('total_donation_amount_in_eur')};${$_('address')}\n`;
data.forEach(function(row) {
csv += row.join(';');
csv += "\n";
});
let hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
hiddenElement.target = '_blank';
hiddenElement.download = `${$_('filename_sponsoringquittungsliste')}.csv`;
hiddenElement.click();
hiddenElement.remove();
}}
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">
{$_('sponsoring-quittungs-liste_herunterladen')}
</button>
{/if}
</span> </span>
<DonorsOverview bind:current_donors /> <DonorsOverview bind:current_donors />
</section> </section>

View File

@@ -1,5 +1,5 @@
<script> <script>
import { getLocaleFromNavigator, _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { DonationService, DonorService } from "@odit/lfk-client-js"; import { DonationService, DonorService } from "@odit/lfk-client-js";
import store from "../../store"; import store from "../../store";
import DonorsEmptyState from "./DonorsEmptyState.svelte"; import DonorsEmptyState from "./DonorsEmptyState.svelte";
@@ -77,6 +77,11 @@
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('total-donation-amount')} {$_('total-donation-amount')}
</th> </th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('total-paid-amount')}
</th>
<th scope="col" class="relative px-6 py-3"> <th scope="col" class="relative px-6 py-3">
<span class="sr-only">{$_('action')}</span> <span class="sr-only">{$_('action')}</span>
</th> </th>
@@ -145,6 +150,11 @@
.toFixed(2) .toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })} .toLocaleString('de-DE', { valute: 'EUR' })}
</td> </td>
<td class="px-6 py-4 whitespace-nowrap">
{(donor.paidDonationAmount / 100)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })}
</td>
{#if active_deletes[donor.id] === true} {#if active_deletes[donor.id] === true}
<td <td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">

View File

@@ -32,8 +32,12 @@
target="_blank" target="_blank"
rel="noopener, noreferrer" rel="noopener, noreferrer"
href="https://git.odit.services/lfk/frontend/src/tag/{releaseinfo}">{releaseinfo}</a> href="https://git.odit.services/lfk/frontend/src/tag/{releaseinfo}">{releaseinfo}</a>
- -
<a class="underline" href="https://docs.lauf-fuer-kaya.de" target="_blank">{$_('documentation')}</a> <a
rel="noopener, noreferrer"
class="underline"
href="https://docs.lauf-fuer-kaya.de"
target="_blank">{$_('documentation')}</a>
- -
<a class="underline" href="/privacy">{$_('privacy')}</a> <a class="underline" href="/privacy">{$_('privacy')}</a>
- -

View File

@@ -19,7 +19,7 @@
) )
.then((resp) => { .then((resp) => {
Toastify({ Toastify({
text: "Organization deleted", text: $_('organization-deleted'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();

View File

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

View File

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

View File

@@ -41,7 +41,7 @@
duration: -1, duration: -1,
}).showToast(); }).showToast();
fetch( fetch(
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -67,7 +67,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Runnercards.pdf"; a.download = `${$_('runnercards')}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -101,7 +101,7 @@
cards.push(card); cards.push(card);
} }
fetch( fetch(
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -127,7 +127,12 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Runnercards.pdf"; if(generate_runners.length == 1){
a.download = `${$_('runnercards')}_${generate_runners[0].firstname}_${generate_runners[0].lastname}-${locale}.pdf`;
}
else{
a.download = `Runnercards-${locale}.pdf`;
}
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -149,7 +154,7 @@
}).showToast(); }).showToast();
let count = 0; let count = 0;
const current_cards = await RunnerCardService.runnerCardControllerGetAll(); const current_cards = await RunnerCardService.runnerCardControllerGetAll();
for await (const t of generate_teams) { for (const t of generate_teams) {
const runners = await RunnerTeamService.runnerTeamControllerGetRunners( const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id t.id
); );
@@ -164,7 +169,7 @@
cards.push(card); cards.push(card);
} }
fetch( fetch(
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -191,7 +196,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsorings_" + t.name + ".pdf"; a.download = `${$_('runnercards')}_${t.name}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -211,15 +216,16 @@
async function generateOrgCards(locale) { async function generateOrgCards(locale) {
const toast = Toastify({ const toast = Toastify({
text: $_("generating-pdf"), text: $_("generating-pdfs"),
duration: -1, duration: -1,
}).showToast(); }).showToast();
let count = 0;
const current_cards = await RunnerCardService.runnerCardControllerGetAll(); const current_cards = await RunnerCardService.runnerCardControllerGetAll();
for await (const o of generate_orgs) { let count = 0;
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners( let count_orgs =0;
o.id for (const o of generate_orgs) {
); count_orgs++;
let count = 0;
let runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(o.id, true)
let cards = []; let cards = [];
for (let runner of runners) { for (let runner of runners) {
let card = current_cards.find((c) => c.runner?.id == runner.id); let card = current_cards.find((c) => c.runner?.id == runner.id);
@@ -230,8 +236,8 @@
} }
cards.push(card); cards.push(card);
} }
fetch( await fetch(
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -240,39 +246,97 @@
body: JSON.stringify(cards), body: JSON.stringify(cards),
} }
) )
.then((response) => { .then((response) => {
if (response.status != "200") { if (response.status != "200") {
toast.hideToast(); toast.hideToast();
Toastify({ Toastify({
text: $_("pdf-generation-failed"), text: $_("pdf-generation-failed"),
duration: 3500, duration: 3500,
backgroundColor: backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast(); }).showToast();
} else { } else {
return response.blob(); return response.blob();
} }
}) })
.then((blob) => { .then((blob) => {
count++; const url = window.URL.createObjectURL(blob);
const url = window.URL.createObjectURL(blob); let a = document.createElement("a");
let a = document.createElement("a"); a.href = url;
a.href = url; a.download = `${$_('runnercards')}_${o.name}_direct-${locale}.pdf`;
a.download = "Sponsorings_" + o.name + ".pdf"; document.body.appendChild(a);
document.body.appendChild(a); a.click();
a.click(); a.remove();
a.remove(); if (count === o.teams.length && count_orgs === generate_orgs.length) {
if (count === generate_orgs.length) { toast.hideToast();
toast.hideToast(); console.log("here")
Toastify({ Toastify({
text: $_("pdfs-successfully-generated"), text: $_("pdfs-successfully-generated"),
duration: 3500, duration: 3500,
backgroundColor: backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)", "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
} }
}) })
.catch((err) => {}); .catch((err) => {});
for (const t of o.teams) {
count++;
let runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id
);
let cards = [];
for (let runner of runners) {
let card = current_cards.find((c) => c.runner?.id == runner.id);
if (!card) {
card = await RunnerCardService.runnerCardControllerPost({
runner: runner.id,
});
}
cards.push(card);
}
await fetch(
`${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(cards),
}
)
.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 = `${$_('runnercards')}_${o.name}_${t.name}-${locale}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
if (count === o.teams.length && count_orgs === generate_orgs.length) {
toast.hideToast();
Toastify({
text: $_("pdfs-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
})
.catch((err) => {});
}
} }
} }
</script> </script>

View File

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

View File

@@ -37,13 +37,13 @@
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
); );
fetch( fetch(
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -69,7 +69,7 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsorings_" + t.name + ".pdf"; a.download = `${$_('sponsorings')}_${t.name}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();
@@ -92,12 +92,13 @@
text: $_("generating-pdf"), text: $_("generating-pdf"),
duration: -1, duration: -1,
}).showToast(); }).showToast();
for await (const o of generate_orgs) { let count_orgs =0;
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners( for (const o of generate_orgs) {
o.id count_orgs++;
); let count = 0;
fetch( let runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(o.id, true)
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`, await fetch(
`${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -106,39 +107,87 @@
body: JSON.stringify(runners), body: JSON.stringify(runners),
} }
) )
.then((response) => { .then((response) => {
if (response.status != "200") { if (response.status != "200") {
toast.hideToast(); toast.hideToast();
Toastify({ Toastify({
text: $_("pdf-generation-failed"), text: $_("pdf-generation-failed"),
duration: 3500, duration: 3500,
backgroundColor: backgroundColor:
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
}).showToast(); }).showToast();
} else { } else {
return response.blob(); return response.blob();
} }
}) })
.then((blob) => { .then((blob) => {
count++; const url = window.URL.createObjectURL(blob);
const url = window.URL.createObjectURL(blob); let a = document.createElement("a");
let a = document.createElement("a"); a.href = url;
a.href = url; a.download = `${$_('sponsorings')}_${o.name}_direct-${locale}.pdf`;
a.download = "Sponsorings_" + o.name + ".pdf"; document.body.appendChild(a);
document.body.appendChild(a); a.click();
a.click(); a.remove();
a.remove(); if (count === o.teams.length && count_orgs === generate_orgs.length) {
if (count === generate_orgs.length) { toast.hideToast();
toast.hideToast(); console.log("here")
Toastify({ Toastify({
text: $_("pdfs-successfully-generated"), text: $_("pdfs-successfully-generated"),
duration: 3500, duration: 3500,
backgroundColor: backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)", "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
} }
}) })
.catch((err) => {}); .catch((err) => {});
for (const t of o.teams) {
count++;
let runners = await RunnerTeamService.runnerTeamControllerGetRunners(
t.id
);
await fetch(
`${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(runners),
}
)
.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 = `${$_('sponsorings')}_${o.name}_${t.name}-${locale}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
if (count === o.teams.length && count_orgs === generate_orgs.length) {
toast.hideToast();
Toastify({
text: $_("pdfs-successfully-generated"),
duration: 3500,
backgroundColor:
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
})
.catch((err) => {});
}
} }
} }
@@ -148,7 +197,7 @@
duration: -1, duration: -1,
}).showToast(); }).showToast();
fetch( fetch(
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`, `${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -174,7 +223,10 @@
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
let a = document.createElement("a"); let a = document.createElement("a");
a.href = url; a.href = url;
a.download = "Sponsoring.pdf"; if(generate_runners.length == 1){
a.download = `${$_('sponsorings')}_${generate_runners[0].firstname}_${generate_runners[0].lastname}-${locale}.pdf`;
}
a.download = `${$_('sponsorings')}-${locale}.pdf`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
a.remove(); a.remove();

View File

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

View File

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

View File

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

View File

@@ -17,7 +17,7 @@
MeService.meControllerRemove(true) MeService.meControllerRemove(true)
.then((resp) => { .then((resp) => {
Toastify({ Toastify({
text: "Profile deleted!", text: $_('profile-deleted'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();

View File

@@ -43,7 +43,7 @@
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: "Team is being added...", text: $_('team-is-being-added'),
duration: -1, duration: -1,
}).showToast(); }).showToast();
RunnerTeamService.runnerTeamControllerPost({ RunnerTeamService.runnerTeamControllerPost({
@@ -55,7 +55,7 @@
modal_open = false; modal_open = false;
// //
Toastify({ Toastify({
text: "Team added", text: $_('team-added'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();

View File

@@ -16,7 +16,7 @@
RunnerTeamService.runnerTeamControllerRemove(delete_team.id, true) RunnerTeamService.runnerTeamControllerRemove(delete_team.id, true)
.then((resp) => { .then((resp) => {
Toastify({ Toastify({
text: "Team deleted", text: $_('team-deleted'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();

View File

@@ -14,6 +14,7 @@
import Teams from "./Teams.svelte"; import Teams from "./Teams.svelte";
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
let [teamdata, original, delete_team, orgs, contacts, modal_open] = [ let [teamdata, original, delete_team, orgs, contacts, modal_open] = [
{}, {},
{}, {},
@@ -25,11 +26,12 @@
export let params; export let params;
export let import_modal_open = false; export let import_modal_open = false;
$: delete_triggered = false; $: delete_triggered = false;
$: save_enabled = !data_changed && teamdata.parentGroup != null; $: save_enabled = data_changed && teamdata.parentGroup != null;
$: data_loaded = false; $: data_loaded = false;
$: data_changed = JSON.stringify(teamdata) === JSON.stringify(original); $: data_changed = !(JSON.stringify(teamdata) === JSON.stringify(original));
$: sponsoring_contracts_show = true; $: sponsoring_contracts_show = true;
$: cards_show = true; $: cards_show = true;
$: certificates_show = true;
$: generate_teams = [original]; $: generate_teams = [original];
$: group = {}; $: group = {};
$: contact = {}; $: contact = {};
@@ -45,6 +47,8 @@
RunnerOrganizationService.runnerOrganizationControllerGetAll().then( RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
(val) => { (val) => {
orgs = val.map((r) => { orgs = val.map((r) => {
delete r.contact;
r.teams = [];
return { label: r.name, value: r }; return { label: r.name, value: r };
}); });
group = orgs.find((g) => g.value.id == teamdata.parentGroup.id); group = orgs.find((g) => g.value.id == teamdata.parentGroup.id);
@@ -65,7 +69,7 @@
RunnerTeamService.runnerTeamControllerRemove(original.id, false) RunnerTeamService.runnerTeamControllerRemove(original.id, false)
.then((resp) => { .then((resp) => {
Toastify({ Toastify({
text: "Organization deleted", text: $_('team-deleted'),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
@@ -79,7 +83,7 @@
function submit() { function submit() {
if (data_loaded === true && save_enabled) { if (data_loaded === true && save_enabled) {
Toastify({ Toastify({
text: "updating team", text: $_('updating-team'),
duration: 2500, duration: 2500,
}).showToast(); }).showToast();
let postdata = teamdata; let postdata = teamdata;
@@ -90,7 +94,7 @@
Object.assign(original, teamdata); Object.assign(original, teamdata);
original = original; original = original;
Toastify({ Toastify({
text: "updated team", text: $_('updated-team'),
duration: 2500, duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
@@ -122,6 +126,9 @@
<GenerateRunnerCards <GenerateRunnerCards
bind:cards_show bind:cards_show
bind:generate_teams /> bind:generate_teams />
<GenerateRunnerCertificates
bind:certificates_show
bind:generate_teams />
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')} {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
<button <button
on:click={() => { on:click={() => {

View File

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

View File

@@ -34,7 +34,7 @@
`[data-id="triggered_table_actions_${trackid}"]` `[data-id="triggered_table_actions_${trackid}"]`
).parentNode.parentNode.parentNode; ).parentNode.parentNode.parentNode;
Toastify({ Toastify({
text: "Track is being updated...", text: $_('track-is-being-updated'),
duration: 500, duration: 500,
}).showToast(); }).showToast();
TrackService.trackControllerPut(trackid, { TrackService.trackControllerPut(trackid, {
@@ -45,7 +45,7 @@
}) })
.then((r) => { .then((r) => {
Toastify({ Toastify({
text: "Track was updated!", text: $_('track-was-updated'),
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
duration: 1000, duration: 1000,
}).showToast(); }).showToast();

View File

@@ -27,7 +27,7 @@
}); });
function submit() { function submit() {
Toastify({ Toastify({
text: "updating permissions...", text: $_('updating-permissions'),
duration: 2500, duration: 2500,
}).showToast(); }).showToast();
to_delete.forEach((d) => { to_delete.forEach((d) => {

View File

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

View File

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

View File

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

9
src/main.js Normal file
View File

@@ -0,0 +1,9 @@
import './style.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;

3
src/style.css Normal file
View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

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,15 @@
module.exports = { module.exports = {
purge: { mode: 'jit',
content: [ './src/**/*.svelte' ] purge: [ './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);

38
vite.config.js Normal file
View File

@@ -0,0 +1,38 @@
import svelte from '@sveltejs/vite-plugin-svelte';
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: [
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
};