Compare commits
338
Commits
0.9.1
...
c7990882cf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7990882cf
|
||
|
|
d4ab76ea1b
|
||
|
|
2c992a0e63
|
||
|
|
88f96acc3c
|
||
|
|
245db06173
|
||
|
|
49c2cd5c4b
|
||
|
|
64db553185
|
||
|
|
a06a19ce9c
|
||
|
|
592ddc1541
|
||
|
|
cb5f2b73d0
|
||
|
|
2304b12c1c
|
||
|
|
38d3e1912c
|
||
|
|
fbc14fd7b4
|
||
|
|
0283df22c8
|
||
|
|
845737ee8e
|
||
|
|
6993511c67
|
||
|
|
9111ad147c
|
||
|
|
333214aa8f
|
||
|
|
c0cde02fec
|
||
|
|
070a20a2e5
|
||
|
|
c5e8409079
|
||
|
|
67eff0eda9
|
||
|
|
3de7b632e0
|
||
|
|
842248e4c4
|
||
|
|
c5d7ec25b5
|
||
|
|
a9a965d698
|
||
|
|
dc866dd540
|
||
|
|
89252619b1
|
||
|
|
2699b06d7c
|
||
|
|
fd0d45f721
|
||
|
|
5ecf838dd2
|
||
|
|
45a7a90cb8
|
||
|
|
cac851f2b1
|
||
|
|
238082b657
|
||
|
|
aecbabe522
|
||
|
|
a9cdac4f74
|
||
|
|
a59dbbe50e
|
||
|
|
9bec95ede8
|
||
|
|
70307a9e82
|
||
|
|
ef077b4e6a
|
||
|
|
dcabed4e93
|
||
|
|
1af047f66e
|
||
|
|
ee91748b3c
|
||
|
|
e5241d619b
|
||
|
|
d79608edbb
|
||
|
|
4cbd26580e
|
||
|
|
fe62ad5539
|
||
|
|
eb13f038a1
|
||
|
|
9505c2b030 | ||
|
|
008835c24f | ||
|
|
7083b3d8d2 | ||
|
|
754931b2f6 | ||
|
|
2dc8ffba32 | ||
|
|
d0fe6a2e85 | ||
|
|
85705b6e68 | ||
|
|
3ea7a015a9 | ||
|
|
44329413ed | ||
|
|
46db68ab22 | ||
|
|
dc9d7f22a2 | ||
|
|
f917018fd9 | ||
|
|
7b420c430d | ||
|
|
00359d25c1 | ||
|
|
d8a3063735 | ||
|
|
6491af19e3
|
||
|
|
61328d20ed | ||
|
|
0a6d92a1f3
|
||
|
|
3a576d1073
|
||
|
|
b30b98b521
|
||
|
|
43d82a2af0
|
||
|
|
6a4495b813 | ||
|
|
e8a0ad6647
|
||
|
|
92b89cc4d8
|
||
|
|
268b1b1d98
|
||
|
|
75bc89ca30
|
||
|
|
0625937068 | ||
|
|
32a9074963
|
||
|
|
b869b5fd2a
|
||
|
|
3a3e2f7157 | ||
|
|
bea57aa03a | ||
|
|
30991d5364 | ||
|
|
5cc8b0811c | ||
|
|
2c73b9862d | ||
|
|
732b2f061e | ||
|
|
3680533eef | ||
|
|
1307d72c9d | ||
|
|
405dfa0c34 | ||
|
|
5c2d154ad1 | ||
|
|
f2bf8d9bac | ||
|
|
f9cfd6bd06
|
||
|
|
287f63fa52
|
||
|
|
5fe47634e8
|
||
|
|
a6590910cf | ||
|
|
ad454c386c | ||
|
|
0b2c296de0
|
||
|
|
0e85940cba
|
||
|
|
8d479c32f8 | ||
|
|
549785cf7d | ||
|
|
aafc4c8d62
|
||
|
|
47dedbdc73
|
||
|
|
6fe134afc8
|
||
|
|
63a50f92e7
|
||
|
|
ca6da15ef7
|
||
|
|
8dfa19fa0f
|
||
|
|
0feee0ae2f
|
||
|
|
2a6a39916a | ||
|
|
f0a2b2859f
|
||
|
|
32ddb66fc8
|
||
|
|
df63c2388d
|
||
|
|
757655ea63
|
||
|
|
329c1cc037 | ||
|
|
da6dd55d13 | ||
|
|
0e5490f1c8 | ||
|
|
b82d638de1 | ||
|
|
224034dcc6 | ||
|
|
026d3d41c1 | ||
|
|
fd1a06b359 | ||
|
|
452d010183
|
||
|
|
eb1c17e3ac
|
||
|
|
a101873eb0
|
||
|
|
3d2acb692a
|
||
|
|
0900c2691e
|
||
|
|
1337676e08
|
||
|
|
2e075eafab | ||
|
|
14d64b6070 | ||
|
|
81b8fbf4e3 | ||
|
|
24d074752f | ||
|
|
08047a9307 | ||
|
|
1b0cd5b90b | ||
|
|
65e8998894 | ||
|
|
449948050b | ||
|
|
cf97281592 | ||
|
|
75684efa1a | ||
|
|
2c4f27a943 | ||
|
|
53b7dec7cd | ||
|
|
e0cbfb000b
|
||
|
|
3a66f4c862 | ||
|
|
85ceaa464f
|
||
|
|
976755338b
|
||
|
|
1c980059cf
|
||
|
|
2d8c4c1698
|
||
|
|
19a333d7bd
|
||
|
|
96c55db63d
|
||
|
|
fecb07ee37
|
||
|
|
e10c6480a5
|
||
|
|
f3cc07c009
|
||
|
|
068076dd47
|
||
|
|
02158605be
|
||
|
|
674e6a90ec
|
||
|
|
f679330466
|
||
|
|
93fc7c2e83
|
||
|
|
f299617c60
|
||
|
|
28cbc5b98c
|
||
|
|
c28f1ee0bc
|
||
|
|
cff112d705
|
||
|
|
9fc4ad63c4 | ||
|
|
97054a71c1 | ||
|
|
2391668a25
|
||
|
|
717d33547c | ||
|
|
997be32679 | ||
|
|
134f00c40e
|
||
|
|
47c898bdfd
|
||
|
|
e752ee12d1 | ||
|
|
cc4515ff66
|
||
|
|
f190292171 | ||
|
|
b246f2b349
|
||
|
|
76b69d851a | ||
|
|
224f586368 | ||
|
|
9add6c8ff1 | ||
|
|
7a63d4eed1 | ||
|
|
e54a4807f7 | ||
|
|
cee04c1d6f | ||
|
|
cbec78589d | ||
|
|
a85db7cb3f | ||
|
|
2bd3779839 | ||
|
|
303e33cafb | ||
|
|
b4e689dddf | ||
|
|
98a0b036c5 | ||
|
|
fb3f30fb10 | ||
|
|
6213952007 | ||
|
|
07ac041d69 | ||
|
|
5c02028841 | ||
|
|
c561b53670 | ||
|
|
dcd0d5a362 | ||
|
|
18acac83bc | ||
|
|
d7d44470bb | ||
|
|
0f0aae7ba4 | ||
|
|
4c0886a5d9 | ||
|
|
04a3038369 | ||
|
|
bdcf5d3fc0 | ||
|
|
c7a858eed7 | ||
|
|
de5aa9237d | ||
|
|
d015f97395 | ||
|
|
57618156b4 | ||
|
|
865254d646 | ||
|
|
1dbab03fe7 | ||
|
|
a943aaf5fc | ||
|
|
6e6e8b2617 | ||
|
|
4c2c24af2c | ||
|
|
3d3a10aafb | ||
|
|
000fc97beb | ||
|
|
5645eeaafa | ||
|
|
961477d522 | ||
|
|
a5f71015a6 | ||
|
|
e42ea943b7 | ||
|
|
9c5fc6b61c | ||
|
|
302caf015f | ||
|
|
e11296071a | ||
|
|
112eb29f93 | ||
|
|
c6c97516b3 | ||
|
|
03676b2894 | ||
|
|
9ca57fac2e | ||
|
|
18f151c1fb | ||
|
|
e90e56d8b2 | ||
|
|
d241ca5698 | ||
|
|
b512cf8667 | ||
|
|
a24d2923c6 | ||
|
|
467808abef | ||
|
|
861f1f2216 | ||
|
|
509b22bea0 | ||
|
|
7447b2f4c1 | ||
|
|
fef14b6e4f | ||
|
|
01d2a7e6aa | ||
|
|
ac586fec5a | ||
|
|
5476808683 | ||
|
|
331d737796 | ||
|
|
ef81b8adf9 | ||
|
|
8a7d635cef | ||
|
|
4c259c1eef | ||
|
|
5b4ede5e2f | ||
|
|
d0ab3dda78 | ||
|
|
d9cf51b4bb | ||
|
|
aa17f24220 | ||
|
|
cf60edf7d4 | ||
|
|
ffbc243194 | ||
|
|
b6b07cf30c | ||
|
|
495a6b22bd | ||
|
|
0acaffbdfa | ||
|
|
6043bc4517 | ||
|
|
e6ed066e3f | ||
|
|
ee4e8655b8 | ||
|
|
37970d2be6 | ||
|
|
1376788016 | ||
|
|
4cad86cf85 | ||
|
|
6304116edb | ||
|
|
834ff8fa63 | ||
|
|
1f428a535e | ||
|
|
0c40966970 | ||
|
|
9da071fe9b | ||
|
|
892a04f289 | ||
|
|
27cc9727f1 | ||
|
|
f0738d451b | ||
|
|
9e6a8daf2c | ||
|
|
bfacfec765 | ||
|
|
0bae5bf32b | ||
|
|
22b09d16d0 | ||
|
|
9c867e106e | ||
|
|
304f28a3c1 | ||
|
|
d65d3793de | ||
|
|
3638d87bd2 | ||
|
|
b97a92860d | ||
|
|
7c86a5eeb3 | ||
|
|
d23dbaaf69 | ||
|
|
e6ffc371e1 | ||
|
|
3177c6eaa3 | ||
|
|
acd2f0519d | ||
|
|
18ec100c33 | ||
|
|
fa55fce76e | ||
|
|
f47d5e347d | ||
|
|
7488a8b597 | ||
|
|
2e3ac154be | ||
|
|
2472640755 | ||
|
|
7b685d6cad | ||
|
|
17f6f4e616 | ||
|
|
48cfc15cfb | ||
|
|
bb9b779cee | ||
|
|
af63ce67ae | ||
|
|
5cc4871ec4 | ||
|
|
c8cfe669b8 | ||
|
|
8b74d6d759 | ||
|
|
a9227768de | ||
|
|
d966e1d4de | ||
|
|
ceb2146c1b | ||
|
|
8d006d8c74 | ||
|
|
777304f259 | ||
|
|
12433f7c23 | ||
|
|
44b53da345 | ||
|
|
ab45fc144e | ||
|
|
e99e9e0708 | ||
|
|
467404bfc8 | ||
|
|
ce50fa2a62 | ||
|
|
10a011d842 | ||
|
|
5352410d0c | ||
|
|
c5d155396a | ||
|
|
93187099d3 | ||
|
|
aa24b1dce5 | ||
|
|
eb3ede9593 | ||
|
|
d7fecfbd0b | ||
|
|
b065b4ff21 | ||
|
|
87370d24be | ||
|
|
8f8b9988ad | ||
|
|
f8ccf4f5d8 | ||
|
|
25d8b86efd | ||
|
|
0cd3e937d8 | ||
|
|
89bb9c215e | ||
|
|
2d18686ce7 | ||
|
|
1d999d4910 | ||
|
|
7dfaa7579a | ||
|
|
08cb079e97 | ||
|
|
450aa83592 | ||
|
|
0614c76e92 | ||
|
|
97e338f9d4 | ||
|
|
636f018daa | ||
|
|
c8d639024a | ||
|
|
6be2ee626a | ||
|
|
f7fc1967a5 | ||
|
|
aedb8a765b | ||
|
|
cf58bd15c3 | ||
|
|
34f4f68524 | ||
|
|
09b8144080 | ||
|
|
f1e6fb4ce7 | ||
|
|
4167819e7a | ||
|
|
5bd3a463f0 | ||
|
|
79c447b4c6 | ||
|
|
540304f947 | ||
|
|
75d8f7331b | ||
|
|
b2509e9e53 | ||
|
|
7862f44653 | ||
|
|
962dd0c1bb | ||
|
|
5d5f7c7f5c | ||
|
|
6aaf838451 | ||
|
|
ad3bd312e9 | ||
|
|
5fa9939696 | ||
|
|
4956bb0e9c | ||
|
|
008027db0e | ||
|
|
aec5e3473e | ||
|
|
95c8fde72f | ||
|
|
0f32968fae | ||
|
|
ae79e9fea1 |
No files matched your search
@@ -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
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
+1
-2
@@ -1,3 +1,2 @@
|
|||||||
public/env.sample.js
|
public/env.sample.js
|
||||||
public/workbox-*.js
|
.pnpm-store
|
||||||
public/workbox-*.js.map
|
|
||||||
+29
-12
@@ -19,6 +19,13 @@ get:
|
|||||||
path: odit-git-bot
|
path: odit-git-bot
|
||||||
name: sshkey
|
name: sshkey
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: secret
|
||||||
|
name: npm_url
|
||||||
|
get:
|
||||||
|
path: odit-npm-cache
|
||||||
|
name: url
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: kubernetes
|
type: kubernetes
|
||||||
@@ -27,10 +34,14 @@ 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:19.7.0-alpine3.16
|
||||||
commands:
|
commands:
|
||||||
- yarn
|
- npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8
|
||||||
- yarn licenses:export
|
- pnpm i
|
||||||
|
- pnpm licenses:export
|
||||||
|
environment:
|
||||||
|
NPM_REGISTRY_URL:
|
||||||
|
from_secret: npm_url
|
||||||
- name: push new licenses file to repo
|
- name: push new licenses file to repo
|
||||||
depends_on: ["run full license export"]
|
depends_on: ["run full license export"]
|
||||||
image: appleboy/drone-git-push
|
image: appleboy/drone-git-push
|
||||||
@@ -43,18 +54,21 @@ steps:
|
|||||||
ssh_key:
|
ssh_key:
|
||||||
from_secret: git_ssh
|
from_secret: git_ssh
|
||||||
- name: build dev
|
- name: build dev
|
||||||
image: plugins/docker
|
depends_on: ["clone"]
|
||||||
depends_on: [clone]
|
image: registry.odit.services/library/drone-kaniko
|
||||||
settings:
|
settings:
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
password:
|
password:
|
||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
repo: registry.odit.services/lfk/frontend
|
build_args:
|
||||||
|
- NPM_REGISTRY_URL:
|
||||||
|
from_secret: npm_url
|
||||||
|
repo: lfk/frontend
|
||||||
tags:
|
tags:
|
||||||
- dev
|
- dev
|
||||||
|
cache: true
|
||||||
registry: registry.odit.services
|
registry: registry.odit.services
|
||||||
mtu: 1000
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
- dev
|
- dev
|
||||||
@@ -67,18 +81,21 @@ type: kubernetes
|
|||||||
name: build:tags
|
name: build:tags
|
||||||
steps:
|
steps:
|
||||||
- name: build $DRONE_TAG
|
- name: build $DRONE_TAG
|
||||||
image: plugins/docker
|
depends_on: ["clone"]
|
||||||
depends_on: [clone]
|
image: registry.odit.services/library/drone-kaniko
|
||||||
settings:
|
settings:
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
password:
|
password:
|
||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
repo: registry.odit.services/lfk/frontend
|
build_args:
|
||||||
|
- NPM_REGISTRY_URL:
|
||||||
|
from_secret: npm_url
|
||||||
|
repo: lfk/frontend
|
||||||
tags:
|
tags:
|
||||||
- '${DRONE_TAG}'
|
- "${DRONE_TAG}"
|
||||||
|
cache: true
|
||||||
registry: registry.odit.services
|
registry: registry.odit.services
|
||||||
mtu: 1000
|
|
||||||
trigger:
|
trigger:
|
||||||
event:
|
event:
|
||||||
- tag
|
- tag
|
||||||
+2
-7
@@ -1,11 +1,6 @@
|
|||||||
node_modules
|
node_modules
|
||||||
build
|
|
||||||
package-lock.json
|
|
||||||
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
|
||||||
|
.pnpm-store
|
||||||
Vendored
+2
-1
@@ -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"
|
||||||
|
|||||||
Vendored
+2
-1
@@ -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,
|
||||||
}
|
}
|
||||||
+411
-1
@@ -2,8 +2,418 @@
|
|||||||
|
|
||||||
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.17.3](https://git.odit.services/lfk/frontend/compare/0.17.2...0.17.3)
|
||||||
|
|
||||||
|
- dependency fixes [`3ea7a01`](https://git.odit.services/lfk/frontend/commit/3ea7a015a9beba3c2e4d3eb966f24ff6d4ac786e)
|
||||||
|
- set pnpm to @7 [`4432941`](https://git.odit.services/lfk/frontend/commit/44329413ed2ca23f74e86db041b2c25b2b1c2a2b)
|
||||||
|
|
||||||
|
#### [0.17.2](https://git.odit.services/lfk/frontend/compare/0.17.1...0.17.2)
|
||||||
|
|
||||||
|
> 15 March 2023
|
||||||
|
|
||||||
|
- new license file version [CI SKIP] [`00359d2`](https://git.odit.services/lfk/frontend/commit/00359d25c1bd3efdd6365bf284b3c07634049399)
|
||||||
|
- 🚀RELEASE v0.17.2 [`46db68a`](https://git.odit.services/lfk/frontend/commit/46db68ab229dc740dfff8835ef916f2c2e629b27)
|
||||||
|
- improved ThFilterGroup style [`f917018`](https://git.odit.services/lfk/frontend/commit/f917018fd92a8a5b034f735ac8b6e41995044317)
|
||||||
|
|
||||||
|
#### [0.17.1](https://git.odit.services/lfk/frontend/compare/0.17.0...0.17.1)
|
||||||
|
|
||||||
|
> 15 March 2023
|
||||||
|
|
||||||
|
- Revert "package dependency fixes, bumps, lockfile update" [`d8a3063`](https://git.odit.services/lfk/frontend/commit/d8a30637351e164599e07a6473d9a1d2b08d245d)
|
||||||
|
- 🚀RELEASE v0.17.1 [`7b420c4`](https://git.odit.services/lfk/frontend/commit/7b420c430d27bf0fc85a4297780164a593fc1be3)
|
||||||
|
|
||||||
|
#### [0.17.0](https://git.odit.services/lfk/frontend/compare/0.16.5...0.17.0)
|
||||||
|
|
||||||
|
> 15 March 2023
|
||||||
|
|
||||||
|
- new license file version [CI SKIP] [`61328d2`](https://git.odit.services/lfk/frontend/commit/61328d20ed2cfd1df7d3c32767f9c64154879d6d)
|
||||||
|
- wip: pnpm + node version [`732b2f0`](https://git.odit.services/lfk/frontend/commit/732b2f061e465bd08cf34c58d8cd6b021ba25dce)
|
||||||
|
- package dependency fixes, bumps, lockfile update [`2c73b98`](https://git.odit.services/lfk/frontend/commit/2c73b9862d401dac15021eed3f7847d46132a8ed)
|
||||||
|
- Fixed runners not showing up [`75bc89c`](https://git.odit.services/lfk/frontend/commit/75bc89ca3020c48f490c7602374616bd9461e78f)
|
||||||
|
- add ThFilterRunner [`3a3e2f7`](https://git.odit.services/lfk/frontend/commit/3a3e2f71575d3a0e39a5e13b05cff932b8683ac9)
|
||||||
|
- fix styling for table filters th border [`bea57aa`](https://git.odit.services/lfk/frontend/commit/bea57aa03acaaaa4b1860b30228dd5d1298317f8)
|
||||||
|
- You can now create cards from runners by searching via #runnerid [`e8a0ad6`](https://git.odit.services/lfk/frontend/commit/e8a0ad6647ab39252865f62b755f27c34ac2d243)
|
||||||
|
- remodelled for early return [`b869b5f`](https://git.odit.services/lfk/frontend/commit/b869b5fd2a01955fb21f936fa38eb5a9648e7de3)
|
||||||
|
- 🚀RELEASE v0.17.0 [`6491af1`](https://git.odit.services/lfk/frontend/commit/6491af19e375cbeba7ddd94e463b4dfe308a70a8)
|
||||||
|
- Wow this api is fun [`32a9074`](https://git.odit.services/lfk/frontend/commit/32a9074963cce3328f14b1f981ddd5ee49df0008)
|
||||||
|
- Fixed double space in label [`92b89cc`](https://git.odit.services/lfk/frontend/commit/92b89cc4d88c9d5625c2ddf7c81c98494f7f5271)
|
||||||
|
- UsersOverview: drop pfp [`30991d5`](https://git.odit.services/lfk/frontend/commit/30991d5364a09d517b2115a7e9ea3fbf1fe2e57d)
|
||||||
|
- Switched license generation to cache registry and pnpm [`0a6d92a`](https://git.odit.services/lfk/frontend/commit/0a6d92a1f3c5562f11562c433b3a04e3eaae3da4)
|
||||||
|
- Pinned pnpm in dockerfile, thx @philipp [`3a576d1`](https://git.odit.services/lfk/frontend/commit/3a576d1073ee503b68100e01054a1756bab62805)
|
||||||
|
- Pinned ci node version [`b30b98b`](https://git.odit.services/lfk/frontend/commit/b30b98b521eda2bc7fc055097546f716e90d92ef)
|
||||||
|
- Fixed pnpm being called without being installed [`43d82a2`](https://git.odit.services/lfk/frontend/commit/43d82a2af04af49c2169f78a0d0f27ef7e4d7558)
|
||||||
|
- Merge pull request 'bugfix/162-create_card_modal' (#163) from bugfix/162-create_card_modal into dev [`6a4495b`](https://git.odit.services/lfk/frontend/commit/6a4495b8131a31cd48a608c2275e80494d0a0fb4)
|
||||||
|
- Removed unused log [`268b1b1`](https://git.odit.services/lfk/frontend/commit/268b1b1d9830de196d1d95345d7a2467bbf19eb6)
|
||||||
|
- Merge pull request 'filter by runner full names + "#<ID>"' (#160) from feature/159-cardsoverview-filter-for-runner-full-names-and-id into dev [`0625937`](https://git.odit.services/lfk/frontend/commit/0625937068f0786078ffd29b9c8bb54949350b6c)
|
||||||
|
- UsersOverview: change profilepic scaling [`5cc8b08`](https://git.odit.services/lfk/frontend/commit/5cc8b0811cf290f97a4399b23c5ea4d961a5a91c)
|
||||||
|
|
||||||
|
#### [0.16.5](https://git.odit.services/lfk/frontend/compare/0.16.4...0.16.5)
|
||||||
|
|
||||||
|
> 14 March 2023
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.16.5 [`3680533`](https://git.odit.services/lfk/frontend/commit/3680533eefef042fc77246dd3d374aafe10c428f)
|
||||||
|
- new license file version [CI SKIP] [`405dfa0`](https://git.odit.services/lfk/frontend/commit/405dfa0c34ba87fc450c22e0e9974f92c4cdeffe)
|
||||||
|
|
||||||
|
#### [0.16.4](https://git.odit.services/lfk/frontend/compare/0.16.3...0.16.4)
|
||||||
|
|
||||||
|
> 14 March 2023
|
||||||
|
|
||||||
|
- fix: OrgDetail: clicking on address will toggle selfservice [`#158`](https://git.odit.services/lfk/frontend/issues/158)
|
||||||
|
- 🚀RELEASE v0.16.4 [`5c2d154`](https://git.odit.services/lfk/frontend/commit/5c2d154ad180ce7916605871c63e2f5ac4428250)
|
||||||
|
|
||||||
|
#### [0.16.3](https://git.odit.services/lfk/frontend/compare/0.16.2...0.16.3)
|
||||||
|
|
||||||
|
> 23 February 2023
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.16.3 [`f9cfd6b`](https://git.odit.services/lfk/frontend/commit/f9cfd6bd063b01a584774854d8fb5eab96f99528)
|
||||||
|
- Bumped vite build targets [`5fe4763`](https://git.odit.services/lfk/frontend/commit/5fe47634e8980e77b65c05f213c475cf49273609)
|
||||||
|
- new license file version [CI SKIP] [`a659091`](https://git.odit.services/lfk/frontend/commit/a6590910cfdc5e91fba91c1bc9237e407ef15fd2)
|
||||||
|
- Merge pull request 'feature/156-pdf_names' (#157) from feature/156-pdf_names into dev [`ad454c3`](https://git.odit.services/lfk/frontend/commit/ad454c386cbf11abc59d41d269d1a0ef7442c9ed)
|
||||||
|
- Added ids for generated pdfs [`0b2c296`](https://git.odit.services/lfk/frontend/commit/0b2c296de069a4ef302c5535de01bc18236675bc)
|
||||||
|
|
||||||
|
#### [0.16.2](https://git.odit.services/lfk/frontend/compare/0.16.1...0.16.2)
|
||||||
|
|
||||||
|
> 23 February 2023
|
||||||
|
|
||||||
|
- Fixed scanmodal [`#154`](https://git.odit.services/lfk/frontend/issues/154)
|
||||||
|
- 🚀RELEASE v0.16.2 [`0e85940`](https://git.odit.services/lfk/frontend/commit/0e85940cba292cbccd1ec038aa24f4a719382c19)
|
||||||
|
- Merge pull request 'feature/147-cardoverview_performance' (#153) from feature/147-cardoverview_performance into dev [`8d479c3`](https://git.odit.services/lfk/frontend/commit/8d479c32f82938904aee6a10deb80fea85487e4b)
|
||||||
|
- Merge pull request 'Fixed scanmodal' (#155) from bugfix/154-scan_select_runner_by_id into dev [`549785c`](https://git.odit.services/lfk/frontend/commit/549785cf7d1c9edc1be37dc745b97096232a08ca)
|
||||||
|
- i18n [`ca6da15`](https://git.odit.services/lfk/frontend/commit/ca6da15ef761184a55b18d56f749f660a32cbb83)
|
||||||
|
- Bsic datatable conversion [`757655e`](https://git.odit.services/lfk/frontend/commit/757655ea63b3667bc4612ae1595eb52910b61137)
|
||||||
|
- 1st datatable try with @vincjo/datatables [`81b8fbf`](https://git.odit.services/lfk/frontend/commit/81b8fbf4e341e6f2998a6e9e2053972c5c225021)
|
||||||
|
- Dasboard Cards redesign [`eb1c17e`](https://git.odit.services/lfk/frontend/commit/eb1c17e3ac7e8f5e7310a90421fc9db3ed15c497)
|
||||||
|
- set .phone to null if empty [`da6dd55`](https://git.odit.services/lfk/frontend/commit/da6dd55d139a672fa50204eabdca67d9740614a0)
|
||||||
|
- add group filtering to table [`14d64b6`](https://git.odit.services/lfk/frontend/commit/14d64b6070d98e6368da5709e9ff8221e8a621c7)
|
||||||
|
- formatting [`24d0747`](https://git.odit.services/lfk/frontend/commit/24d074752f1c5dc1a14b075ac14b448d7e129376)
|
||||||
|
- RunnersOverview loading fix [`2e075ea`](https://git.odit.services/lfk/frontend/commit/2e075eafab5c4d78fd9aa9d66834b477b2685bfc)
|
||||||
|
- Added old formatting for runner and status [`df63c23`](https://git.odit.services/lfk/frontend/commit/df63c2388da359dec9ed9968bc9f970be7092a45)
|
||||||
|
- Added custom status filter [`f0a2b28`](https://git.odit.services/lfk/frontend/commit/f0a2b2859fa18426a454b7d9d6dd22dfdfe7ce27)
|
||||||
|
- Basic checkbox fix [`1337676`](https://git.odit.services/lfk/frontend/commit/1337676e0894c46da0b6dcb7553e5ea8f88d0c14)
|
||||||
|
- Fixed all filter [`8dfa19f`](https://git.odit.services/lfk/frontend/commit/8dfa19fa0f9897c61342ece956df88731c7aa861)
|
||||||
|
- improved runner search [`1b0cd5b`](https://git.odit.services/lfk/frontend/commit/1b0cd5b90bcceb92627c6b7cdcdd7792ed81b50f)
|
||||||
|
- set table-layout:fixed + display when loaded [`65e8998`](https://git.odit.services/lfk/frontend/commit/65e89988943807c1606a8b6aea49564b13d52537)
|
||||||
|
- Trigger edit modal [`32ddb66`](https://git.odit.services/lfk/frontend/commit/32ddb66fc8d8cd689f1104759812f4cee4b7a613)
|
||||||
|
- cleaned up table search [`08047a9`](https://git.odit.services/lfk/frontend/commit/08047a93073c32f5dd7a8e958400ae8a5b7f4035)
|
||||||
|
- Fixed edit update bug [`0feee0a`](https://git.odit.services/lfk/frontend/commit/0feee0ae2fb6d8dba0b6fd72cedc0712dc749511)
|
||||||
|
- fix: z-index on action buttons [`224034d`](https://git.odit.services/lfk/frontend/commit/224034dcc6263d3b0a8ea20045e435142d8ed2af)
|
||||||
|
- rename: ThFilterGroup -> ThFilterStatus [`2a6a399`](https://git.odit.services/lfk/frontend/commit/2a6a39916a03c0466e63354e9f5ad7924cb59b6b)
|
||||||
|
- new license file version [CI SKIP] [`0e5490f`](https://git.odit.services/lfk/frontend/commit/0e5490f1c84217a5a6d5c8745c4667b32ca65e1a)
|
||||||
|
- new license file version [CI SKIP] [`026d3d4`](https://git.odit.services/lfk/frontend/commit/026d3d41c1b976a4dc7c733576a6a9e8d4b13b78)
|
||||||
|
- Updated breakpoints [`452d010`](https://git.odit.services/lfk/frontend/commit/452d0101838d72bff7d588a953faae028e2ff819)
|
||||||
|
- Tailwind bump [`a101873`](https://git.odit.services/lfk/frontend/commit/a101873eb0946b284a11a5081642711f5087da14)
|
||||||
|
- Fixed checkbox show [`0900c26`](https://git.odit.services/lfk/frontend/commit/0900c2691e4cfe5046e8ae186c8ac8884c90abd6)
|
||||||
|
- Removed unused console log [`aafc4c8`](https://git.odit.services/lfk/frontend/commit/aafc4c8d62a7a0a493c8bd60149f90c842534bdd)
|
||||||
|
- i18n import [`6fe134a`](https://git.odit.services/lfk/frontend/commit/6fe134afc8bfef4e7470b7e53b9312b172a7322b)
|
||||||
|
- Merge pull request 'fix: RunnerDetail: set .phone to null if empty' (#152) from bugfix/151-runnerdetail--cannot-unset-phone-number into dev [`329c1cc`](https://git.odit.services/lfk/frontend/commit/329c1cc037a43c818ba3b6c72581d29586d76232)
|
||||||
|
- Merge pull request 'feature/146-runner-table-performance-data-table' (#150) from feature/146-runner-table-performance-data-table into dev [`b82d638`](https://git.odit.services/lfk/frontend/commit/b82d638de1aa1f72aada212cf3e4147d808b4fcf)
|
||||||
|
- Merge pull request 'feature/148-dashboard_statscards' (#149) from feature/148-dashboard_statscards into dev [`fd1a06b`](https://git.odit.services/lfk/frontend/commit/fd1a06b3595b3713ad474e623c74105125602d46)
|
||||||
|
- Fixed top checkbox state [`3d2acb6`](https://git.odit.services/lfk/frontend/commit/3d2acb692a28c116790248679e238fb562b24ac5)
|
||||||
|
|
||||||
|
#### [0.16.1](https://git.odit.services/lfk/frontend/compare/0.16.0...0.16.1)
|
||||||
|
|
||||||
|
> 15 February 2023
|
||||||
|
|
||||||
|
- fix: donor detail: sponsorings: unset middlename will show as "null" [`#145`](https://git.odit.services/lfk/frontend/issues/145)
|
||||||
|
- 🚀RELEASE v0.16.1 [`4499480`](https://git.odit.services/lfk/frontend/commit/449948050b8673d43a8dfbb225c3198e4bbb3c7b)
|
||||||
|
|
||||||
|
#### [0.16.0](https://git.odit.services/lfk/frontend/compare/0.15.6...0.16.0)
|
||||||
|
|
||||||
|
> 3 February 2023
|
||||||
|
|
||||||
|
- First page for statsclients [`f299617`](https://git.odit.services/lfk/frontend/commit/f299617c600d2bba7b4405c7c3acae9fd93aefa8)
|
||||||
|
- 🚀RELEASE v0.16.0 [`75684ef`](https://git.odit.services/lfk/frontend/commit/75684efa1ae0edb4b4d414757c5acf2a77c572e5)
|
||||||
|
- Basic statsclient detail [`0215860`](https://git.odit.services/lfk/frontend/commit/02158605be824e5ac21a6284731138190988c794)
|
||||||
|
- Updated Add modal [`f679330`](https://git.odit.services/lfk/frontend/commit/f679330466205e6480cd7f2b7c2b4fdc41c51525)
|
||||||
|
- Switched drone to kaniko [`1c98005`](https://git.odit.services/lfk/frontend/commit/1c980059cff5c87c452428b53513507c2339451f)
|
||||||
|
- Re-added copy modal [`fecb07e`](https://git.odit.services/lfk/frontend/commit/fecb07ee373dcaaeaea69fdf8d4c6ee2c257c89c)
|
||||||
|
- Added Statsclients to sidebar [`068076d`](https://git.odit.services/lfk/frontend/commit/068076dd47373c673a25e730cb8a57c686682810)
|
||||||
|
- Fixed imports and naming [`f3cc07c`](https://git.odit.services/lfk/frontend/commit/f3cc07c009ed0a34e61f1aad47a1a31778145439)
|
||||||
|
- new license file version [CI SKIP] [`2c4f27a`](https://git.odit.services/lfk/frontend/commit/2c4f27a943bb35be6728bb49bd5c2263cba78165)
|
||||||
|
- Merge pull request 'feature/143-beamershow_clients' (#144) from feature/143-beamershow_clients into dev [`53b7dec`](https://git.odit.services/lfk/frontend/commit/53b7dec7cd516c908d45591b855f4be09371f9b1)
|
||||||
|
- Updated deletion modal [`93fc7c2`](https://git.odit.services/lfk/frontend/commit/93fc7c2e83f78dd88f15d9246127bb9e69f1a8ee)
|
||||||
|
- Updated mounted variables [`674e6a9`](https://git.odit.services/lfk/frontend/commit/674e6a90ec23dde9377bea64c14a50e41ffa450d)
|
||||||
|
- Removed Key after creation [`e10c648`](https://git.odit.services/lfk/frontend/commit/e10c6480a504338b21e30fdf2577e5b6c3b635db)
|
||||||
|
- Updated docker base images [`9767553`](https://git.odit.services/lfk/frontend/commit/976755338b8621064f9a73147aa600af1f77cd51)
|
||||||
|
- Added translation [`96c55db`](https://git.odit.services/lfk/frontend/commit/96c55db63dbfed92b78ff0e7bdab7a8cce4d76e9)
|
||||||
|
- Pinned versions [`cff112d`](https://git.odit.services/lfk/frontend/commit/cff112d705a74a135286943298f3f344341325ac)
|
||||||
|
- Tailwind bump [`e0cbfb0`](https://git.odit.services/lfk/frontend/commit/e0cbfb000bee59a71e06bd58a9c7ef6a0fc7091d)
|
||||||
|
- Added missing translation [`19a333d`](https://git.odit.services/lfk/frontend/commit/19a333d7bda525fbcb3c68f3cbf85a4f925a9707)
|
||||||
|
- Bumped apiclient [`c28f1ee`](https://git.odit.services/lfk/frontend/commit/c28f1ee0bc4456595c21858f38e52ed6f16871c5)
|
||||||
|
- new license file version [CI SKIP] [`3a66f4c`](https://git.odit.services/lfk/frontend/commit/3a66f4c862db9f35c223cc7007b0560fef4e1d63)
|
||||||
|
- Bumped apiclient [`28cbc5b`](https://git.odit.services/lfk/frontend/commit/28cbc5b98ca09657100e1740b83aa2617243b26b)
|
||||||
|
- Ignore pnpm lock [`2d8c4c1`](https://git.odit.services/lfk/frontend/commit/2d8c4c1698a1675f618e85e678012f310f87c6ee)
|
||||||
|
|
||||||
|
#### [0.15.6](https://git.odit.services/lfk/frontend/compare/0.15.5...0.15.6)
|
||||||
|
|
||||||
|
> 19 July 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.15.6 [`9fc4ad6`](https://git.odit.services/lfk/frontend/commit/9fc4ad63c4f77b46d645e83c94b51747b91247b8)
|
||||||
|
- Fixed donations getting reduced to the first one on certificates [`2391668`](https://git.odit.services/lfk/frontend/commit/2391668a25a1e11a1409df572d77ad1635070fbc)
|
||||||
|
- new license file version [CI SKIP] [`97054a7`](https://git.odit.services/lfk/frontend/commit/97054a71c1ab8a045762a55148124965c6994373)
|
||||||
|
|
||||||
|
#### [0.15.5](https://git.odit.services/lfk/frontend/compare/0.15.4...0.15.5)
|
||||||
|
|
||||||
|
> 5 July 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.15.5 [`717d335`](https://git.odit.services/lfk/frontend/commit/717d33547c3378424dd720005da9952f8a753f1a)
|
||||||
|
- Merge pull request 'Fixed kilometer conversion' (#142) from bugfix/141-runner_kilometers into dev [`997be32`](https://git.odit.services/lfk/frontend/commit/997be32679dc38c9fb0e92b6ce011057b854d99d)
|
||||||
|
- Fixed kilometer conversion [`134f00c`](https://git.odit.services/lfk/frontend/commit/134f00c40e0c8252e7604a73151e8d6685b2c61d)
|
||||||
|
- new license file version [CI SKIP] [`e752ee1`](https://git.odit.services/lfk/frontend/commit/e752ee12d17a4423f4364f7766eafbe7d4cef2d1)
|
||||||
|
|
||||||
|
#### [0.15.4](https://git.odit.services/lfk/frontend/compare/0.15.3...0.15.4)
|
||||||
|
|
||||||
|
> 5 July 2021
|
||||||
|
|
||||||
|
- Merge pull request 'fix total donation sum in dashboard' (#140) from bugfix/139-total-donation-sum-is-wrong into dev [`#139`](https://git.odit.services/lfk/frontend/issues/139)
|
||||||
|
- 🚀RELEASE v0.15.4 [`cc4515f`](https://git.odit.services/lfk/frontend/commit/cc4515ff66b1c1de3747d0ee6cc465574accedb7)
|
||||||
|
- divide by 100 + toFixes(2) [`b246f2b`](https://git.odit.services/lfk/frontend/commit/b246f2b349b06d1adea318dfad58f97fb1a249bb)
|
||||||
|
|
||||||
|
#### [0.15.3](https://git.odit.services/lfk/frontend/compare/0.15.2...0.15.3)
|
||||||
|
|
||||||
|
> 16 April 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.15.3 [`76b69d8`](https://git.odit.services/lfk/frontend/commit/76b69d851aa590ecf8caac135b72962a72e83635)
|
||||||
|
- Small bugfix (null got displayed) 🛠 [`224f586`](https://git.odit.services/lfk/frontend/commit/224f5863683ae2543a4a435510ed2c558dc5d307)
|
||||||
|
|
||||||
|
#### [0.15.2](https://git.odit.services/lfk/frontend/compare/0.15.1...0.15.2)
|
||||||
|
|
||||||
|
> 16 April 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.15.2 [`9add6c8`](https://git.odit.services/lfk/frontend/commit/9add6c8ff1fbeed91fe97a7cf262921b716f4e3c)
|
||||||
|
- 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)
|
||||||
|
|
||||||
|
> 26 March 2021
|
||||||
|
|
||||||
|
- Added translations [`79c447b`](https://git.odit.services/lfk/frontend/commit/79c447b4c65e55ebb5af71fb0b09174c36e2cecf)
|
||||||
|
- Sorted translations 🌍 [`5bd3a46`](https://git.odit.services/lfk/frontend/commit/5bd3a463f00abaf2c98ab554f88e5542d01f364a)
|
||||||
|
- Reset can now only be triggered if pw is strong enoug [`75d8f73`](https://git.odit.services/lfk/frontend/commit/75d8f7331b6ae78f3979bb62148188a16f83cb8d)
|
||||||
|
- Module now exports functions that check if a password is strong enough and equal to a potential confirmation field [`b2509e9`](https://git.odit.services/lfk/frontend/commit/b2509e9e53ab6b51dfd55e26712e8928160cd64b)
|
||||||
|
- 🚀RELEASE v0.10.0 [`f7fc196`](https://git.odit.services/lfk/frontend/commit/f7fc1967a50f302af1d8b668628be2f4ab2975a3)
|
||||||
|
- Added more cirteria to the password strength component [`5fa9939`](https://git.odit.services/lfk/frontend/commit/5fa9939696a35d60d762feb0cebef61d31869218)
|
||||||
|
- Now using pw strength component [`6aaf838`](https://git.odit.services/lfk/frontend/commit/6aaf8384512185a3a319ce6b3e2505e910468e64)
|
||||||
|
- Added a password strength verification [`ad3bd31`](https://git.odit.services/lfk/frontend/commit/ad3bd312e9a5785f81029ea2b7e302ea1addd988)
|
||||||
|
- Implemented a custom password strength component [`4956bb0`](https://git.odit.services/lfk/frontend/commit/4956bb0e9c3c1d22d60e849aea5664e35330f897)
|
||||||
|
- User creation can now only be triggered if pw is strong enoug [`540304f`](https://git.odit.services/lfk/frontend/commit/540304f947f60a7072c592ca8088996ce7e95cb4)
|
||||||
|
- Now using pw strength component for user creation [`7862f44`](https://git.odit.services/lfk/frontend/commit/7862f446532903f1a2eac7b21d5c80c3245785e5)
|
||||||
|
- Added missing exports [`962dd0c`](https://git.odit.services/lfk/frontend/commit/962dd0c1bbc0df7f20bcec5b4247188c8935c87e)
|
||||||
|
- new license file version [CI SKIP] [`aedb8a7`](https://git.odit.services/lfk/frontend/commit/aedb8a765ba053545adbba9eb014b3bb0e5aac8c)
|
||||||
|
- Bumped lfk-client version 🔝 [`cf58bd1`](https://git.odit.services/lfk/frontend/commit/cf58bd15c3541c417ab2be83d96135e931a2b6f6)
|
||||||
|
- new license file version [CI SKIP] [`34f4f68`](https://git.odit.services/lfk/frontend/commit/34f4f68524918fd3d1963966a1e259d5b60efaca)
|
||||||
|
- Merge pull request 'Implemented password strength test feature/106-password_strength' (#115) from feature/106-password_strength into dev [`09b8144`](https://git.odit.services/lfk/frontend/commit/09b81440804cf98303fcb723a9717d6d0f432da8)
|
||||||
|
- Formatting🛠 [`4167819`](https://git.odit.services/lfk/frontend/commit/4167819e7a864d3b1dd95ba48ab1525a454f7f30)
|
||||||
|
- Now using pw strength component for reset [`5d5f7c7`](https://git.odit.services/lfk/frontend/commit/5d5f7c7f5c6a69146f41996f4facfeff95791be0)
|
||||||
|
|
||||||
#### [0.9.1](https://git.odit.services/lfk/frontend/compare/0.9.0...0.9.1)
|
#### [0.9.1](https://git.odit.services/lfk/frontend/compare/0.9.0...0.9.1)
|
||||||
|
|
||||||
|
> 26 March 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.9.1 [`2ca63fd`](https://git.odit.services/lfk/frontend/commit/2ca63fd1f675f0da2b18ba43095074dd4823991d)
|
||||||
- Merge pull request 'Org selfservice Link feature/112-org_registration_links' (#114) from feature/112-org_registration_links into dev [`a5d25e7`](https://git.odit.services/lfk/frontend/commit/a5d25e7d92c7c37e90dbb4ba74b787873f920c6b)
|
- Merge pull request 'Org selfservice Link feature/112-org_registration_links' (#114) from feature/112-org_registration_links into dev [`a5d25e7`](https://git.odit.services/lfk/frontend/commit/a5d25e7d92c7c37e90dbb4ba74b787873f920c6b)
|
||||||
- Added checkbox to enable registration [`f9fe793`](https://git.odit.services/lfk/frontend/commit/f9fe79357317653b46c09eb95b0db13845cddcf9)
|
- Added checkbox to enable registration [`f9fe793`](https://git.odit.services/lfk/frontend/commit/f9fe79357317653b46c09eb95b0db13845cddcf9)
|
||||||
- Sorted translations [`c074c12`](https://git.odit.services/lfk/frontend/commit/c074c12be75f285612f7a732c106404d9fb4538a)
|
- Sorted translations [`c074c12`](https://git.odit.services/lfk/frontend/commit/c074c12be75f285612f7a732c106404d9fb4538a)
|
||||||
@@ -919,7 +1329,7 @@ All notable changes to this project will be documented in this file. Dates are d
|
|||||||
- init [`32357ec`](https://git.odit.services/lfk/frontend/commit/32357ece0a7195ea1135c9c3e4c6c84323f95b4d)
|
- init [`32357ec`](https://git.odit.services/lfk/frontend/commit/32357ece0a7195ea1135c9c3e4c6c84323f95b4d)
|
||||||
- tmp [`1b7173c`](https://git.odit.services/lfk/frontend/commit/1b7173cda9134ee8058a00bdc030defa80d46bfc)
|
- tmp [`1b7173c`](https://git.odit.services/lfk/frontend/commit/1b7173cda9134ee8058a00bdc030defa80d46bfc)
|
||||||
- Login - move to env.js import [`8ef0b21`](https://git.odit.services/lfk/frontend/commit/8ef0b21819309752c573d0485f6514152fb684e6)
|
- Login - move to env.js import [`8ef0b21`](https://git.odit.services/lfk/frontend/commit/8ef0b21819309752c573d0485f6514152fb684e6)
|
||||||
- initial commit [`4bb3bae`](https://git.odit.services/lfk/frontend/commit/4bb3bae4e6fc89c35a8a2b36b7cd6e6d47958eae)
|
- initial commit [`4bb3bae`](https://git.odit.services/lfk/frontend/commit/4bb3bae4e6fc89c35a8a2b36b7cd6e6d47958eae)
|
||||||
- Initial license export [`4c96b9a`](https://git.odit.services/lfk/frontend/commit/4c96b9a3e04dbb7c021c71aa8828a29248509fbe)
|
- Initial license export [`4c96b9a`](https://git.odit.services/lfk/frontend/commit/4c96b9a3e04dbb7c021c71aa8828a29248509fbe)
|
||||||
- 🚚 move to tinro svelte router [`a50ea15`](https://git.odit.services/lfk/frontend/commit/a50ea15b38023b867a9f7757e973184cbcdd2457)
|
- 🚚 move to tinro svelte router [`a50ea15`](https://git.odit.services/lfk/frontend/commit/a50ea15b38023b867a9f7757e973184cbcdd2457)
|
||||||
- new Dashboard [`7270ce9`](https://git.odit.services/lfk/frontend/commit/7270ce9d32869abd4f6ac65ab7c2c87363633cbe)
|
- new Dashboard [`7270ce9`](https://git.odit.services/lfk/frontend/commit/7270ce9d32869abd4f6ac65ab7c2c87363633cbe)
|
||||||
|
|||||||
+10
-13
@@ -1,18 +1,15 @@
|
|||||||
FROM node:15.5.1-alpine3.12
|
FROM registry.odit.services/hub/library/node:19.7.0-alpine3.16 as build
|
||||||
|
ARG NPM_REGISTRY_URL=https://registry.npmjs.org
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN npm i -g pnpm
|
|
||||||
COPY package.json ./
|
COPY package.json pnpm-lock.yaml *.config.js *.config.cjs index.html ./
|
||||||
RUN pnpm i
|
RUN npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8 && pnpm i
|
||||||
COPY package.json *.config.js workbox-config.js template-copy.js index.template.html s-config.template.js ./
|
|
||||||
COPY src ./src
|
COPY src ./src
|
||||||
COPY public ./public
|
COPY public ./public
|
||||||
RUN pnpm run build
|
RUN pnpm build
|
||||||
|
|
||||||
# final image
|
# final image
|
||||||
FROM alpine
|
FROM registry.odit.services/library/nginx-brotli:3.15 as final
|
||||||
COPY --from=0 /app/build /app
|
COPY --from=build /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
|
||||||
@@ -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
|
||||||
|
```
|
||||||
@@ -10,14 +10,13 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="description" content="Lauf Für Kaya! - Admin" />
|
<meta name="description" content="Lauf Für Kaya! - Admin" />
|
||||||
<title>Lauf für Kaya! - Admin</title>
|
<title>Lauf für Kaya! - Admin</title>
|
||||||
__TAILWIND_INSERT__
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.9.1-RELEASE_INFO</span>
|
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.17.3-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>
|
||||||
+14
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+63
-61
@@ -1,61 +1,63 @@
|
|||||||
{
|
{
|
||||||
"name": "@odit/lfk-frontend",
|
"name": "@odit/lfk-frontend",
|
||||||
"version": "0.9.1",
|
"version": "0.17.3",
|
||||||
"scripts": {
|
"type": "module",
|
||||||
"i18n-order": "node order.js",
|
"scripts": {
|
||||||
"dev:all": "yarn prebuild && snowpack dev",
|
"i18n-order": "node order.js",
|
||||||
"dev": "cross-env NODE_ENV_ODIT=development_fast node template-copy.js && yarn build:sw && snowpack dev",
|
"dev": "vite",
|
||||||
"build": "yarn prebuild && snowpack build",
|
"build": "vite build",
|
||||||
"prebuild": "cross-env NODE_ENV_ODIT=production node template-copy.js && yarn build:sw",
|
"release": "release-it",
|
||||||
"build:sw": "workbox generateSW workbox-config.js",
|
"licenses:export": "license-exporter --json -o public"
|
||||||
"release": "release-it",
|
},
|
||||||
"licenses:export": "license-exporter --json -o public"
|
"license": "CC-BY-NC-SA-4.0",
|
||||||
},
|
"devDependencies": {
|
||||||
"license": "CC-BY-NC-SA-4.0",
|
"@odit/license-exporter": "0.0.12",
|
||||||
"dependencies": {
|
"@sveltejs/vite-plugin-svelte": "2.0.4",
|
||||||
"@odit/lfk-client-js": "0.7.0",
|
"@types/html-minifier": "4.0.2",
|
||||||
"csvtojson": "^2.0.10",
|
"auto-changelog": "2.4.0",
|
||||||
"gridjs": "3.3.0",
|
"autoprefixer": "10.4.14",
|
||||||
"localforage": "1.9.0",
|
"html-minifier": "4.0.0",
|
||||||
"marked": "^2.0.1",
|
"postcss": "8.4.21",
|
||||||
"svelte-focus-trap": "1.0.1",
|
"release-it": "15.10.1",
|
||||||
"svelte-i18n": "3.3.7",
|
"svelte-select": "3.17.0",
|
||||||
"svelte-select": "^3.17.0",
|
"tailwindcss": "3.3.1",
|
||||||
"tailwindcss": "2.0.3",
|
"vite": "4.2.1"
|
||||||
"tinro": "0.6.1",
|
},
|
||||||
"toastify-js": "1.9.3",
|
"release-it": {
|
||||||
"validator": "13.5.2",
|
"git": {
|
||||||
"xlsx": "^0.16.9"
|
"commit": true,
|
||||||
},
|
"requireCleanWorkingDir": false,
|
||||||
"devDependencies": {
|
"commitMessage": "🚀RELEASE v${version}",
|
||||||
"@odit/license-exporter": "^0.0.11",
|
"push": false,
|
||||||
"@snowpack/plugin-svelte": "3.5.2",
|
"tag": true,
|
||||||
"auto-changelog": "^2.2.1",
|
"tagName": null,
|
||||||
"autoprefixer": "10.2.5",
|
"tagAnnotation": "v${version}"
|
||||||
"cross-env": "^7.0.3",
|
},
|
||||||
"postcss": "8.2.8",
|
"npm": {
|
||||||
"postcss-load-config": "3.0.1",
|
"publish": false
|
||||||
"release-it": "^14.4.1",
|
},
|
||||||
"snowpack": "3.0.13",
|
"hooks": {
|
||||||
"svelte": "3.35.0",
|
"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"
|
||||||
"svelte-preprocess": "4.6.9",
|
}
|
||||||
"workbox-cli": "6.1.2"
|
},
|
||||||
},
|
"dependencies": {
|
||||||
"release-it": {
|
"@odit/lfk-client-js": "0.14.3",
|
||||||
"git": {
|
"@paralleldrive/cuid2": "^2.2.0",
|
||||||
"commit": true,
|
"@tanstack/svelte-table": "^8.8.5",
|
||||||
"requireCleanWorkingDir": false,
|
"@tanstack/table-core": "^8.8.5",
|
||||||
"commitMessage": "🚀RELEASE v${version}",
|
"check-password-strength": "2.0.7",
|
||||||
"push": false,
|
"csvtojson": "2.0.10",
|
||||||
"tag": true,
|
"gridjs": "3.4.0",
|
||||||
"tagName": null,
|
"localforage": "1.10.0",
|
||||||
"tagAnnotation": "v${version}"
|
"marked": "2.0.3",
|
||||||
},
|
"svelte": "3.58.0",
|
||||||
"npm": {
|
"svelte-i18n": "3.6.0",
|
||||||
"publish": false
|
"tinro": "0.6.12",
|
||||||
},
|
"toastify-js": "1.12.0",
|
||||||
"hooks": {
|
"validator": "13.9.0",
|
||||||
"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"
|
"xlsx": "0.18.5"
|
||||||
}
|
},
|
||||||
}
|
"volta": {
|
||||||
}
|
"node": "19.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+4040
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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',
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
[{"author":"ODIT.Services","repo":{"type":"git","url":"git+https://git.odit.services/lfk/lfk-client-js"},"description":"A lib to interact with https://git.odit.services/lfk/backend. Use this version for native JS applications.","name":"@odit/lfk-client-js","license":"CC-BY-NC-SA-4.0","version":"0.7.0","licensetext":"Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Creative\r\nCommons Corporation (\"Creative Commons\") is not a law firm and does not provide\r\nlegal services or legal advice. Distribution of Creative Commons public licenses\r\ndoes not create a lawyer-client or other relationship. Creative Commons makes\r\nits licenses and related information available on an \"as-is\" basis. Creative\r\nCommons gives no warranties regarding its licenses, any material licensed\r\nunder their terms and conditions, or any related information. Creative Commons\r\ndisclaims all liability for damages resulting from their use to the fullest\r\nextent possible.\r\n\r\nUsing Creative Commons Public Licenses\r\n\r\nCreative Commons public licenses provide a standard set of terms and conditions\r\nthat creators and other rights holders may use to share original works of\r\nauthorship and other material subject to copyright and certain other rights\r\nspecified in the public license below. The following considerations are for\r\ninformational purposes only, are not exhaustive, and do not form part of our\r\nlicenses.\r\n\r\nConsiderations for licensors: Our public licenses are intended for use by\r\nthose authorized to give the public permission to use material in ways otherwise\r\nrestricted by copyright and certain other rights. Our licenses are irrevocable.\r\nLicensors should read and understand the terms and conditions of the license\r\nthey choose before applying it. Licensors should also secure all rights necessary\r\nbefore applying our licenses so that the public can reuse the material as\r\nexpected. Licensors should clearly mark any material not subject to the license.\r\nThis includes other CC-licensed material, or material used under an exception\r\nor limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors\r\n\r\nConsiderations for the public: By using one of our public licenses, a licensor\r\ngrants the public permission to use the licensed material under specified\r\nterms and conditions. If the licensor's permission is not necessary for any\r\nreason–for example, because of any applicable exception or limitation to copyright–then\r\nthat use is not regulated by the license. Our licenses grant only permissions\r\nunder copyright and certain other rights that a licensor has authority to\r\ngrant. Use of the licensed material may still be restricted for other reasons,\r\nincluding because others have copyright or other rights in the material. A\r\nlicensor may make special requests, such as asking that all changes be marked\r\nor described. Although not required by our licenses, you are encouraged to\r\nrespect those requests where reasonable. More considerations for the public\r\n: wiki.creativecommons.org/Considerations_for_licensees\r\n\r\nCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public\r\nLicense\r\n\r\nBy exercising the Licensed Rights (defined below), You accept and agree to\r\nbe bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike\r\n4.0 International Public License (\"Public License\"). To the extent this Public\r\nLicense may be interpreted as a contract, You are granted the Licensed Rights\r\nin consideration of Your acceptance of these terms and conditions, and the\r\nLicensor grants You such rights in consideration of benefits the Licensor\r\nreceives from making the Licensed Material available under these terms and\r\nconditions.\r\n\r\nSection 1 – Definitions.\r\n\r\na. Adapted Material means material subject to Copyright and Similar Rights\r\nthat is derived from or based upon the Licensed Material and in which the\r\nLicensed Material is translated, altered, arranged, transformed, or otherwise\r\nmodified in a manner requiring permission under the Copyright and Similar\r\nRights held by the Licensor. For purposes of this Public License, where the\r\nLicensed Material is a musical work, performance, or sound recording, Adapted\r\nMaterial is always produced where the Licensed Material is synched in timed\r\nrelation with a moving image.\r\n\r\nb. Adapter's License means the license You apply to Your Copyright and Similar\r\nRights in Your contributions to Adapted Material in accordance with the terms\r\nand conditions of this Public License.\r\n\r\nc. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses,\r\napproved by Creative Commons as essentially the equivalent of this Public\r\nLicense.\r\n\r\nd. Copyright and Similar Rights means copyright and/or similar rights closely\r\nrelated to copLine truncated
|
[{"author":"Alexey Schebelev","repo":{"type":"git","url":"https://github.com/AlexxNB/tinro"},"description":"tinro is a tiny declarative router for Svelte","name":"tinro","license":"MIT","version":"0.6.12","licensetext":"MIT License\n\nCopyright (c) 2020 Alexey Schebelev\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"},{"author":"Varun A P","repo":{"type":"git","url":"https://github.com/apvarun/toastify-js"},"description":"Toastify is a lightweight, vanilla JS toast notification library.","name":"toastify-js","license":"MIT","version":"1.12.0","licensetext":"MIT License\n\nCopyright (c) 2018 apvarun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"},{"author":"Chris O'Hara <cohara87@gmail.com>","repo":{"type":"git","url":"https://github.com/validatorjs/validator.js"},"description":"String validation and sanitization","name":"validator","license":"MIT","version":"13.9.0","licensetext":"Copyright (c) 2018 Chris O'Hara <cohara87@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"},{"author":"sheetjs","repo":{"type":"git","url":"https://github.comSheetJS/sheetjs"},"description":"SheetJS Spreadsheet data parser and writer","name":"xlsx","license":"Apache-2.0","version":"0.16.9","licensetext":" Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" meansLine truncated
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
const sveltePreprocess = require('svelte-preprocess');
|
|
||||||
const preprocess = sveltePreprocess(__insert__);
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
preprocess
|
|
||||||
};
|
|
||||||
@@ -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 }
|
|
||||||
};
|
|
||||||
+231
-224
@@ -1,224 +1,231 @@
|
|||||||
<script>
|
<script>
|
||||||
import "./TailwindStyles.svelte";
|
import "toastify-js/src/toastify.css";
|
||||||
import "toastify-js/src/toastify.css";
|
import "gridjs/dist/theme/mermaid.css";
|
||||||
import "gridjs/dist/theme/mermaid.css";
|
import { Route, router } from "tinro";
|
||||||
import { Route, router } from "tinro";
|
router.subscribe((routeInfo) => {
|
||||||
router.subscribe((routeInfo) => {
|
window.scrollTo(0, 0);
|
||||||
window.scrollTo(0, 0);
|
});
|
||||||
});
|
if (config.prefersHashRouting) {
|
||||||
if (config.prefersHashRouting) {
|
if (config.prefersHashRouting === true) {
|
||||||
if (config.prefersHashRouting === true) {
|
router.useHashNavigation();
|
||||||
router.useHashNavigation();
|
}
|
||||||
}
|
}
|
||||||
}
|
import localForage from "localforage";
|
||||||
import localForage from "localforage";
|
import { addMessages, init, getLocaleFromNavigator } from "svelte-i18n";
|
||||||
import { addMessages, init, getLocaleFromNavigator } from "svelte-i18n";
|
import en from "./locales/en.json";
|
||||||
import en from "./locales/en.json";
|
import de from "./locales/de.json";
|
||||||
import de from "./locales/de.json";
|
addMessages("en", en);
|
||||||
addMessages("en", en);
|
addMessages("de", de);
|
||||||
addMessages("de", de);
|
init({
|
||||||
init({
|
fallbackLocale: "en",
|
||||||
fallbackLocale: "en",
|
initialLocale: getLocaleFromNavigator(),
|
||||||
initialLocale: getLocaleFromNavigator(),
|
});
|
||||||
});
|
localForage.config({
|
||||||
localForage.config({
|
name: "lfk_admin",
|
||||||
name: "lfk_admin",
|
version: 1.0,
|
||||||
version: 1.0,
|
storeName: "lfk_admin",
|
||||||
storeName: "lfk_admin",
|
description: "LfK! admin dashbaord",
|
||||||
description: "LfK! admin dashbaord",
|
});
|
||||||
});
|
window.onunhandledrejection = (event) => {
|
||||||
window.onunhandledrejection = (event) => {
|
if (event.reason.toString() == "Error: Unauthorized") {
|
||||||
if (event.reason.toString() == "Error: Unauthorized") {
|
console.log("Found 1");
|
||||||
console.log("Found 1");
|
localForage.clear();
|
||||||
localForage.clear();
|
location.replace("/");
|
||||||
location.replace("/");
|
}
|
||||||
}
|
};
|
||||||
};
|
//
|
||||||
//
|
import Login from "./components/auth/Login.svelte";
|
||||||
import Login from "./components/auth/Login.svelte";
|
import Dashboard from "./components/dashboard/Dashboard.svelte";
|
||||||
import Dashboard from "./components/dashboard/Dashboard.svelte";
|
import store from "./store.js";
|
||||||
import store from "./store.js";
|
import ForgotPassword from "./components/auth/ForgotPassword.svelte";
|
||||||
import ForgotPassword from "./components/auth/ForgotPassword.svelte";
|
import MainDashContent from "./components/dashboard/MainDashContent.svelte";
|
||||||
import MainDashContent from "./components/dashboard/MainDashContent.svelte";
|
import Users from "./components/users/Users.svelte";
|
||||||
import Users from "./components/users/Users.svelte";
|
import About from "./components/general/About.svelte";
|
||||||
import About from "./components/general/About.svelte";
|
import Settings from "./components/settings/Settings.svelte";
|
||||||
import Settings from "./components/settings/Settings.svelte";
|
import Transition from "./components/base/Transition.svelte";
|
||||||
import Transition from "./components/base/Transition.svelte";
|
import Orgs from "./components/orgs/Orgs.svelte";
|
||||||
import Orgs from "./components/orgs/Orgs.svelte";
|
import Runners from "./components/runners/Runners.svelte";
|
||||||
import Runners from "./components/runners/Runners.svelte";
|
import Footer from "./components/general/Footer.svelte";
|
||||||
import Footer from "./components/general/Footer.svelte";
|
import TracksOverview from "./components/tracks/TracksOverview.svelte";
|
||||||
import TracksOverview from "./components/tracks/TracksOverview.svelte";
|
import OrgDetail from "./components/orgs/OrgDetail.svelte";
|
||||||
import OrgDetail from "./components/orgs/OrgDetail.svelte";
|
import Teams from "./components/teams/Teams.svelte";
|
||||||
import Teams from "./components/teams/Teams.svelte";
|
import { OpenAPI } from "@odit/lfk-client-js";
|
||||||
import { OpenAPI } from "@odit/lfk-client-js";
|
import UserDetail from "./components/users/UserDetail.svelte";
|
||||||
import UserDetail from "./components/users/UserDetail.svelte";
|
OpenAPI.BASE = config.baseurl;
|
||||||
OpenAPI.BASE = config.baseurl;
|
import TeamDetail from "./components/teams/TeamDetail.svelte";
|
||||||
import { register as registerSW } from "./swmodule";
|
import UserPermissions from "./components/users/UserPermissions.svelte";
|
||||||
import TeamDetail from "./components/teams/TeamDetail.svelte";
|
import GroupPermissions from "./components/groups/GroupPermissions.svelte";
|
||||||
import UserPermissions from "./components/users/UserPermissions.svelte";
|
import RunnerDetail from "./components/runners/RunnerDetail.svelte";
|
||||||
import GroupPermissions from "./components/groups/GroupPermissions.svelte";
|
import Imprint from "./components/general/Imprint.svelte";
|
||||||
import RunnerDetail from "./components/runners/RunnerDetail.svelte";
|
import Privacy from "./components/general/Privacy.svelte";
|
||||||
import Imprint from "./components/general/Imprint.svelte";
|
import ResetPassword from "./components/auth/ResetPassword.svelte";
|
||||||
import Privacy from "./components/general/Privacy.svelte";
|
import Contacts from "./components/contacts/Contacts.svelte";
|
||||||
import ResetPassword from "./components/auth/ResetPassword.svelte";
|
import ContactDetail from "./components/contacts/ContactDetail.svelte";
|
||||||
import Contacts from "./components/contacts/Contacts.svelte";
|
import Donors from "./components/donors/Donors.svelte";
|
||||||
import ContactDetail from "./components/contacts/ContactDetail.svelte";
|
import Groups from "./components/groups/Groups.svelte";
|
||||||
import Donors from "./components/donors/Donors.svelte";
|
import DonorDetail from "./components/donors/DonorDetail.svelte";
|
||||||
import Groups from "./components/groups/Groups.svelte";
|
import Donations from "./components/donations/Donations.svelte";
|
||||||
import DonorDetail from "./components/donors/DonorDetail.svelte";
|
import DonationDetail from "./components/donations/DonationDetail.svelte";
|
||||||
import Donations from "./components/donations/Donations.svelte";
|
import GroupDetail from "./components/groups/GroupDetail.svelte";
|
||||||
import DonationDetail from "./components/donations/DonationDetail.svelte";
|
import ScanStations from "./components/scanstations/ScanStations.svelte";
|
||||||
import GroupDetail from "./components/groups/GroupDetail.svelte";
|
import ScanStationDetail from "./components/scanstations/ScanStationDetail.svelte";
|
||||||
import ScanStations from "./components/scanstations/ScanStations.svelte";
|
import Scans from "./components/scans/Scans.svelte";
|
||||||
import ScanStationDetail from "./components/scanstations/ScanStationDetail.svelte";
|
import ScanDetail from "./components/scans/ScanDetail.svelte";
|
||||||
import Scans from "./components/scans/Scans.svelte";
|
import Cards from "./components/cards/Cards.svelte";
|
||||||
import ScanDetail from "./components/scans/ScanDetail.svelte";
|
import StatsClients from "./components/statsclients/StatsClients.svelte";
|
||||||
import Cards from "./components/cards/Cards.svelte";
|
import StatsClientDetail from "./components/statsclients/StatsClientDetail.svelte";
|
||||||
store.init();
|
store.init();
|
||||||
registerSW();
|
</script>
|
||||||
</script>
|
|
||||||
|
<Route>
|
||||||
<Route>
|
{#if $router.path === '/forgot_password'}
|
||||||
{#if $router.path === '/forgot_password'}
|
<Route path="/forgot_password">
|
||||||
<Route path="/forgot_password">
|
<ForgotPassword />
|
||||||
<ForgotPassword />
|
</Route>
|
||||||
</Route>
|
{:else if $router.path.includes('/reset')}
|
||||||
{:else if $router.path.includes('/reset')}
|
<Route path="/reset/:resetkey" let:params>
|
||||||
<Route path="/reset/:resetkey" let:params>
|
<ResetPassword {params} />
|
||||||
<ResetPassword {params} />
|
</Route>
|
||||||
</Route>
|
{:else if $router.path === '/about'}
|
||||||
{:else if $router.path === '/about'}
|
<Route path="/about">
|
||||||
<Route path="/about">
|
<About />
|
||||||
<About />
|
</Route>
|
||||||
</Route>
|
{:else if $router.path === '/imprint'}
|
||||||
{:else if $router.path === '/imprint'}
|
<Route path="/imprint">
|
||||||
<Route path="/imprint">
|
<Imprint />
|
||||||
<Imprint />
|
</Route>
|
||||||
</Route>
|
{:else if $router.path === '/privacy'}
|
||||||
{:else if $router.path === '/privacy'}
|
<Route path="/privacy">
|
||||||
<Route path="/privacy">
|
<Privacy />
|
||||||
<Privacy />
|
</Route>
|
||||||
</Route>
|
{:else if $store.isLoggedIn}
|
||||||
{:else if $store.isLoggedIn}
|
<Dashboard>
|
||||||
<Dashboard>
|
<Transition>
|
||||||
<Transition>
|
<Route path="/">
|
||||||
<Route path="/">
|
<MainDashContent />
|
||||||
<MainDashContent />
|
</Route>
|
||||||
</Route>
|
<Route path="/users/*">
|
||||||
<Route path="/users/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Users />
|
||||||
<Users />
|
</Route>
|
||||||
</Route>
|
<Route path="/:userid/*" let:params>
|
||||||
<Route path="/:userid/*" let:params>
|
<Route path="/">
|
||||||
<Route path="/">
|
<UserDetail {params} />
|
||||||
<UserDetail {params} />
|
</Route>
|
||||||
</Route>
|
<Route path="/permissions/">
|
||||||
<Route path="/permissions/">
|
<UserPermissions {params} />
|
||||||
<UserPermissions {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/groups/*">
|
||||||
<Route path="/groups/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Groups />
|
||||||
<Groups />
|
</Route>
|
||||||
</Route>
|
<Route path="/:groupid/*" let:params>
|
||||||
<Route path="/:groupid/*" let:params>
|
<Route path="/">
|
||||||
<Route path="/">
|
<GroupDetail {params} />
|
||||||
<GroupDetail {params} />
|
</Route>
|
||||||
</Route>
|
<Route path="/permissions/">
|
||||||
<Route path="/permissions/">
|
<GroupPermissions {params} />
|
||||||
<GroupPermissions {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/tracks/*">
|
||||||
<Route path="/tracks/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<TracksOverview />
|
||||||
<TracksOverview />
|
</Route>
|
||||||
</Route>
|
<Route path="/:trackid" let:params />
|
||||||
<Route path="/:trackid" let:params />
|
</Route>
|
||||||
</Route>
|
<Route path="/runners/*">
|
||||||
<Route path="/runners/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Runners />
|
||||||
<Runners />
|
</Route>
|
||||||
</Route>
|
<Route path="/:runnerid" let:params>
|
||||||
<Route path="/:runnerid" let:params>
|
<RunnerDetail {params} />
|
||||||
<RunnerDetail {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/teams/*">
|
||||||
<Route path="/teams/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Teams />
|
||||||
<Teams />
|
</Route>
|
||||||
</Route>
|
<Route path="/:teamid" let:params>
|
||||||
<Route path="/:teamid" let:params>
|
<TeamDetail {params} />
|
||||||
<TeamDetail {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/contacts/*">
|
||||||
<Route path="/contacts/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Contacts />
|
||||||
<Contacts />
|
</Route>
|
||||||
</Route>
|
<Route path="/:contact" let:params>
|
||||||
<Route path="/:contact" let:params>
|
<ContactDetail {params} />
|
||||||
<ContactDetail {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/orgs/*">
|
||||||
<Route path="/orgs/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Orgs />
|
||||||
<Orgs />
|
</Route>
|
||||||
</Route>
|
<Route path="/:orgid" let:params>
|
||||||
<Route path="/:orgid" let:params>
|
<OrgDetail {params} />
|
||||||
<OrgDetail {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/donors/*">
|
||||||
<Route path="/donors/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Donors />
|
||||||
<Donors />
|
</Route>
|
||||||
</Route>
|
<Route path="/:donorid" let:params>
|
||||||
<Route path="/:donorid" let:params>
|
<DonorDetail {params} />
|
||||||
<DonorDetail {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/donations/*">
|
||||||
<Route path="/donations/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Donations />
|
||||||
<Donations />
|
</Route>
|
||||||
</Route>
|
<Route path="/:donationid" let:params>
|
||||||
<Route path="/:donationid" let:params>
|
<DonationDetail {params} />
|
||||||
<DonationDetail {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/cards/*">
|
||||||
<Route path="/cards/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Cards />
|
||||||
<Cards />
|
</Route>
|
||||||
</Route>
|
<!-- <Route path="/:scanid" let:params>
|
||||||
<!-- <Route path="/:scanid" let:params>
|
<ScanDetail {params} />
|
||||||
<ScanDetail {params} />
|
</Route> -->
|
||||||
</Route> -->
|
</Route>
|
||||||
</Route>
|
<Route path="/scans/*">
|
||||||
<Route path="/scans/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<Scans />
|
||||||
<Scans />
|
</Route>
|
||||||
</Route>
|
<Route path="/:scanid" let:params>
|
||||||
<Route path="/:scanid" let:params>
|
<ScanDetail {params} />
|
||||||
<ScanDetail {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/scanstations/*">
|
||||||
<Route path="/scanstations/*">
|
<Route path="/">
|
||||||
<Route path="/">
|
<ScanStations />
|
||||||
<ScanStations />
|
</Route>
|
||||||
</Route>
|
<Route path="/:stationid" let:params>
|
||||||
<Route path="/:stationid" let:params>
|
<ScanStationDetail {params} />
|
||||||
<ScanStationDetail {params} />
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
<Route path="/statsclients/*">
|
||||||
<Route path="/about">
|
<Route path="/">
|
||||||
<About />
|
<StatsClients />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/settings">
|
<Route path="/:clientid" let:params>
|
||||||
<Settings />
|
<StatsClientDetail {params} />
|
||||||
</Route>
|
</Route>
|
||||||
</Transition>
|
</Route>
|
||||||
<Footer />
|
<Route path="/about">
|
||||||
</Dashboard>
|
<About />
|
||||||
{:else}
|
</Route>
|
||||||
<Login />
|
<Route path="/settings">
|
||||||
{/if}
|
<Settings />
|
||||||
</Route>
|
</Route>
|
||||||
|
</Transition>
|
||||||
|
<Footer />
|
||||||
|
</Dashboard>
|
||||||
|
{:else}
|
||||||
|
<Login />
|
||||||
|
{/if}
|
||||||
|
</Route>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<style global>
|
|
||||||
/*! @import */
|
|
||||||
@tailwind base;
|
|
||||||
@tailwind components;
|
|
||||||
@tailwind utilities;
|
|
||||||
</style>
|
|
||||||
@@ -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%)",
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<script context="module">
|
||||||
|
import { passwordStrength } from "check-password-strength";
|
||||||
|
export function password_strong_enough(password_change) {
|
||||||
|
let strength = passwordStrength(password_change);
|
||||||
|
return (
|
||||||
|
strength?.contains.includes("lowercase") &&
|
||||||
|
strength?.contains.includes("uppercase") &&
|
||||||
|
strength?.contains.includes("number") &&
|
||||||
|
strength?.length > 9
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export function password_strong_enough_and_equal(
|
||||||
|
password_change,
|
||||||
|
password_confirm
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
password_strong_enough(password_change) &&
|
||||||
|
password_change === password_confirm
|
||||||
|
);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
|
import { passwordStrength as Strength } from "check-password-strength";
|
||||||
|
export let password_change;
|
||||||
|
export let password_confirm;
|
||||||
|
|
||||||
|
$: strength = Strength(password_change);
|
||||||
|
$: passwords_match =
|
||||||
|
!password_confirm || password_confirm === password_change;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="ml-4">
|
||||||
|
<ul class="list-disc font-medium tracking-wide text-red-500 text-xs">
|
||||||
|
{#if !strength.contains.includes('lowercase')}
|
||||||
|
<li>{$_('must-contain-a-lowercase-letter')}</li>
|
||||||
|
{/if}
|
||||||
|
{#if !strength.contains.includes('uppercase')}
|
||||||
|
<li>{$_('must-contain-a-uppercase-letter')}</li>
|
||||||
|
{/if}
|
||||||
|
{#if !strength.contains.includes('number')}
|
||||||
|
<li>{$_('must-contain-a-number')}</li>
|
||||||
|
{/if}
|
||||||
|
{#if !(strength.length > 9)}
|
||||||
|
<li>{$_('must-be-at-least-10-characters-long')}</li>
|
||||||
|
{/if}
|
||||||
|
{#if !(passwords_match == true)}
|
||||||
|
<li>{$_('passwords-dont-match')}</li>
|
||||||
|
{/if}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
@@ -1,38 +1,43 @@
|
|||||||
<script>
|
<script>
|
||||||
import { AuthService } from "@odit/lfk-client-js";
|
import { AuthService } from "@odit/lfk-client-js";
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import "toastify-js/src/toastify.css";
|
import "toastify-js/src/toastify.css";
|
||||||
|
import PasswordStrength, {
|
||||||
|
password_strong_enough,
|
||||||
|
} from "../auth/PasswordStrength.svelte";
|
||||||
let state = "reset_in_progress";
|
let state = "reset_in_progress";
|
||||||
let password = "";
|
let password = "";
|
||||||
export let params;
|
export let params;
|
||||||
function set_new_password() {
|
function set_new_password() {
|
||||||
if(password.trim() !== ""){
|
if (password.trim() !== "") {
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_('password-reset-in-progress'),
|
text: $_("password-reset-in-progress"),
|
||||||
duration: 3500,
|
duration: 3500,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
AuthService.authControllerResetPassword(atob(params.resetkey),{ password })
|
AuthService.authControllerResetPassword(atob(params.resetkey), {
|
||||||
|
password,
|
||||||
|
})
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_('password-reset-successful'),
|
text: $_("password-reset-successful"),
|
||||||
duration: 3500,
|
duration: 3500,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
state="reset_success";
|
state = "reset_success";
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
state="reset_error";
|
state = "reset_error";
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_('please-provide-a-password'),
|
text: $_("please-provide-a-password"),
|
||||||
duration: 3500,
|
duration: 3500,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if state==="reset_success"}
|
{#if state === 'reset_success'}
|
||||||
<div class="min-h-screen flex items-center justify-center bg-gray-100">
|
<div class="min-h-screen flex items-center justify-center bg-gray-100">
|
||||||
<div class="max-w-md w-full py-12 px-6">
|
<div class="max-w-md w-full py-12 px-6">
|
||||||
<img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" />
|
<img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" />
|
||||||
@@ -56,31 +61,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else if state==="reset_error"}
|
{:else if state === 'reset_error'}
|
||||||
<div class="min-h-screen flex items-center justify-center bg-gray-100">
|
<div class="min-h-screen flex items-center justify-center bg-gray-100">
|
||||||
<div class="max-w-md w-full py-12 px-6">
|
<div class="max-w-md w-full py-12 px-6">
|
||||||
<img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" />
|
<img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" />
|
||||||
<p class="mt-6 text-lg text-center font-bold text-gray-900">
|
<p class="mt-6 text-lg text-center font-bold text-gray-900">
|
||||||
{$_('application_name')}
|
{$_('application_name')}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2 mb-2 text-sm text-center text-gray-900 font-bold">
|
<p class="mt-2 mb-2 text-sm text-center text-gray-900 font-bold">
|
||||||
{$_('password-reset-failed')}
|
{$_('password-reset-failed')}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2 mb-2 text-sm text-center text-gray-900">
|
<p class="mt-2 mb-2 text-sm text-center text-gray-900">
|
||||||
{$_('please-request-a-new-reset-mail')}
|
{$_('please-request-a-new-reset-mail')}
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-6">
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<a
|
<div class="mt-6">
|
||||||
href="/forgot_password/"
|
<a
|
||||||
class="text-center relative block w-full py-2 px-3 border border-transparent rounded-md text-white font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm">
|
href="/forgot_password/"
|
||||||
{$_('request-a-new-reset-mail')}
|
class="text-center relative block w-full py-2 px-3 border border-transparent rounded-md text-white font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm">
|
||||||
</a>
|
{$_('request-a-new-reset-mail')}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{:else if state === 'reset_in_progress'}
|
||||||
{:else if state==="reset_in_progress"}
|
|
||||||
<div class="min-h-screen flex items-center justify-center bg-gray-100">
|
<div class="min-h-screen flex items-center justify-center bg-gray-100">
|
||||||
<div class="max-w-md w-full py-12 px-6">
|
<div class="max-w-md w-full py-12 px-6">
|
||||||
<img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" />
|
<img style="height:10rem;" class="mx-auto" src="/lfk-logo.png" alt="" />
|
||||||
@@ -102,11 +107,14 @@
|
|||||||
placeholder={$_('new-password')}
|
placeholder={$_('new-password')}
|
||||||
bind:value={password} />
|
bind:value={password} />
|
||||||
</div>
|
</div>
|
||||||
|
<PasswordStrength bind:password_change={password} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<button
|
<button
|
||||||
on:click={set_new_password}
|
on:click={set_new_password}
|
||||||
|
disabled={!password_strong_enough(password)}
|
||||||
|
class:opacity-50={!password_strong_enough(password)}
|
||||||
type="submit"
|
type="submit"
|
||||||
class="relative block w-full py-2 px-3 border border-transparent rounded-md text-white font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm">
|
class="relative block w-full py-2 px-3 border border-transparent rounded-md text-white font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm">
|
||||||
<span class="absolute left-0 inset-y pl-3">
|
<span class="absolute left-0 inset-y pl-3">
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { RunnerCardService } from "@odit/lfk-client-js";
|
import { RunnerCardService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
export let bulk_modal_open;
|
export let bulk_modal_open;
|
||||||
@@ -22,19 +22,19 @@
|
|||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
if (createbtnenabled === true) {
|
if (createbtnenabled === true) {
|
||||||
createbtnenabled = false;
|
createbtnenabled = false;
|
||||||
submit();
|
submit_with_print();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
function submit() {
|
function submit_without_print() {
|
||||||
if (processed_last_submit === true) {
|
if (processed_last_submit === true) {
|
||||||
processed_last_submit = false;
|
processed_last_submit = false;
|
||||||
const toast = Toastify({
|
const toast = Toastify({
|
||||||
text: $_("creating-blanco-cards"),
|
text: $_("creating-blanco-cards"),
|
||||||
duration: -1,
|
duration: -1,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
RunnerCardService.runnerCardControllerPostBlancoBulk(card_count)
|
RunnerCardService.runnerCardControllerPostBlancoBulk(card_count, false)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
bulk_modal_open = false;
|
bulk_modal_open = false;
|
||||||
//
|
//
|
||||||
@@ -54,12 +54,86 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function submit_with_print() {
|
||||||
|
if (processed_last_submit === true) {
|
||||||
|
processed_last_submit = false;
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("creating-blanco-cards"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
RunnerCardService.runnerCardControllerPostBlancoBulk(card_count, true)
|
||||||
|
.then((result) => {
|
||||||
|
bulk_modal_open = false;
|
||||||
|
//
|
||||||
|
Toastify({
|
||||||
|
text: $_("created-blanco-cards"),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
current_cards = current_cards.concat(result);
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("generating-pdf"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
fetch(
|
||||||
|
`${config.baseurl_documentserver}/cards?&download=true&key=${config.documentserver_key}`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(result),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status != "200") {
|
||||||
|
toast.hideToast();
|
||||||
|
Toastify({
|
||||||
|
text: $_("pdf-generation-failed"),
|
||||||
|
duration: 3500,
|
||||||
|
backgroundColor:
|
||||||
|
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
||||||
|
}).showToast();
|
||||||
|
} else {
|
||||||
|
return response.blob();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((blob) => {
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
a.download = "Bulkcards.pdf";
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
toast.hideToast();
|
||||||
|
Toastify({
|
||||||
|
text: $_("pdf-successfully-generated"),
|
||||||
|
duration: 3500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
processed_last_submit = true;
|
||||||
|
//
|
||||||
|
toast.hideToast();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if bulk_modal_open}
|
{#if bulk_modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
bulk_modal_open = false;
|
bulk_modal_open = false;
|
||||||
@@ -75,14 +149,14 @@
|
|||||||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||||
aria-hidden="true">​</span>
|
aria-hidden="true">​</span>
|
||||||
<div
|
<div
|
||||||
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
|
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-2xl sm:w-full"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
aria-labelledby="modal-headline">
|
aria-labelledby="modal-headline">
|
||||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||||
<div class="sm:flex sm:items-start">
|
<div class="sm:flex sm:items-start">
|
||||||
<div
|
<div
|
||||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
|
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w- rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||||
<svg
|
<svg
|
||||||
class="h-6 w-6 text-blue-600"
|
class="h-6 w-6 text-blue-600"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@@ -138,17 +212,25 @@
|
|||||||
<button
|
<button
|
||||||
disabled={!createbtnenabled}
|
disabled={!createbtnenabled}
|
||||||
class:opacity-50={!createbtnenabled}
|
class:opacity-50={!createbtnenabled}
|
||||||
on:click={submit}
|
on:click={submit_with_print}
|
||||||
type="button"
|
type="button"
|
||||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||||
{$_('create')}
|
{$_('create-and-generate-pdf')}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
disabled={!createbtnenabled}
|
||||||
|
class:opacity-50={!createbtnenabled}
|
||||||
|
on:click={submit_without_print}
|
||||||
|
type="button"
|
||||||
|
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-400 text-base font-medium text-white hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||||
|
{$_('create-without-pdf')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
bulk_modal_open = false;
|
bulk_modal_open = false;
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
|
class="mr-auto mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
|
||||||
{$_('cancel')}
|
{$_('cancel')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import {
|
import {
|
||||||
RunnerCardService,
|
RunnerCardService,
|
||||||
RunnerService,
|
RunnerService,
|
||||||
@@ -11,22 +11,37 @@
|
|||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
export let modal_open;
|
export let modal_open;
|
||||||
export let current_cards;
|
export let current_cards;
|
||||||
const getRunnerLabel = (option) =>
|
|
||||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
const getRunnerLabel = (option) => {
|
||||||
const filterRunners = (label, filterText, option) =>
|
if (option.middlename) {
|
||||||
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
return option.firstname + " " + option.middlename + " " + option.lastname;
|
||||||
option.value.toString().startsWith(filterText.toLowerCase());
|
}
|
||||||
|
return option.firstname + " " + option.lastname;
|
||||||
|
};
|
||||||
|
|
||||||
|
const filterRunners = (label, filterText, option) => {
|
||||||
|
if (filterText.startsWith("#")) {
|
||||||
|
return option.value.id == parseInt(filterText.replace("#",""))
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||||
|
option.value.toString().startsWith(filterText.toLowerCase())
|
||||||
|
);
|
||||||
|
};
|
||||||
function focus(el) {
|
function focus(el) {
|
||||||
el.focus();
|
el.focus();
|
||||||
}
|
}
|
||||||
$: runner = 0;
|
$: runner = 0;
|
||||||
$: runners = [];
|
|
||||||
$: enabled = true;
|
$: enabled = true;
|
||||||
$: processed_last_submit = true;
|
$: processed_last_submit = true;
|
||||||
|
|
||||||
|
let loading = true;
|
||||||
|
let runners = [];
|
||||||
RunnerService.runnerControllerGetAll().then((val) => {
|
RunnerService.runnerControllerGetAll().then((val) => {
|
||||||
runners = val.map((r) => {
|
runners = val.map((r) => {
|
||||||
return { label: getRunnerLabel(r), value: r };
|
return { label: getRunnerLabel(r), value: r };
|
||||||
});
|
});
|
||||||
|
loading = false;
|
||||||
});
|
});
|
||||||
$: createbtnenabled = true;
|
$: createbtnenabled = true;
|
||||||
(() => {
|
(() => {
|
||||||
@@ -82,65 +97,82 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
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="fixed inset-0 transition-opacity" aria-hidden="true">
|
||||||
<div
|
<div
|
||||||
class="absolute inset-0 bg-gray-500 opacity-75"
|
class="absolute inset-0 bg-gray-500 opacity-75"
|
||||||
data-id="modal_backdrop" />
|
data-id="modal_backdrop"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
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">​</span>
|
aria-hidden="true">​</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-lg 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-12 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"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
width="24"
|
width="24"
|
||||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
height="24"
|
||||||
|
><path fill="none" d="M0 0h24v24H0z" />
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
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>
|
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>
|
||||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
<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">
|
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||||
{$_('create-a-new-card')}
|
{$_("create-a-new-card")}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="mt-2 mb-6">
|
<div class="mt-2 mb-6">
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500">
|
||||||
{$_('you-can-provide-a-runner-but-you-dont-have-to')}
|
{$_("you-can-provide-a-runner-but-you-dont-have-to")}
|
||||||
{$_('if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button')}
|
{$_(
|
||||||
|
"if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button"
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-6 gap-6">
|
<div class="grid grid-cols-6 gap-6">
|
||||||
<div class="col-span-6">
|
<div class="col-span-6">
|
||||||
<label
|
<label
|
||||||
for="donor"
|
for="donor"
|
||||||
class="block text-sm font-medium text-gray-700">{$_('runner')}</label>
|
class="block text-sm font-medium text-gray-700"
|
||||||
|
>{$_("runner")}</label
|
||||||
|
>
|
||||||
<Select
|
<Select
|
||||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||||
itemFilter={(label, filterText, option) => filterRunners(label, filterText, option)}
|
itemFilter={(label, filterText, option) =>
|
||||||
|
filterRunners(label, filterText, option)}
|
||||||
items={runners}
|
items={runners}
|
||||||
showChevron={true}
|
bind:loading
|
||||||
placeholder={$_('search-for-runner-by-name-or-id')}
|
showChevron={!loading}
|
||||||
noOptionsMessage={$_('no-runners-found')}
|
placeholder={$_("search-for-runner-by-name-or-id")}
|
||||||
on:select={(selectedValue) => (runner = selectedValue.detail.value.id)}
|
noOptionsMessage={$_("no-runners-found")}
|
||||||
on:clear={() => (runner = null)} />
|
on:select={(selectedValue) =>
|
||||||
|
(runner = selectedValue.detail.value.id)}
|
||||||
|
on:clear={() => (runner = null)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -152,16 +184,18 @@
|
|||||||
class:opacity-50={!createbtnenabled}
|
class:opacity-50={!createbtnenabled}
|
||||||
on:click={submit}
|
on:click={submit}
|
||||||
type="button"
|
type="button"
|
||||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"
|
||||||
{$_('create')}
|
>
|
||||||
|
{$_("create")}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
modal_open = false;
|
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="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>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { RunnerCardService, RunnerService } from "@odit/lfk-client-js";
|
import { RunnerCardService, RunnerService } 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 { createEventDispatcher } from "svelte";
|
||||||
export let edit_modal_open;
|
export let edit_modal_open;
|
||||||
export let current_cards;
|
export let current_cards;
|
||||||
export let runner = {};
|
export let runner = {};
|
||||||
@@ -12,15 +13,26 @@
|
|||||||
export let original_data = {};
|
export let original_data = {};
|
||||||
const getRunnerLabel = (option) =>
|
const getRunnerLabel = (option) =>
|
||||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||||
const filterRunners = (label, filterText, option) =>
|
const filterRunners = (label, filterText, option) => {
|
||||||
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
if (filterText.startsWith("#")) {
|
||||||
option.value.toString().startsWith(filterText.toLowerCase());
|
return option.value.id == parseInt(filterText.replace("#",""))
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||||
|
option.value.toString().startsWith(filterText.toLowerCase())
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
function focus(el) {
|
function focus(el) {
|
||||||
el.focus();
|
el.focus();
|
||||||
}
|
}
|
||||||
$: runners = [];
|
$: runners = [];
|
||||||
$: enabled = true;
|
$: enabled = true;
|
||||||
$: processed_last_submit = true;
|
$: processed_last_submit = true;
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
function dataUpdated() {
|
||||||
|
dispatch('dataUpdated',);
|
||||||
|
}
|
||||||
RunnerService.runnerControllerGetAll().then((val) => {
|
RunnerService.runnerControllerGetAll().then((val) => {
|
||||||
runners = val.map((r) => {
|
runners = val.map((r) => {
|
||||||
return { label: getRunnerLabel(r), value: r };
|
return { label: getRunnerLabel(r), value: r };
|
||||||
@@ -65,6 +77,7 @@
|
|||||||
}).showToast();
|
}).showToast();
|
||||||
current_cards[current_cards.findIndex((c) => c.id === id)] = result;
|
current_cards[current_cards.findIndex((c) => c.id === id)] = result;
|
||||||
current_cards = current_cards;
|
current_cards = current_cards;
|
||||||
|
dataUpdated();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
//
|
//
|
||||||
@@ -81,7 +94,7 @@
|
|||||||
{#if edit_modal_open}
|
{#if edit_modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
edit_modal_open = false;
|
edit_modal_open = false;
|
||||||
|
|||||||
@@ -1,46 +1,45 @@
|
|||||||
<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";
|
||||||
import CardsEmptyState from "./CardsEmptyState.svelte";
|
import CardsEmptyState from "./CardsEmptyState.svelte";
|
||||||
import CardDetailModal from "./CardDetailModal.svelte";
|
import CardDetailModal from "./CardDetailModal.svelte";
|
||||||
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
|
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
|
||||||
|
import ThFilterStatus from "./ThFilterStatus.svelte";
|
||||||
|
import ThFilterRunner from "./ThFilterRunner.svelte";
|
||||||
export let edit_modal_open = false;
|
export let edit_modal_open = false;
|
||||||
export let runner = {};
|
export let runner = {};
|
||||||
export let editable = {};
|
export let editable = {};
|
||||||
export let original_data = {};
|
export let original_data = {};
|
||||||
export let current_cards = [];
|
export let current_cards = [];
|
||||||
$: searchvalue = "";
|
const handler = new DataHandler(current_cards, { rowsPerPage: 50 });
|
||||||
|
const rows = handler.getRows();
|
||||||
$: active_deletes = [];
|
$: active_deletes = [];
|
||||||
$: cards_show = current_cards.some(
|
$: cards_show = generate_cards.length > 0;
|
||||||
(r) => r.is_selected === true
|
$: generate_cards = [];
|
||||||
);
|
|
||||||
$: generate_cards = current_cards.filter((r) => r.is_selected === true);
|
|
||||||
const cards_promise = RunnerCardService.runnerCardControllerGetAll().then(
|
const cards_promise = RunnerCardService.runnerCardControllerGetAll().then(
|
||||||
(val) => {
|
(val) => {
|
||||||
current_cards = val;
|
current_cards = val;
|
||||||
|
handler.setRows(val);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
function should_display_based_on_id(id) {
|
|
||||||
if (searchvalue.toString().slice(-1) === "*") {
|
|
||||||
return id.toString().startsWith(searchvalue.replace("*", ""));
|
|
||||||
}
|
|
||||||
return id.toString() === searchvalue;
|
|
||||||
}
|
|
||||||
const getRunnerLabel = (option) =>
|
const getRunnerLabel = (option) =>
|
||||||
option?.firstname + " " + (option?.middlename || "") + " " + (option?.lastname || "{$_('non-blanko')}");
|
option?.firstname +
|
||||||
|
" " +
|
||||||
|
(option?.middlename || "") +
|
||||||
|
" " +
|
||||||
|
(option?.lastname || "{$_('non-blanko')}");
|
||||||
function open_edit_modal(card) {
|
function open_edit_modal(card) {
|
||||||
if(card.runner?.id){
|
if (card.runner?.id) {
|
||||||
runner = Object.assign(
|
runner = Object.assign(
|
||||||
{ runner },
|
{ runner },
|
||||||
{ label: getRunnerLabel(card.runner), value: card.runner }
|
{ label: getRunnerLabel(card.runner), value: card.runner }
|
||||||
);
|
);
|
||||||
card.runner = card.runner.id;
|
card.runner = card.runner.id;
|
||||||
}
|
} else {
|
||||||
else{
|
card.runner = null;
|
||||||
card.runner=null;
|
runner = null;
|
||||||
runner = null
|
|
||||||
}
|
}
|
||||||
editable = Object.assign(editable, card);
|
editable = Object.assign(editable, card);
|
||||||
original_data = Object.assign(original_data, card);
|
original_data = Object.assign(original_data, card);
|
||||||
@@ -48,190 +47,217 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#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
|
||||||
bind:edit_modal_open
|
bind:edit_modal_open
|
||||||
bind:runner
|
bind:runner
|
||||||
bind:editable
|
bind:editable
|
||||||
bind:original_data />
|
bind:original_data
|
||||||
|
on:dataUpdated={handler.setRows(current_cards)}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:GET')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes("CARD:GET")}
|
||||||
{#await cards_promise}
|
{#await cards_promise}
|
||||||
<div
|
<div
|
||||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||||
role="alert">
|
role="alert"
|
||||||
<p class="font-bold">{$_('loading-cards')}</p>
|
>
|
||||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
<p class="font-bold">{$_("loading-cards")}</p>
|
||||||
|
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
|
||||||
</div>
|
</div>
|
||||||
{:then}
|
{:then}
|
||||||
{#if current_cards.length === 0}
|
{#if current_cards.length === 0}
|
||||||
<CardsEmptyState />
|
<CardsEmptyState />
|
||||||
{:else}
|
{:else}
|
||||||
<input
|
<div class="h-12 mt-1">
|
||||||
type="search"
|
{#if cards_show}
|
||||||
bind:value={searchvalue}
|
<button
|
||||||
placeholder={$_('datatable.search')}
|
type="button"
|
||||||
aria-label={$_('datatable.search')}
|
class="w-full justify-center 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 sm:ml-3 sm:w-auto sm:text-sm inline-flex"
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
id="options-menu"
|
||||||
<div class="h-12">
|
on:click={async () => {
|
||||||
<GenerateRunnerCards
|
const prom = [];
|
||||||
bind:cards_show
|
for (const card of generate_cards) {
|
||||||
bind:generate_cards />
|
prom.push(
|
||||||
</div>
|
RunnerCardService.runnerCardControllerRemove(card.id, true)
|
||||||
<div
|
);
|
||||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
}
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
await Promise.all(prom);
|
||||||
<thead class="bg-gray-50">
|
Toastify({
|
||||||
<tr>
|
text: $_("cards-deleted"),
|
||||||
<th
|
duration: 3500,
|
||||||
scope="col"
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
}).showToast();
|
||||||
<span
|
//TODO: Delete cards from table
|
||||||
on:click={() => {
|
}}
|
||||||
const newstate = !current_cards.some((r) => r.is_selected === true);
|
>
|
||||||
current_cards = current_cards.map((r) => {
|
{$_("delete-cards")}
|
||||||
r.is_selected = newstate;
|
<svg
|
||||||
return r;
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
});
|
fill="none"
|
||||||
}}
|
viewBox="0 0 24 24"
|
||||||
class="underline cursor-pointer select-none">{#if current_cards.some((r) => r.is_selected === true)}
|
stroke-width="1.5"
|
||||||
{$_('deselect-all')}
|
stroke="currentColor"
|
||||||
{:else}{$_('select-all')}{/if}
|
class="w-5 h-5"
|
||||||
</span>
|
>
|
||||||
</th>
|
<path
|
||||||
<th
|
stroke-linecap="round"
|
||||||
scope="col"
|
stroke-linejoin="round"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
|
||||||
{$_('code')}
|
/>
|
||||||
</th>
|
</svg>
|
||||||
<th
|
</button>
|
||||||
scope="col"
|
{/if}
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
<GenerateRunnerCards bind:cards_show bind:generate_cards />
|
||||||
{$_('runner')}
|
|
||||||
</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">
|
|
||||||
<span class="sr-only">{$_('action')}</span>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="divide-y divide-gray-200">
|
|
||||||
{#each current_cards as card}
|
|
||||||
{#if card.code
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
searchvalue.toLowerCase()
|
|
||||||
) || card.runner?.firstname
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
searchvalue.toLowerCase()
|
|
||||||
) || card.runner?.middlename
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
searchvalue.toLowerCase()
|
|
||||||
) || card.runner?.lastname
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
searchvalue.toLowerCase()
|
|
||||||
) || should_display_based_on_id(card.id)}
|
|
||||||
<tr data-rowid="card_{card.id}">
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
<input
|
|
||||||
bind:checked={card.is_selected}
|
|
||||||
type="checkbox"
|
|
||||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
<div class="flex items-center">{card.code}</div>
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
<div class="flex items-center">
|
|
||||||
{#if card.runner}
|
|
||||||
<a
|
|
||||||
href="../runners/{card.runner.id}"
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{card.runner.firstname}
|
|
||||||
{card.runner.middlename || ''}
|
|
||||||
{card.runner.lastname}</a>
|
|
||||||
{:else}{$_('non-blanko')}{/if}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
<div class="flex items-center">
|
|
||||||
{#if card.enabled}
|
|
||||||
<span
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('enabled')}</span>
|
|
||||||
{:else}
|
|
||||||
<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}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[card.id] = false;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
RunnerCardService.runnerCardControllerRemove(card.id, false).then(
|
|
||||||
(resp) => {
|
|
||||||
current_cards = current_cards.filter(
|
|
||||||
(obj) => obj.id !== card.id
|
|
||||||
);
|
|
||||||
Toastify({
|
|
||||||
text: $_('card-deleted'),
|
|
||||||
duration: 500,
|
|
||||||
backgroundColor:
|
|
||||||
'linear-gradient(to right, #00b09b, #96c93d)',
|
|
||||||
}).showToast();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
|
||||||
</td>
|
|
||||||
{:else}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
open_edit_modal(card);
|
|
||||||
}}
|
|
||||||
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</button>
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')}
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[card.id] = true;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
{/if}
|
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="border-bottom: 1px solid #ddd;">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
|
||||||
|
checked={generate_cards.length == current_cards.length}
|
||||||
|
on:click={() => {
|
||||||
|
if (generate_cards.length != current_cards.length) {
|
||||||
|
generate_cards = current_cards;
|
||||||
|
} else {
|
||||||
|
generate_cards = [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</th>
|
||||||
|
<Th {handler} orderBy="code">{$_("code")}</Th>
|
||||||
|
<Th {handler} orderBy="runner">{$_("runner")}</Th>
|
||||||
|
<Th {handler} orderBy="status">{$_("status")}</Th>
|
||||||
|
<th style="border-bottom: 1px solid #ddd;">{$_("action")}</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th style="border-bottom: 1px solid #ddd;" />
|
||||||
|
<ThFilter {handler} filterBy="code" />
|
||||||
|
<ThFilterRunner {handler} />
|
||||||
|
<ThFilterStatus {handler} />
|
||||||
|
<th style="border-bottom: 1px solid #ddd;" />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each $rows as row}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
|
||||||
|
checked={generate_cards.filter((i) => i.id == row.id).length >
|
||||||
|
0}
|
||||||
|
on:click={() => {
|
||||||
|
if (generate_cards.findIndex((i) => i.id == row.id) == -1) {
|
||||||
|
generate_cards.push(row);
|
||||||
|
generate_cards = generate_cards;
|
||||||
|
} else {
|
||||||
|
generate_cards = generate_cards.filter(
|
||||||
|
(r) => r.id != row.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console.log(generate_cards);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>{row.code}</td>
|
||||||
|
<td>
|
||||||
|
{#if row.runner}
|
||||||
|
<a
|
||||||
|
href="../runners/{row.runner.id}"
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
|
||||||
|
>{row.runner.firstname}
|
||||||
|
{row.runner.middlename || ""}
|
||||||
|
{row.runner.lastname}</a
|
||||||
|
>
|
||||||
|
{:else}{$_("non-blanko")}{/if}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{#if row.enabled}
|
||||||
|
<span
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"
|
||||||
|
>{$_("enabled")}</span
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<span
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800"
|
||||||
|
>{$_("disabled")}</span
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{#if active_deletes[row.id] === true}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[row.id] = false;
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer"
|
||||||
|
>{$_("cancel-delete")}</button
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
RunnerCardService.runnerCardControllerRemove(row.id, true)
|
||||||
|
.then((resp) => {
|
||||||
|
current_cards = current_cards.filter(
|
||||||
|
(obj) => obj.id !== row.id
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer"
|
||||||
|
>{$_("confirm-delete")}</button
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
open_edit_modal(row);
|
||||||
|
}}
|
||||||
|
class="text-indigo-600 hover:text-indigo-900"
|
||||||
|
>{$_("details")}</button
|
||||||
|
>
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes("CARD:DELETE")}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[row.id] = true;
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer"
|
||||||
|
>{$_("delete")}</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
{/if}
|
{/if}
|
||||||
{:catch error}
|
{:catch error}
|
||||||
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
||||||
<span class="inline-block align-middle mr-8">
|
<span class="inline-block align-middle mr-8">
|
||||||
<b class="capitalize">{$_('general_promise_error')}</b>
|
<b class="capitalize">{$_("general_promise_error")}</b>
|
||||||
{error}
|
{error}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{/await}
|
{/await}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
table tbody {
|
||||||
|
display: block;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead,
|
||||||
|
table tbody tr {
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<script>
|
||||||
|
export let handler;
|
||||||
|
let filterValue = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<input
|
||||||
|
on:input={() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const v = filterValue.toLowerCase();
|
||||||
|
handler.filter(v, (c) => {
|
||||||
|
// if (v === "") {
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (!c.runner && v === "blanko") {
|
||||||
|
return "blanko";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v.startsWith("#")) {
|
||||||
|
return `#${c.runner?.id}`;
|
||||||
|
}
|
||||||
|
if (c.runner) {
|
||||||
|
let runnerName = `${c.runner.firstname} ${c.runner.lastname}`;
|
||||||
|
if (c.runner.middlename) {
|
||||||
|
runnerName = `${c.runner.firstname} ${c.runner.middlename} ${c.runner.lastname}`;
|
||||||
|
}
|
||||||
|
runnerName = runnerName.toLowerCase();
|
||||||
|
return runnerName;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
}, 150);
|
||||||
|
}}
|
||||||
|
bind:value={filterValue}
|
||||||
|
type="text"
|
||||||
|
name="runnerfilter"
|
||||||
|
id="runnerfilter"
|
||||||
|
/>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
th {
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
margin: -1px 0 0 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 24px;
|
||||||
|
border: none;
|
||||||
|
text-align: left;
|
||||||
|
background: inherit;
|
||||||
|
outline: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
export let handler;
|
||||||
|
let selected = "all";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<select
|
||||||
|
on:input={() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (`${selected}`.trim()) {
|
||||||
|
if (selected === "all") {
|
||||||
|
handler.filter("", "enabled");
|
||||||
|
} else {
|
||||||
|
handler.filter(selected, "enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}}
|
||||||
|
bind:value={selected}
|
||||||
|
name="statusfilter"
|
||||||
|
id="statusfilter"
|
||||||
|
>
|
||||||
|
<option value="all">{$_("all")}</option>
|
||||||
|
<option value="true">{$_("enabled")}</option>
|
||||||
|
<option value="false">{$_("disabled")}</option>
|
||||||
|
</select>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
th {
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
margin: -1px 0 0 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 24px;
|
||||||
|
border: none;
|
||||||
|
text-align: left;
|
||||||
|
background: inherit;
|
||||||
|
outline: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import {
|
import {
|
||||||
GroupContactService,
|
GroupContactService,
|
||||||
RunnerTeamService,
|
RunnerTeamService,
|
||||||
@@ -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();
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
bind:value={searchvalue}
|
bind:value={searchvalue}
|
||||||
placeholder={$_('datatable.search')}
|
placeholder={$_('datatable.search')}
|
||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="mb-4" />
|
||||||
<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">
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -246,6 +256,26 @@
|
|||||||
<span>{$_('scanstations')}</span>
|
<span>{$_('scanstations')}</span>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('STATSCLIENT:GET')}
|
||||||
|
<a
|
||||||
|
class:bg-gray-100={$router.path === '/statsclients/'}
|
||||||
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
|
href="/statsclients/">
|
||||||
|
<svg
|
||||||
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
|
fill="currentColor"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"><path
|
||||||
|
fill="none"
|
||||||
|
d="M0 0h24v24H0z" />
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
||||||
|
<span>{$_('statsclients')}</span>
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
<a
|
<a
|
||||||
class:bg-gray-100={$router.path === '/settings/'}
|
class:bg-gray-100={$router.path === '/settings/'}
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
@@ -297,14 +327,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 +349,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>
|
||||||
@@ -1,22 +1,157 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import StatCards from "./StatCards.svelte";
|
import { StatsService } from "@odit/lfk-client-js";
|
||||||
|
import StatCards from "./StatCard.svelte";
|
||||||
import store from "../../store";
|
import store from "../../store";
|
||||||
|
import StatCard from "./StatCard.svelte";
|
||||||
let navOpen = false;
|
let navOpen = false;
|
||||||
|
const stats_promise = StatsService.statsControllerGet();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="p-5 overflow-x-hidden"
|
class="p-5 overflow-x-hidden"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
navOpen = false;
|
navOpen = false;
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<h1 class="text-3xl leading-tight">
|
<h1 class="text-3xl leading-tight">
|
||||||
<span class="font-extrabold">{$_('dashboard-title')}</span>
|
<span class="font-extrabold">{$_("dashboard-title")}</span>
|
||||||
<span>
|
<span>
|
||||||
-
|
-
|
||||||
{$_('dashboard-greeting')},
|
{$_("dashboard-greeting")},
|
||||||
<span
|
<span class="text-blue-500"
|
||||||
class="text-blue-500">{store.state.jwtinfo.userdetails.firstname} {store.state.jwtinfo.userdetails.lastname}</span></span>
|
>{store.state.jwtinfo.userdetails.firstname}
|
||||||
|
{store.state.jwtinfo.userdetails.lastname}</span
|
||||||
|
></span
|
||||||
|
>
|
||||||
</h1>
|
</h1>
|
||||||
<StatCards />
|
<h1>{$_("general-stats")}</h1>
|
||||||
|
{#await stats_promise}
|
||||||
|
<div
|
||||||
|
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<p class="font-bold">{$_("stats-are-being-loaded")}</p>
|
||||||
|
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
|
||||||
|
</div>
|
||||||
|
{:then stats}
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 2xl:grid-cols-6 gap-4">
|
||||||
|
<StatCard
|
||||||
|
title={$_("runners")}
|
||||||
|
value={stats.total_runners}
|
||||||
|
href="/runners/"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
height="24"
|
||||||
|
width="24"
|
||||||
|
fill="currentColor"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
><path d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path
|
||||||
|
d="M13.49 5.48c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-3.6 13.9l1-4.4 2.1 2v6h2v-7.5l-2.1-2 .6-3c1.3 1.5 3.3 2.5 5.5 2.5v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1l-5.2 2.2v4.7h2v-3.4l1.8-.7-1.6 8.1-4.9-1-.4 2 7 1.4z"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</StatCard>
|
||||||
|
<StatCard
|
||||||
|
title={$_("total-scans")}
|
||||||
|
value={stats.total_scans}
|
||||||
|
href="/scans/"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
size="24"
|
||||||
|
class="stroke-current text-grey-500"
|
||||||
|
height="24"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
><polyline points="22 12 18 12 15 21 9 3 6 12 2 12" /></svg
|
||||||
|
>
|
||||||
|
</StatCard>
|
||||||
|
<StatCard
|
||||||
|
title={$_("total-donations")}
|
||||||
|
value={`${(stats.total_donation / 100).toFixed(2)} €`}
|
||||||
|
href="/donations/"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
height="24"
|
||||||
|
fill="currentColor"
|
||||||
|
width="24"
|
||||||
|
><path d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path
|
||||||
|
d="M15 18.5A6.48 6.48 0 019.24 15H15v-2H8.58c-.05-.33-.08-.66-.08-1s.03-.67.08-1H15V9H9.24A6.491 6.491 0 0115 5.5c1.61 0 3.09.59 4.23 1.57L21 5.3A8.955 8.955 0 0015 3c-3.92 0-7.24 2.51-8.48 6H3v2h3.06a8.262 8.262 0 000 2H3v2h3.52c1.24 3.49 4.56 6 8.48 6 2.31 0 4.41-.87 6-2.3l-1.78-1.77c-1.13.98-2.6 1.57-4.22 1.57z"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</StatCard>
|
||||||
|
<StatCard
|
||||||
|
title={$_("total-distance")}
|
||||||
|
value={`${stats.total_distance / 1000} km`}
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
fill="currentColor"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
height="24"
|
||||||
|
width="24"
|
||||||
|
><path d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path
|
||||||
|
d="M21 6H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 10H3V8h2v4h2V8h2v4h2V8h2v4h2V8h2v4h2V8h2v8z"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</StatCard>
|
||||||
|
<StatCard
|
||||||
|
title={$_("count_teams")}
|
||||||
|
value={stats.total_teams}
|
||||||
|
href="/teams/"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
size="24"
|
||||||
|
class="stroke-current text-grey-500"
|
||||||
|
height="24"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
|
||||||
|
<circle cx="9" cy="7" r="4" />
|
||||||
|
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
||||||
|
<path d="M16 3.13a4 4 0 0 1 0 7.75" /></svg
|
||||||
|
>
|
||||||
|
</StatCard>
|
||||||
|
<StatCard
|
||||||
|
title={$_("count_organizations")}
|
||||||
|
value={stats.total_orgs}
|
||||||
|
href="/orgs/"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
height="24"
|
||||||
|
fill="currentColor"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
><path fill="none" d="M0 0h24v24H0z" />
|
||||||
|
<path
|
||||||
|
d="M17 11V3H7v4H3v14h8v-4h2v4h8V11h-4zM7 19H5v-2h2v2zm0-4H5v-2h2v2zm0-4H5V9h2v2zm4 4H9v-2h2v2zm0-4H9V9h2v2zm0-4H9V5h2v2zm4 8h-2v-2h2v2zm0-4h-2V9h2v2zm0-4h-2V5h2v2zm4 12h-2v-2h2v2zm0-4h-2v-2h2v2z"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</StatCard>
|
||||||
|
</div>
|
||||||
|
{:catch error}
|
||||||
|
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
||||||
|
<span class="inline-block align-middle mr-8">
|
||||||
|
<b class="capitalize">{$_("general_promise_error")}</b>
|
||||||
|
{error}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/await}
|
||||||
</div>
|
</div>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
|
||||||
|
export let href = "#"
|
||||||
|
export let title = "";
|
||||||
|
export let value = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<a href={href}>
|
||||||
|
<div
|
||||||
|
class="p-4 rounded-lg bg-white border border-grey-100">
|
||||||
|
<div class="flex flex-row items-center justify-between">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="text-xs uppercase font-light text-grey-500">
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
<div class="text-xl font-bold">{value}</div>
|
||||||
|
</div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { StatsService } from "@odit/lfk-client-js";
|
|
||||||
import { _ } from "svelte-i18n";
|
|
||||||
const stats_promise = StatsService.statsControllerGet();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
<h1>{$_('general-stats')}</h1>
|
|
||||||
{#await stats_promise}
|
|
||||||
<div
|
|
||||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
|
||||||
role="alert">
|
|
||||||
<p class="font-bold">{$_('stats-are-being-loaded')}</p>
|
|
||||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
|
||||||
</div>
|
|
||||||
{:then stats}
|
|
||||||
<div
|
|
||||||
class="flex flex-col lg:flex-row w-full lg:space-x-2 space-y-2 lg:space-y-0 mb-2 lg:mb-4">
|
|
||||||
<a href="/runners/" class="w-full lg:w-1/4">
|
|
||||||
<div
|
|
||||||
class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
|
|
||||||
<div class="flex flex-row items-center justify-between">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="text-xs uppercase font-light text-grey-500">
|
|
||||||
{$_('runners')}
|
|
||||||
</div>
|
|
||||||
<div class="text-xl font-bold">{stats.total_runners}</div>
|
|
||||||
</div>
|
|
||||||
<svg
|
|
||||||
height="24"
|
|
||||||
width="24"
|
|
||||||
fill="currentColor"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none" />
|
|
||||||
<path
|
|
||||||
d="M13.49 5.48c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-3.6 13.9l1-4.4 2.1 2v6h2v-7.5l-2.1-2 .6-3c1.3 1.5 3.3 2.5 5.5 2.5v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1l-5.2 2.2v4.7h2v-3.4l1.8-.7-1.6 8.1-4.9-1-.4 2 7 1.4z" /></svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<div class="w-full lg:w-1/4">
|
|
||||||
<div
|
|
||||||
class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
|
|
||||||
<div class="flex flex-row items-center justify-between">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="text-xs uppercase font-light text-grey-500">
|
|
||||||
{$_('total-scans')}
|
|
||||||
</div>
|
|
||||||
<div class="text-xl font-bold">{stats.total_scans}</div>
|
|
||||||
</div><svg
|
|
||||||
stroke="currentColor"
|
|
||||||
fill="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
size="24"
|
|
||||||
class="stroke-current text-grey-500"
|
|
||||||
height="24"
|
|
||||||
width="24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"><polyline
|
|
||||||
points="22 12 18 12 15 21 9 3 6 12 2 12" /></svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-full lg:w-1/4">
|
|
||||||
<div
|
|
||||||
class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
|
|
||||||
<div class="flex flex-row items-center justify-between">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="text-xs uppercase font-light text-grey-500">
|
|
||||||
{$_('total-donations')}
|
|
||||||
</div>
|
|
||||||
<div class="text-xl font-bold">{stats.total_donation} €</div>
|
|
||||||
</div><svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
height="24"
|
|
||||||
fill="currentColor"
|
|
||||||
width="24"><path d="M0 0h24v24H0z" fill="none" />
|
|
||||||
<path
|
|
||||||
d="M15 18.5A6.48 6.48 0 019.24 15H15v-2H8.58c-.05-.33-.08-.66-.08-1s.03-.67.08-1H15V9H9.24A6.491 6.491 0 0115 5.5c1.61 0 3.09.59 4.23 1.57L21 5.3A8.955 8.955 0 0015 3c-3.92 0-7.24 2.51-8.48 6H3v2h3.06a8.262 8.262 0 000 2H3v2h3.52c1.24 3.49 4.56 6 8.48 6 2.31 0 4.41-.87 6-2.3l-1.78-1.77c-1.13.98-2.6 1.57-4.22 1.57z" /></svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-full lg:w-1/4">
|
|
||||||
<div
|
|
||||||
class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
|
|
||||||
<div class="flex flex-row items-center justify-between">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="text-xs uppercase font-light text-grey-500">
|
|
||||||
{$_('total-distance')}
|
|
||||||
</div>
|
|
||||||
<div class="text-xl font-bold">
|
|
||||||
{stats.total_distance / 1000}
|
|
||||||
km
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<svg
|
|
||||||
fill="currentColor"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
height="24"
|
|
||||||
width="24"><path d="M0 0h24v24H0z" fill="none" />
|
|
||||||
<path
|
|
||||||
d="M21 6H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 10H3V8h2v4h2V8h2v4h2V8h2v4h2V8h2v4h2V8h2v8z" /></svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a href="/teams/" class="w-full lg:w-1/4">
|
|
||||||
<div
|
|
||||||
class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
|
|
||||||
<div class="flex flex-row items-center justify-between">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="text-xs uppercase font-light text-grey-500">
|
|
||||||
{$_('count_teams')}
|
|
||||||
</div>
|
|
||||||
<div class="text-xl font-bold">{stats.total_teams}</div>
|
|
||||||
</div>
|
|
||||||
<svg
|
|
||||||
stroke="currentColor"
|
|
||||||
fill="none"
|
|
||||||
stroke-width="2"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
size="24"
|
|
||||||
class="stroke-current text-grey-500"
|
|
||||||
height="24"
|
|
||||||
width="24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"><path
|
|
||||||
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
|
|
||||||
<circle cx="9" cy="7" r="4" />
|
|
||||||
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
|
||||||
<path d="M16 3.13a4 4 0 0 1 0 7.75" /></svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a href="/orgs/" class="w-full lg:w-1/4">
|
|
||||||
<div
|
|
||||||
class="widget w-full p-4 rounded-lg bg-white border border-grey-100">
|
|
||||||
<div class="flex flex-row items-center justify-between">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="text-xs uppercase font-light text-grey-500">
|
|
||||||
{$_('count_organizations')}
|
|
||||||
</div>
|
|
||||||
<div class="text-xl font-bold">{stats.total_orgs}</div>
|
|
||||||
</div>
|
|
||||||
<svg
|
|
||||||
height="24"
|
|
||||||
fill="currentColor"
|
|
||||||
width="24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z" />
|
|
||||||
<path
|
|
||||||
d="M17 11V3H7v4H3v14h8v-4h2v4h8V11h-4zM7 19H5v-2h2v2zm0-4H5v-2h2v2zm0-4H5V9h2v2zm4 4H9v-2h2v2zm0-4H9V9h2v2zm0-4H9V5h2v2zm4 8h-2v-2h2v2zm0-4h-2V9h2v2zm0-4h-2V5h2v2zm4 12h-2v-2h2v2zm0-4h-2v-2h2v2z" /></svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{:catch error}
|
|
||||||
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
|
||||||
<span class="inline-block align-middle mr-8">
|
|
||||||
<b class="capitalize">{$_('general_promise_error')}</b>
|
|
||||||
{error}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{/await}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import {
|
import {
|
||||||
DonationService,
|
DonationService,
|
||||||
DonorService,
|
DonorService,
|
||||||
@@ -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>
|
||||||
@@ -150,7 +156,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -0,0 +1,202 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
|
||||||
|
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: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">​</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}
|
||||||
@@ -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} />
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -37,7 +49,7 @@
|
|||||||
bind:value={searchvalue}
|
bind:value={searchvalue}
|
||||||
placeholder={$_('datatable.search')}
|
placeholder={$_('datatable.search')}
|
||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="mb-4" />
|
||||||
<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">
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import {
|
import {
|
||||||
DonorService
|
DonorService
|
||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { DonorService } from "@odit/lfk-client-js";
|
import { DonorService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from "svelte";
|
||||||
@@ -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();
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={cancelDelete}>
|
on:click_outside={cancelDelete}>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -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}
|
||||||
@@ -201,7 +207,7 @@
|
|||||||
<a
|
<a
|
||||||
href="../donations/{d.id}"
|
href="../donations/{d.id}"
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-600 text-white mr-1">{d.runner.firstname}
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-600 text-white mr-1">{d.runner.firstname}
|
||||||
{d.runner.middlename}
|
{d.runner.middlename || ""}
|
||||||
{d.runner.lastname}</a>
|
{d.runner.lastname}</a>
|
||||||
{:else}
|
{:else}
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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";
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
bind:value={searchvalue}
|
bind:value={searchvalue}
|
||||||
placeholder={$_('datatable.search')}
|
placeholder={$_('datatable.search')}
|
||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="mb-4" />
|
||||||
<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">
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
@@ -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>
|
||||||
@@ -127,7 +132,7 @@
|
|||||||
<a
|
<a
|
||||||
href="../donations/{d.id}"
|
href="../donations/{d.id}"
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-600 text-white mr-1">{d.runner.firstname}
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-600 text-white mr-1">{d.runner.firstname}
|
||||||
{d.runner.middlename}
|
{d.runner.middlename || ''}
|
||||||
{d.runner.lastname}</a>
|
{d.runner.lastname}</a>
|
||||||
{:else}
|
{:else}
|
||||||
<a
|
<a
|
||||||
@@ -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">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
export let modal_open;
|
export let modal_open;
|
||||||
(function () {
|
(function () {
|
||||||
document.onkeydown = function (e) {
|
document.onkeydown = function (e) {
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -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>
|
||||||
-
|
-
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { _, getLocaleFromNavigator } from "svelte-i18n";
|
import { _, getLocaleFromNavigator } from "svelte-i18n";
|
||||||
import marked from "marked";
|
import marked from "marked";
|
||||||
import Footer from "./Footer.svelte";
|
import Footer from "./Footer.svelte";
|
||||||
import * as css from "../base/simple.css";
|
// import * as css from "../base/simple.css?inline";
|
||||||
let html = "";
|
let html = "";
|
||||||
async function load() {
|
async function load() {
|
||||||
let md = await fetch("/privacy_" + getLocaleFromNavigator() + ".md");
|
let md = await fetch("/privacy_" + getLocaleFromNavigator() + ".md");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import { UserGroupService } from "@odit/lfk-client-js";
|
import { UserGroupService } from "@odit/lfk-client-js";
|
||||||
export let modal_open;
|
export let modal_open;
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
bind:value={searchvalue}
|
bind:value={searchvalue}
|
||||||
placeholder={$_('datatable.search')}
|
placeholder={$_('datatable.search')}
|
||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="mb-4" />
|
||||||
<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">
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
export let modal_open;
|
export let modal_open;
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from "svelte";
|
||||||
@@ -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();
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={cancelDelete}>
|
on:click_outside={cancelDelete}>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -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}
|
||||||
@@ -323,14 +326,14 @@
|
|||||||
<div class="flex items-center h-5">
|
<div class="flex items-center h-5">
|
||||||
<input
|
<input
|
||||||
bind:checked={editable.registrationEnabled}
|
bind:checked={editable.registrationEnabled}
|
||||||
id="comments"
|
id="toggle_selfservice_feature"
|
||||||
name="comments"
|
name="toggle_selfservice_feature"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-3 text-sm">
|
<div class="ml-3 text-sm">
|
||||||
<label
|
<label
|
||||||
for="comments"
|
for="toggle_selfservice_feature"
|
||||||
class="font-medium text-gray-700">{$_('selfservice-registration')}</label>
|
class="font-medium text-gray-700">{$_('selfservice-registration')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -372,14 +375,14 @@
|
|||||||
<div class="flex items-center h-5">
|
<div class="flex items-center h-5">
|
||||||
<input
|
<input
|
||||||
bind:checked={editable.address_checked}
|
bind:checked={editable.address_checked}
|
||||||
id="comments"
|
id="toggle_address_checkbox"
|
||||||
name="comments"
|
name="toggle_address_checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-3 text-sm">
|
<div class="ml-3 text-sm">
|
||||||
<label
|
<label
|
||||||
for="comments"
|
for="toggle_address_checkbox"
|
||||||
class="font-medium text-gray-700">{$_('address')}</label>
|
class="font-medium text-gray-700">{$_('address')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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(
|
||||||
@@ -47,7 +51,7 @@
|
|||||||
bind:value={searchvalue}
|
bind:value={searchvalue}
|
||||||
placeholder={$_('datatable.search')}
|
placeholder={$_('datatable.search')}
|
||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="mb-4" />
|
||||||
<div class="h-12">
|
<div class="h-12">
|
||||||
<GenerateSponsoringContracts
|
<GenerateSponsoringContracts
|
||||||
bind:sponsoring_contracts_show
|
bind:sponsoring_contracts_show
|
||||||
@@ -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">
|
||||||
|
|||||||
@@ -1,339 +1,418 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
import {
|
import {
|
||||||
RunnerCardService,
|
RunnerCardService,
|
||||||
RunnerOrganizationService,
|
RunnerOrganizationService,
|
||||||
RunnerTeamService,
|
RunnerTeamService,
|
||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
export let cards_show = false;
|
import { init } from "@paralleldrive/cuid2";
|
||||||
export let generate_cards = [];
|
const createId = init({ length: 10, fingerprint: "lfk-frontend" });
|
||||||
export let generate_runners = [];
|
|
||||||
export let generate_orgs = [];
|
|
||||||
export let generate_teams = [];
|
|
||||||
$: cards_dropdown_open = false;
|
|
||||||
document.addEventListener("click", function (e) {
|
|
||||||
if (
|
|
||||||
e.target.parentNode?.parentNode?.id != "cards:dropdown" &&
|
|
||||||
e.target.parentNode?.parentNode?.id != "cards:dropdown:menu"
|
|
||||||
) {
|
|
||||||
cards_dropdown_open = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function generateRunnerCards(locale) {
|
export let cards_show = false;
|
||||||
cards_dropdown_open = false;
|
export let generate_cards = [];
|
||||||
|
export let generate_runners = [];
|
||||||
|
export let generate_orgs = [];
|
||||||
|
export let generate_teams = [];
|
||||||
|
$: cards_dropdown_open = false;
|
||||||
|
document.addEventListener("click", function (e) {
|
||||||
|
if (
|
||||||
|
e.target.parentNode?.parentNode?.id != "cards:dropdown" &&
|
||||||
|
e.target.parentNode?.parentNode?.id != "cards:dropdown:menu"
|
||||||
|
) {
|
||||||
|
cards_dropdown_open = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (generate_orgs.length > 0) {
|
function generateRunnerCards(locale) {
|
||||||
generateOrgCards(locale);
|
cards_dropdown_open = false;
|
||||||
} else if (generate_teams.length > 0) {
|
|
||||||
generateTeamCards(locale);
|
if (generate_orgs.length > 0) {
|
||||||
} else if (generate_runners.length > 0) {
|
generateOrgCards(locale);
|
||||||
generateRunnersCards(locale);
|
} else if (generate_teams.length > 0) {
|
||||||
|
generateTeamCards(locale);
|
||||||
|
} else if (generate_runners.length > 0) {
|
||||||
|
generateRunnersCards(locale);
|
||||||
|
} else {
|
||||||
|
generateCards(locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateCards(locale) {
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("generating-pdf"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
fetch(
|
||||||
|
`${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(generate_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 {
|
} else {
|
||||||
generateCards(locale);
|
return response.blob();
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
.then((blob) => {
|
||||||
function generateCards(locale) {
|
const url = window.URL.createObjectURL(blob);
|
||||||
const toast = Toastify({
|
let a = document.createElement("a");
|
||||||
text: $_("generating-pdf"),
|
a.href = url;
|
||||||
duration: -1,
|
a.download = `${$_("runnercards")}-${locale}-${createId()}.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();
|
}).showToast();
|
||||||
fetch(
|
})
|
||||||
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
.catch((err) => {
|
||||||
{
|
console.error(err);
|
||||||
method: "POST",
|
});
|
||||||
headers: {
|
}
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(generate_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.pdf";
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
a.remove();
|
|
||||||
toast.hideToast();
|
|
||||||
Toastify({
|
|
||||||
text: $_("pdf-successfully-generated"),
|
|
||||||
duration: 3500,
|
|
||||||
backgroundColor:
|
|
||||||
"linear-gradient(to right, #00b09b, #96c93d)",
|
|
||||||
}).showToast();
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function generateRunnersCards(locale) {
|
async function generateRunnersCards(locale) {
|
||||||
const toast = Toastify({
|
const toast = Toastify({
|
||||||
text: $_("generating-pdf"),
|
text: $_("generating-pdf"),
|
||||||
duration: -1,
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
const current_cards = await RunnerCardService.runnerCardControllerGetAll();
|
||||||
|
let cards = [];
|
||||||
|
for (let runner of generate_runners) {
|
||||||
|
let card = current_cards.find((c) => c.runner?.id == runner.id);
|
||||||
|
if (!card) {
|
||||||
|
card = await RunnerCardService.runnerCardControllerPost({
|
||||||
|
runner: runner.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
cards.push(card);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
if (generate_runners.length == 1) {
|
||||||
|
a.download = `${$_("runnercards")}_${generate_runners[0].firstname}_${
|
||||||
|
generate_runners[0].lastname
|
||||||
|
}-${locale}-${createId()}.pdf`;
|
||||||
|
} else {
|
||||||
|
a.download = `${$_("runnercards")}-${locale}-${createId()}.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();
|
}).showToast();
|
||||||
const current_cards = await RunnerCardService.runnerCardControllerGetAll();
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateTeamCards(locale) {
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("generating-pdfs"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
let count = 0;
|
||||||
|
const current_cards = await RunnerCardService.runnerCardControllerGetAll();
|
||||||
|
for (const t of generate_teams) {
|
||||||
|
const 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);
|
||||||
|
}
|
||||||
|
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) => {
|
||||||
|
count++;
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
a.download = `${$_("runnercards")}_${t.name}-${locale}-${createId()}.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 generateOrgCards(locale) {
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("generating-pdfs"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
const current_cards = await RunnerCardService.runnerCardControllerGetAll();
|
||||||
|
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 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}_direct-${locale}-${createId()}.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 cards = [];
|
let cards = [];
|
||||||
for (let runner of generate_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);
|
||||||
if (!card) {
|
if (!card) {
|
||||||
card = await RunnerCardService.runnerCardControllerPost({
|
card = await RunnerCardService.runnerCardControllerPost({
|
||||||
runner: runner.id,
|
runner: runner.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
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: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
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) => {
|
|
||||||
const url = window.URL.createObjectURL(blob);
|
|
||||||
let a = document.createElement("a");
|
|
||||||
a.href = url;
|
|
||||||
a.download = "Runnercards.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 generateTeamCards(locale) {
|
|
||||||
const toast = Toastify({
|
|
||||||
text: $_("generating-pdfs"),
|
|
||||||
duration: -1,
|
|
||||||
}).showToast();
|
|
||||||
let count = 0;
|
|
||||||
const current_cards = await RunnerCardService.runnerCardControllerGetAll();
|
|
||||||
for await (const t of generate_teams) {
|
|
||||||
const 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);
|
|
||||||
}
|
}
|
||||||
fetch(
|
})
|
||||||
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
.then((blob) => {
|
||||||
{
|
const url = window.URL.createObjectURL(blob);
|
||||||
method: "POST",
|
let a = document.createElement("a");
|
||||||
headers: {
|
a.href = url;
|
||||||
"Content-Type": "application/json",
|
a.download = `${$_("runnercards")}_${o.name}_${
|
||||||
},
|
t.name
|
||||||
body: JSON.stringify(cards),
|
}-${locale}-${createId()}.pdf`;
|
||||||
}
|
document.body.appendChild(a);
|
||||||
)
|
a.click();
|
||||||
.then((response) => {
|
a.remove();
|
||||||
if (response.status != "200") {
|
if (
|
||||||
toast.hideToast();
|
count === o.teams.length &&
|
||||||
Toastify({
|
count_orgs === generate_orgs.length
|
||||||
text: $_("pdf-generation-failed"),
|
) {
|
||||||
duration: 3500,
|
toast.hideToast();
|
||||||
backgroundColor:
|
Toastify({
|
||||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
text: $_("pdfs-successfully-generated"),
|
||||||
}).showToast();
|
duration: 3500,
|
||||||
} else {
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
return response.blob();
|
}).showToast();
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((blob) => {
|
|
||||||
count++;
|
|
||||||
const url = window.URL.createObjectURL(blob);
|
|
||||||
let a = document.createElement("a");
|
|
||||||
a.href = url;
|
|
||||||
a.download = "Sponsorings_" + t.name + ".pdf";
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
a.remove();
|
|
||||||
if (count === generate_teams.length) {
|
|
||||||
toast.hideToast();
|
|
||||||
Toastify({
|
|
||||||
text: $_("pdfs-successfully-generated"),
|
|
||||||
duration: 3500,
|
|
||||||
backgroundColor:
|
|
||||||
"linear-gradient(to right, #00b09b, #96c93d)",
|
|
||||||
}).showToast();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function generateOrgCards(locale) {
|
|
||||||
const toast = Toastify({
|
|
||||||
text: $_("generating-pdf"),
|
|
||||||
duration: -1,
|
|
||||||
}).showToast();
|
|
||||||
let count = 0;
|
|
||||||
const current_cards = await RunnerCardService.runnerCardControllerGetAll();
|
|
||||||
for await (const o of generate_orgs) {
|
|
||||||
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(
|
|
||||||
o.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);
|
|
||||||
}
|
}
|
||||||
fetch(
|
})
|
||||||
`${config.baseurl}/documents/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
.catch((err) => {});
|
||||||
{
|
}
|
||||||
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) => {
|
|
||||||
count++;
|
|
||||||
const url = window.URL.createObjectURL(blob);
|
|
||||||
let a = document.createElement("a");
|
|
||||||
a.href = url;
|
|
||||||
a.download = "Sponsorings_" + o.name + ".pdf";
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
a.remove();
|
|
||||||
if (count === generate_orgs.length) {
|
|
||||||
toast.hideToast();
|
|
||||||
Toastify({
|
|
||||||
text: $_("pdfs-successfully-generated"),
|
|
||||||
duration: 3500,
|
|
||||||
backgroundColor:
|
|
||||||
"linear-gradient(to right, #00b09b, #96c93d)",
|
|
||||||
}).showToast();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if cards_show}
|
{#if cards_show}
|
||||||
<div id="cards:dropdown" class="relative inline-block">
|
<div id="cards:dropdown" class="relative inline-block">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
cards_dropdown_open = !cards_dropdown_open;
|
cards_dropdown_open = !cards_dropdown_open;
|
||||||
}}
|
}}
|
||||||
type="button"
|
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"
|
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"
|
id="options-menu"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="true">
|
aria-expanded="true"
|
||||||
{$_('generate-runnercards')}
|
>
|
||||||
<svg
|
{$_("generate-runnercards")}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<svg
|
||||||
width="24"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
height="24"
|
width="24"
|
||||||
viewBox="0 0 24 24"
|
height="24"
|
||||||
class="-mr-1 ml-2 h-5 w-5"><path
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
class="-mr-1 ml-2 h-5 w-5"
|
||||||
d="M0 0h24v24H0z" />
|
><path fill="none" d="M0 0h24v24H0z" />
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
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>
|
d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z"
|
||||||
</button>
|
/></svg
|
||||||
</div>
|
>
|
||||||
{#if cards_dropdown_open}
|
</button>
|
||||||
<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="cards: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={() => {
|
|
||||||
generateRunnerCards('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={() => {
|
|
||||||
generateRunnerCards('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>
|
</div>
|
||||||
|
{#if cards_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 z-10"
|
||||||
|
id="cards: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={() => {
|
||||||
|
generateRunnerCards("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={() => {
|
||||||
|
generateRunnerCards("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}
|
{/if}
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import {
|
||||||
|
DonationService,
|
||||||
|
RunnerTeamService,
|
||||||
|
RunnerOrganizationService,
|
||||||
|
} from "@odit/lfk-client-js";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import { init } from "@paralleldrive/cuid2";
|
||||||
|
const createId = init({ length: 10, fingerprint: "lfk-frontend" });
|
||||||
|
|
||||||
|
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.filter((d) => d.runner?.id == runner.id) || [];
|
||||||
|
console.log(runner.distanceDonations);
|
||||||
|
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}-${createId()}.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.filter((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}-${createId()}.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.filter((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}-${locale}-${createId()}.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.filter((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}-${createId()}.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 z-10"
|
||||||
|
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}
|
||||||
@@ -1,251 +1,324 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
import { RunnerOrganizationService, RunnerTeamService } from "@odit/lfk-client-js";
|
import {
|
||||||
import Toastify from "toastify-js";
|
RunnerOrganizationService,
|
||||||
export let sponsoring_contracts_show = false;
|
RunnerTeamService,
|
||||||
export let generate_runners = [];
|
} from "@odit/lfk-client-js";
|
||||||
export let generate_orgs = [];
|
import Toastify from "toastify-js";
|
||||||
export let generate_teams = [];
|
import { init } from "@paralleldrive/cuid2";
|
||||||
$: sponsoring_contracts_download_open = false;
|
const createId = init({ length: 10, fingerprint: "lfk-frontend" });
|
||||||
document.addEventListener("click", function (e) {
|
|
||||||
if (
|
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
|
||||||
) {
|
|
||||||
sponsoring_contracts_download_open = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function generateSponsoringContract(locale) {
|
export let sponsoring_contracts_show = false;
|
||||||
sponsoring_contracts_download_open = false;
|
export let generate_runners = [];
|
||||||
|
export let generate_orgs = [];
|
||||||
if (generate_orgs.length > 0) {
|
export let generate_teams = [];
|
||||||
generateOrgContracts(locale);
|
$: sponsoring_contracts_download_open = false;
|
||||||
} else if (generate_teams.length > 0) {
|
document.addEventListener("click", function (e) {
|
||||||
generateTeamContracts(locale);
|
if (
|
||||||
} else {
|
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
||||||
generateRunnerContracts(locale);
|
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
||||||
}
|
) {
|
||||||
|
sponsoring_contracts_download_open = false;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
async function generateTeamContracts(locale) {
|
function generateSponsoringContract(locale) {
|
||||||
const toast = Toastify({
|
sponsoring_contracts_download_open = false;
|
||||||
text: $_("generating-pdfs"),
|
|
||||||
duration: -1,
|
if (generate_orgs.length > 0) {
|
||||||
}).showToast();
|
generateOrgContracts(locale);
|
||||||
let count = 0;
|
} else if (generate_teams.length > 0) {
|
||||||
for await (const t of generate_teams) {
|
generateTeamContracts(locale);
|
||||||
count++;
|
} else {
|
||||||
const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
|
generateRunnerContracts(locale);
|
||||||
t.id
|
|
||||||
);
|
|
||||||
fetch(
|
|
||||||
`${config.baseurl}/documents/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_" + t.name + ".pdf";
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
a.remove();
|
|
||||||
if (count === generate_teams.length) {
|
|
||||||
toast.hideToast();
|
|
||||||
Toastify({
|
|
||||||
text: $_("pdfs-successfully-generated"),
|
|
||||||
duration: 3500,
|
|
||||||
backgroundColor:
|
|
||||||
"linear-gradient(to right, #00b09b, #96c93d)",
|
|
||||||
}).showToast();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function generateOrgContracts(locale) {
|
async function generateTeamContracts(locale) {
|
||||||
const toast = Toastify({
|
const toast = Toastify({
|
||||||
text: $_("generating-pdf"),
|
text: $_("generating-pdfs"),
|
||||||
duration: -1,
|
duration: -1,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
for await (const o of generate_orgs) {
|
let count = 0;
|
||||||
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(
|
for (const t of generate_teams) {
|
||||||
o.id
|
count++;
|
||||||
);
|
const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
|
||||||
fetch(
|
t.id
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
);
|
||||||
{
|
fetch(
|
||||||
method: "POST",
|
`${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
||||||
headers: {
|
{
|
||||||
"Content-Type": "application/json",
|
method: "POST",
|
||||||
},
|
headers: {
|
||||||
body: JSON.stringify(runners),
|
"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) => {
|
|
||||||
count++;
|
|
||||||
const url = window.URL.createObjectURL(blob);
|
|
||||||
let a = document.createElement("a");
|
|
||||||
a.href = url;
|
|
||||||
a.download = "Sponsorings_" + o.name + ".pdf";
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
a.remove();
|
|
||||||
if (count === generate_orgs.length) {
|
|
||||||
toast.hideToast();
|
|
||||||
Toastify({
|
|
||||||
text: $_("pdfs-successfully-generated"),
|
|
||||||
duration: 3500,
|
|
||||||
backgroundColor:
|
|
||||||
"linear-gradient(to right, #00b09b, #96c93d)",
|
|
||||||
}).showToast();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {});
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
.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")}_${t.name}-${locale}-${createId()}.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) => {});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function generateRunnerContracts(locale) {
|
async function generateOrgContracts(locale) {
|
||||||
const toast = Toastify({
|
const toast = Toastify({
|
||||||
text: $_("generating-pdf"),
|
text: $_("generating-pdf"),
|
||||||
duration: -1,
|
duration: -1,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
fetch(
|
let count_orgs = 0;
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
for (const o of generate_orgs) {
|
||||||
{
|
count_orgs++;
|
||||||
method: "POST",
|
let count = 0;
|
||||||
headers: {
|
let runners =
|
||||||
"Content-Type": "application/json",
|
await RunnerOrganizationService.runnerOrganizationControllerGetRunners(
|
||||||
},
|
o.id,
|
||||||
body: JSON.stringify(generate_runners),
|
true
|
||||||
}
|
);
|
||||||
|
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}_direct-${locale}-${createId()}.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
|
||||||
|
);
|
||||||
|
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) => {
|
.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) => {
|
||||||
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";
|
a.download = `${$_("sponsorings")}_${o.name}_${
|
||||||
document.body.appendChild(a);
|
t.name
|
||||||
a.click();
|
}-${locale}-${createId()}.pdf`;
|
||||||
a.remove();
|
document.body.appendChild(a);
|
||||||
toast.hideToast();
|
a.click();
|
||||||
Toastify({
|
a.remove();
|
||||||
text: $_("pdf-successfully-generated"),
|
if (
|
||||||
duration: 3500,
|
count === o.teams.length &&
|
||||||
backgroundColor:
|
count_orgs === generate_orgs.length
|
||||||
"linear-gradient(to right, #00b09b, #96c93d)",
|
) {
|
||||||
}).showToast();
|
toast.hideToast();
|
||||||
})
|
Toastify({
|
||||||
.catch((err) => {
|
text: $_("pdfs-successfully-generated"),
|
||||||
console.error(err);
|
duration: 3500,
|
||||||
});
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateRunnerContracts(locale) {
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("generating-pdf"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
fetch(
|
||||||
|
`${config.baseurl_documentserver}/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(generate_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;
|
||||||
|
if (generate_runners.length == 1) {
|
||||||
|
a.download = `${$_("sponsorings")}_${generate_runners[0].firstname}_${
|
||||||
|
generate_runners[0].lastname
|
||||||
|
}-${locale}-${createId()}.pdf`;
|
||||||
|
}
|
||||||
|
a.download = `${$_("sponsorings")}-${locale}-${createId()}.pdf`;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
toast.hideToast();
|
||||||
|
Toastify({
|
||||||
|
text: $_("pdf-successfully-generated"),
|
||||||
|
duration: 3500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if sponsoring_contracts_show}
|
{#if sponsoring_contracts_show}
|
||||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
<div id="sponsoring:dropdown" class="relative inline-block">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
sponsoring_contracts_download_open =
|
||||||
}}
|
!sponsoring_contracts_download_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"
|
type="button"
|
||||||
id="options-menu"
|
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"
|
||||||
aria-haspopup="true"
|
id="options-menu"
|
||||||
aria-expanded="true">
|
aria-haspopup="true"
|
||||||
{$_('generate-sponsoring-contracts')}
|
aria-expanded="true"
|
||||||
<svg
|
>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
{$_("generate-sponsoring-contracts")}
|
||||||
width="24"
|
<svg
|
||||||
height="24"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 24 24"
|
width="24"
|
||||||
class="-mr-1 ml-2 h-5 w-5"><path
|
height="24"
|
||||||
fill="none"
|
viewBox="0 0 24 24"
|
||||||
d="M0 0h24v24H0z" />
|
class="-mr-1 ml-2 h-5 w-5"
|
||||||
<path
|
><path fill="none" d="M0 0h24v24H0z" />
|
||||||
fill="currentColor"
|
<path
|
||||||
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>
|
fill="currentColor"
|
||||||
</button>
|
d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z"
|
||||||
</div>
|
/></svg
|
||||||
{#if sponsoring_contracts_download_open}
|
>
|
||||||
<div
|
</button>
|
||||||
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="sponsoring: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={() => {
|
|
||||||
generateSponsoringContract('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={() => {
|
|
||||||
generateSponsoringContract('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>
|
</div>
|
||||||
|
{#if sponsoring_contracts_download_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 z-10"
|
||||||
|
id="sponsoring: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={() => {
|
||||||
|
generateSponsoringContract("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={() => {
|
||||||
|
generateSponsoringContract("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}
|
{/if}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { _, json } from "svelte-i18n";
|
|
||||||
import { getlang } from "./datatable_i18n";
|
|
||||||
import { Grid } from "gridjs";
|
|
||||||
//
|
|
||||||
let table;
|
|
||||||
const datatable = new Grid({
|
|
||||||
columns: ["Name", "Email", "Phone Number"],
|
|
||||||
language: getlang($json("datatable")),
|
|
||||||
sort: true,
|
|
||||||
search: { enabled: true },
|
|
||||||
data: [
|
|
||||||
["John", "john@example.com", "(353) 01 222 3333"],
|
|
||||||
["Mark", "mark@gmail.com", "(01) 22 888 4444"],
|
|
||||||
["Eoin", "eoin@gmail.com", "0097 22 654 00033"],
|
|
||||||
["Sarah", "sarahcdd@gmail.com", "+322 876 1233"],
|
|
||||||
["Afshin", "afshin@mail.com", "(353) 22 87 8356"],
|
|
||||||
],
|
|
||||||
pagination: {
|
|
||||||
enabled: true,
|
|
||||||
limit: 2,
|
|
||||||
summary: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
setTimeout(() => {
|
|
||||||
datatable.render(table);
|
|
||||||
}, 0);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div bind:this={table} />
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import {
|
import {
|
||||||
RunnerService,
|
RunnerService,
|
||||||
RunnerTeamService,
|
RunnerTeamService,
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { read as readXlsx, utils as xlsx_utils } from "xlsx";
|
import { read as readXlsx, utils as xlsx_utils } from "xlsx";
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import {
|
import {
|
||||||
ImportService,
|
ImportService,
|
||||||
@@ -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();
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
{#if import_modal_open}
|
{#if import_modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
cancelModal();
|
cancelModal();
|
||||||
@@ -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'}
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -69,6 +71,9 @@
|
|||||||
}).showToast();
|
}).showToast();
|
||||||
let postdata = {};
|
let postdata = {};
|
||||||
postdata = Object.assign(postdata, editable);
|
postdata = Object.assign(postdata, editable);
|
||||||
|
if (postdata.phone === "") {
|
||||||
|
postdata.phone = null;
|
||||||
|
}
|
||||||
RunnerService.runnerControllerPut(original_data.id, postdata)
|
RunnerService.runnerControllerPut(original_data.id, postdata)
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
Object.assign(original_data, editable);
|
Object.assign(original_data, editable);
|
||||||
@@ -93,7 +98,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#await runner_promise}
|
{#await runner_promise}
|
||||||
{$_('loading-runners')}
|
{$_("loading-runners")}
|
||||||
{:then}
|
{:then}
|
||||||
<section class="container p-5 select-none">
|
<section class="container p-5 select-none">
|
||||||
<div class="flex flex-row mb-4">
|
<div class="flex flex-row mb-4">
|
||||||
@@ -107,12 +112,15 @@
|
|||||||
class="flex-shrink-0 w-5 h-5 mr-2"
|
class="flex-shrink-0 w-5 h-5 mr-2"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
width="24"
|
width="24"
|
||||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
height="24"
|
||||||
|
><path fill="none" d="M0 0h24v24H0z" />
|
||||||
<path
|
<path
|
||||||
d="M9.83 8.79L8 9.456V13H6V8.05h.015l5.268-1.918c.244-.093.51-.14.782-.131a2.616 2.616 0 0 1 2.427 1.82c.186.583.356.977.51 1.182A4.992 4.992 0 0 0 19 11v2a6.986 6.986 0 0 1-5.402-2.547l-.581 3.297L15 15.67V23h-2v-5.986l-2.05-1.987-.947 4.298-6.894-1.215.348-1.97 4.924.868L9.83 8.79zM13.5 5.5a2 2 0 1 1 0-4 2 2 0 0 1 0 4z" /></svg>
|
d="M9.83 8.79L8 9.456V13H6V8.05h.015l5.268-1.918c.244-.093.51-.14.782-.131a2.616 2.616 0 0 1 2.427 1.82c.186.583.356.977.51 1.182A4.992 4.992 0 0 0 19 11v2a6.986 6.986 0 0 1-5.402-2.547l-.581 3.297L15 15.67V23h-2v-5.986l-2.05-1.987-.947 4.298-6.894-1.215.348-1.97 4.924.868L9.83 8.79zM13.5 5.5a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex items-center">
|
<li class="flex items-center">
|
||||||
<a class="mr-2" href="./">{$_('runners')}</a><svg
|
<a class="mr-2" href="./">{$_("runners")}</a><svg
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
@@ -122,17 +130,17 @@
|
|||||||
class="h-3 w-3 mr-2 stroke-current"
|
class="h-3 w-3 mr-2 stroke-current"
|
||||||
height="1em"
|
height="1em"
|
||||||
width="1em"
|
width="1em"
|
||||||
xmlns="http://www.w3.org/2000/svg"><line
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
x1="5"
|
><line x1="5" y1="12" x2="19" y2="12" />
|
||||||
y1="12"
|
<polyline points="12 5 19 12 12 19" /></svg
|
||||||
x2="19"
|
>
|
||||||
y2="12" />
|
|
||||||
<polyline points="12 5 19 12 12 19" /></svg>
|
|
||||||
</li>
|
</li>
|
||||||
<li class="flex items-center">
|
<li class="flex items-center">
|
||||||
<span class="mr-2">{original_data.firstname}
|
<span class="mr-2"
|
||||||
{original_data.middlename || ''}
|
>{original_data.firstname}
|
||||||
{original_data.lastname}</span>
|
{original_data.middlename || ""}
|
||||||
|
{original_data.lastname}</span
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
@@ -140,33 +148,42 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||||
{original_data.firstname}
|
{original_data.firstname}
|
||||||
{original_data.middlename || ''}
|
{original_data.middlename || ""}
|
||||||
{original_data.lastname}
|
{original_data.lastname}
|
||||||
<span data-id="runner_actions_${editable.id}">
|
<span data-id="runner_actions_${editable.id}">
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:DELETE")}
|
||||||
{#if delete_triggered}
|
{#if delete_triggered}
|
||||||
<button
|
<button
|
||||||
on:click={deleteRunner}
|
on:click={deleteRunner}
|
||||||
class="w-full justify-center 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 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-deletion')}</button>
|
class="w-full justify-center 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 sm:ml-3 sm:w-auto sm:text-sm"
|
||||||
|
>{$_("confirm-deletion")}</button
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
delete_triggered = !delete_triggered;
|
delete_triggered = !delete_triggered;
|
||||||
}}
|
}}
|
||||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button>
|
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm"
|
||||||
|
>{$_("cancel")}</button
|
||||||
|
>
|
||||||
{/if}
|
{/if}
|
||||||
<GenerateSponsoringContracts
|
<GenerateSponsoringContracts
|
||||||
bind:sponsoring_contracts_show
|
bind:sponsoring_contracts_show
|
||||||
bind:generate_runners />
|
bind:generate_runners
|
||||||
<GenerateRunnerCards
|
/>
|
||||||
bind:sponsoring_contracts_show
|
<GenerateRunnerCards bind:cards_show bind:generate_runners />
|
||||||
bind:generate_runners />
|
<GenerateRunnerCertificates
|
||||||
|
bind:certificates_show
|
||||||
|
bind:generate_runners
|
||||||
|
/>
|
||||||
{#if !delete_triggered}
|
{#if !delete_triggered}
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
delete_triggered = true;
|
delete_triggered = true;
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
class="w-full justify-center 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 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-runner')}</button>
|
class="w-full justify-center 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 sm:ml-3 sm:w-auto sm:text-sm"
|
||||||
|
>{$_("delete-runner")}</button
|
||||||
|
>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
{#if !delete_triggered}
|
{#if !delete_triggered}
|
||||||
@@ -175,121 +192,128 @@
|
|||||||
class:opacity-50={!save_enabled}
|
class:opacity-50={!save_enabled}
|
||||||
type="button"
|
type="button"
|
||||||
on:click={submit}
|
on:click={submit}
|
||||||
class="w-full 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>
|
class="w-full 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
|
||||||
|
>
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<div class="text-sm w-full">
|
<div class="text-sm w-full">
|
||||||
<label
|
<label for="firstname" class="font-medium text-gray-700"
|
||||||
for="firstname"
|
>{$_("first-name")}</label
|
||||||
class="font-medium text-gray-700">{$_('first-name')}</label>
|
>
|
||||||
<input
|
<input
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder={$_('first-name')}
|
placeholder={$_("first-name")}
|
||||||
type="text"
|
type="text"
|
||||||
class:border-red-500={!isFirstnameValid}
|
class:border-red-500={!isFirstnameValid}
|
||||||
class:focus:border-red-500={!isFirstnameValid}
|
class:focus:border-red-500={!isFirstnameValid}
|
||||||
class:focus:ring-red-500={!isFirstnameValid}
|
class:focus:ring-red-500={!isFirstnameValid}
|
||||||
bind:value={editable.firstname}
|
bind:value={editable.firstname}
|
||||||
name="firstname"
|
name="firstname"
|
||||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||||
|
/>
|
||||||
{#if !isFirstnameValid}
|
{#if !isFirstnameValid}
|
||||||
<span
|
<span
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
|
||||||
{$_('first-name-is-required')}
|
>
|
||||||
|
{$_("first-name-is-required")}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm w-full">
|
<div class="text-sm w-full">
|
||||||
<label
|
<label for="middlename" class="font-medium text-gray-700"
|
||||||
for="middlename"
|
>{$_("middle-name")}</label
|
||||||
class="font-medium text-gray-700">{$_('middle-name')}</label>
|
>
|
||||||
<input
|
<input
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder={$_('middle-name')}
|
placeholder={$_("middle-name")}
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={editable.middlename}
|
bind:value={editable.middlename}
|
||||||
name="middlename"
|
name="middlename"
|
||||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm w-full">
|
<div class="text-sm w-full">
|
||||||
<label
|
<label for="lastname" class="font-medium text-gray-700"
|
||||||
for="lastname"
|
>{$_("last-name")}</label
|
||||||
class="font-medium text-gray-700">{$_('last-name')}</label>
|
>
|
||||||
<input
|
<input
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder={$_('last-name')}
|
placeholder={$_("last-name")}
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={editable.lastname}
|
bind:value={editable.lastname}
|
||||||
class:border-red-500={!isLastnameValid}
|
class:border-red-500={!isLastnameValid}
|
||||||
class:focus:border-red-500={!isLastnameValid}
|
class:focus:border-red-500={!isLastnameValid}
|
||||||
class:focus:ring-red-500={!isLastnameValid}
|
class:focus:ring-red-500={!isLastnameValid}
|
||||||
name="lastname"
|
name="lastname"
|
||||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||||
|
/>
|
||||||
{#if !isLastnameValid}
|
{#if !isLastnameValid}
|
||||||
<span
|
<span
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
|
||||||
{$_('last-name-is-required')}
|
>
|
||||||
|
{$_("last-name-is-required")}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm w-full">
|
<div class="text-sm w-full">
|
||||||
<label
|
<label for="email" class="font-medium text-gray-700"
|
||||||
for="email"
|
>{$_("e-mail-adress")}</label
|
||||||
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
|
>
|
||||||
<input
|
<input
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder={$_('e-mail-adress')}
|
placeholder={$_("e-mail-adress")}
|
||||||
type="email"
|
type="email"
|
||||||
bind:value={editable.email}
|
bind:value={editable.email}
|
||||||
class:border-red-500={!isEmailValid}
|
class:border-red-500={!isEmailValid}
|
||||||
class:focus:border-red-500={!isEmailValid}
|
class:focus:border-red-500={!isEmailValid}
|
||||||
class:focus:ring-red-500={!isEmailValid}
|
class:focus:ring-red-500={!isEmailValid}
|
||||||
name="email"
|
name="email"
|
||||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||||
|
/>
|
||||||
{#if !isEmailValid}
|
{#if !isEmailValid}
|
||||||
<span
|
<span
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
|
||||||
{$_('valid-email-is-required')}
|
>
|
||||||
|
{$_("valid-email-is-required")}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm w-full">
|
<div class="text-sm w-full">
|
||||||
<label for="phone" class="font-medium text-gray-700">{$_('phone')}</label>
|
<label for="phone" class="font-medium text-gray-700">{$_("phone")}</label>
|
||||||
<input
|
<input
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder={$_('phone')}
|
placeholder={$_("phone")}
|
||||||
type="tel"
|
type="tel"
|
||||||
bind:value={editable.phone}
|
bind:value={editable.phone}
|
||||||
name="phone"
|
name="phone"
|
||||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm w-full">
|
<div class="text-sm w-full">
|
||||||
<span class="font-medium text-gray-700">{$_('group')}</span>
|
<span class="font-medium text-gray-700">{$_("group")}</span>
|
||||||
<Select
|
<Select
|
||||||
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
containerClasses="rounded-l-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
|
||||||
itemFilter={(label, filterText, option) => label
|
itemFilter={(label, filterText, option) =>
|
||||||
.toLowerCase()
|
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||||
.includes(
|
option.id.value.toString().startsWith(filterText.toLowerCase())}
|
||||||
filterText.toLowerCase()
|
|
||||||
) || option.id.value
|
|
||||||
.toString()
|
|
||||||
.startsWith(filterText.toLowerCase())}
|
|
||||||
items={groups}
|
items={groups}
|
||||||
showChevron={true}
|
showChevron={true}
|
||||||
placeholder={$_('search-for-an-organization-or-team-by-name-or-id')}
|
placeholder={$_("search-for-an-organization-or-team-by-name-or-id")}
|
||||||
noOptionsMessage={$_('no-organization-or-team-found')}
|
noOptionsMessage={$_("no-organization-or-team-found")}
|
||||||
bind:selectedValue={group}
|
bind:selectedValue={group}
|
||||||
on:select={(selectedValue) => {
|
on:select={(selectedValue) => {
|
||||||
editable.group = selectedValue.detail.value.id;
|
editable.group = selectedValue.detail.value.id;
|
||||||
}}
|
}}
|
||||||
on:clear={() => (editable.group = null)} />
|
on:clear={() => (editable.group = null)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm w-full">
|
<div class="text-sm w-full">
|
||||||
<span class="font-medium text-gray-700">{$_('distance')}</span>
|
<span class="font-medium text-gray-700">{$_("distance")}</span>
|
||||||
<br />
|
<br />
|
||||||
<span class="text-gray-700">{original_data.distance} km</span>
|
<span class="text-gray-700">{original_data.distance / 1000} km</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{:catch error}
|
{:catch error}
|
||||||
|
|||||||
@@ -1,33 +1,82 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
|
let tablePageCount = [25, 50, 100, 250, 500];
|
||||||
|
import { writable } from "svelte/store";
|
||||||
|
import {
|
||||||
|
createSvelteTable,
|
||||||
|
flexRender,
|
||||||
|
getCoreRowModel,
|
||||||
|
getFilteredRowModel,
|
||||||
|
getPaginationRowModel,
|
||||||
|
getSortedRowModel,
|
||||||
|
} from "@tanstack/svelte-table";
|
||||||
import {
|
import {
|
||||||
RunnerService,
|
RunnerService,
|
||||||
RunnerTeamService,
|
RunnerTeamService,
|
||||||
RunnerOrganizationService,
|
RunnerOrganizationService,
|
||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
import store from "../../store";
|
import store from "../../store";
|
||||||
import RunnersEmptyState from "./RunnersEmptyState.svelte";
|
|
||||||
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";
|
||||||
$: searchvalue = "";
|
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import InputElement from "../shared/InputElement.svelte";
|
||||||
|
import { groupFilter } from "../shared/tablefilters";
|
||||||
|
|
||||||
|
$: selectedRunners =
|
||||||
|
$table?.getSelectedRowModel().rows.map((row) => row.original) || [];
|
||||||
|
$: selected =
|
||||||
|
$table?.getSelectedRowModel().rows.map((row) => row.index) || [];
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
accessorKey: "id",
|
||||||
|
header: () => "id",
|
||||||
|
filterFn: `equalsString`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "firstname",
|
||||||
|
header: () => $_("first-name"),
|
||||||
|
filterFn: `includesString`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "lastname",
|
||||||
|
header: () => $_("last-name"),
|
||||||
|
filterFn: `includesString`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "group",
|
||||||
|
header: () => $_("group"),
|
||||||
|
cell: (info) => {
|
||||||
|
const group = info.getValue();
|
||||||
|
if (group.responseType === "RUNNERORGANIZATION") {
|
||||||
|
return group.name;
|
||||||
|
}
|
||||||
|
return `${group.parentGroup.name} > ${group.name}`;
|
||||||
|
},
|
||||||
|
filterFn: `group`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "distance",
|
||||||
|
header: () => $_("distance"),
|
||||||
|
cell: (info) => {
|
||||||
|
if (info.getValue() < 1000) {
|
||||||
|
return `${info.getValue()} m`;
|
||||||
|
}
|
||||||
|
return `${(info.getValue() / 1000).toFixed(1)} km`;
|
||||||
|
},
|
||||||
|
enableColumnFilter: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
$: active_deletes = [];
|
$: active_deletes = [];
|
||||||
|
let dataLoaded = false;
|
||||||
export let current_runners = [];
|
export let current_runners = [];
|
||||||
const runners_promise = RunnerService.runnerControllerGetAll().then((val) => {
|
$: sponsoring_contracts_show = selected.length > 0;
|
||||||
current_runners = val;
|
$: cards_show = selected.length > 0;
|
||||||
});
|
$: certificates_show = selected.length > 0;
|
||||||
$: selectedFilter_teams = null;
|
|
||||||
$: selectedFilter = null;
|
|
||||||
$: filter__teams = selectedFilter_teams || [];
|
|
||||||
$: filter__orgs = selectedFilter || [];
|
|
||||||
$: filterGroupIDs = filter__teams.concat(filter__orgs).map((i) => i.value);
|
|
||||||
$: sponsoring_contracts_show = current_runners.some(
|
|
||||||
(r) => r.is_selected === true
|
|
||||||
);
|
|
||||||
$: cards_show = current_runners.some(
|
|
||||||
(r) => r.is_selected === true
|
|
||||||
);
|
|
||||||
$: generate_runners = current_runners.filter((r) => r.is_selected === true);
|
|
||||||
$: teams = [];
|
$: teams = [];
|
||||||
$: orgs = [];
|
$: orgs = [];
|
||||||
$: mappedteams = teams.map(function (g) {
|
$: mappedteams = teams.map(function (g) {
|
||||||
@@ -38,219 +87,245 @@
|
|||||||
return { value: g.id, label: g.name };
|
return { value: g.id, label: g.name };
|
||||||
})
|
})
|
||||||
.concat(mappedteams);
|
.concat(mappedteams);
|
||||||
|
const options = writable({
|
||||||
|
data: [],
|
||||||
|
columns: columns,
|
||||||
|
filterFns: {
|
||||||
|
group: groupFilter,
|
||||||
|
},
|
||||||
|
initialState: {
|
||||||
|
pagination: {
|
||||||
|
pageSize: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
enableRowSelection: true,
|
||||||
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
getFilteredRowModel: getFilteredRowModel(),
|
||||||
|
getPaginationRowModel: getPaginationRowModel(),
|
||||||
|
getSortedRowModel: getSortedRowModel(),
|
||||||
|
});
|
||||||
|
const table = createSvelteTable(options);
|
||||||
|
onMount(() => {
|
||||||
|
RunnerService.runnerControllerGetAll().then((val) => {
|
||||||
|
current_runners = val;
|
||||||
|
dataLoaded = true;
|
||||||
|
|
||||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
options.update((options) => ({
|
||||||
teams = val;
|
...options,
|
||||||
|
data: current_runners,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||||
|
teams = val;
|
||||||
|
});
|
||||||
|
RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
|
||||||
|
(val) => {
|
||||||
|
orgs = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
|
||||||
orgs = val;
|
|
||||||
});
|
|
||||||
function should_display_based_on_id(id) {
|
|
||||||
if (searchvalue.toString().slice(-1) === "*") {
|
|
||||||
return id.toString().startsWith(searchvalue.replace("*", ""));
|
|
||||||
}
|
|
||||||
return id.toString() === searchvalue;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:GET")}
|
||||||
{#await runners_promise}
|
{#if !dataLoaded}
|
||||||
<div
|
<div
|
||||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||||
role="alert">
|
role="alert"
|
||||||
<p class="font-bold">{$_('runners-are-being-loaded')}</p>
|
>
|
||||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
<p class="font-bold">{$_("runners-are-being-loaded")}</p>
|
||||||
|
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
|
||||||
</div>
|
</div>
|
||||||
{:then}
|
{:else}
|
||||||
{#if current_runners.length === 0}
|
<div class="h-12 mt-2">
|
||||||
<RunnersEmptyState />
|
<GenerateSponsoringContracts
|
||||||
{:else}
|
bind:sponsoring_contracts_show
|
||||||
<input
|
bind:generate_runners={selectedRunners}
|
||||||
type="search"
|
/>
|
||||||
bind:value={searchvalue}
|
<GenerateRunnerCards
|
||||||
placeholder={$_('datatable.search')}
|
bind:cards_show
|
||||||
aria-label={$_('datatable.search')}
|
bind:generate_runners={selectedRunners}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
/>
|
||||||
<div class="block mb-6">
|
<GenerateRunnerCertificates
|
||||||
<label
|
bind:certificates_show
|
||||||
for="country"
|
bind:generate_runners={selectedRunners}
|
||||||
class="text-sm font-medium text-gray-700">{$_('filter-by-organization-team')}</label>
|
/>
|
||||||
<Select
|
</div>
|
||||||
on:select={(event) => {
|
<table class="w-full">
|
||||||
selectedFilter = event.detail;
|
<thead>
|
||||||
}}
|
{#each $table.getHeaderGroups() as headerGroup}
|
||||||
selectedValue={selectedFilter}
|
<tr class="select-none">
|
||||||
placeholder={$_('filter-by-organization-team')}
|
<th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
|
||||||
containerClasses="mt-1 py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
<InputElement
|
||||||
items={selectgroups}
|
type="checkbox"
|
||||||
isMulti={true} />
|
checked={$table.getIsAllRowsSelected()}
|
||||||
</div>
|
indeterminate={$table.getIsSomeRowsSelected()}
|
||||||
<div class="h-12">
|
on:change={() => $table.toggleAllRowsSelected()}
|
||||||
<GenerateSponsoringContracts
|
/>
|
||||||
bind:sponsoring_contracts_show
|
</th>
|
||||||
bind:generate_runners />
|
{#each headerGroup.headers as header}
|
||||||
<GenerateRunnerCards
|
<th class="cursor-pointer">
|
||||||
bind:cards_show
|
{#if !header.isPlaceholder}
|
||||||
bind:generate_runners />
|
<div on:click={header.column.getToggleSortingHandler()}>
|
||||||
</div>
|
<svelte:component
|
||||||
<div
|
this={flexRender(
|
||||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
header.column.columnDef.header,
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
header.getContext()
|
||||||
<thead class="bg-gray-50">
|
)}
|
||||||
<tr>
|
/>
|
||||||
<th
|
{#if header.column.getIsSorted().toString() == "asc"}
|
||||||
scope="col"
|
🔼
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
{:else if header.column.getIsSorted().toString() == "desc"}
|
||||||
<span
|
🔽
|
||||||
on:click={() => {
|
|
||||||
const newstate = !current_runners.some((r) => r.is_selected === true);
|
|
||||||
current_runners = current_runners.map((r) => {
|
|
||||||
r.is_selected = newstate;
|
|
||||||
return r;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
class="underline cursor-pointer select-none">{#if current_runners.some((r) => r.is_selected === true)}
|
|
||||||
{$_('deselect-all')}
|
|
||||||
{:else}{$_('select-all')}{/if}
|
|
||||||
</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
scope="col"
|
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{$_('name')}
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
scope="col"
|
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{$_('contact-information')}
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
scope="col"
|
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{$_('group')}
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
scope="col"
|
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{$_('distance-in-km')}
|
|
||||||
</th>
|
|
||||||
<th scope="col" class="relative px-6 py-3">
|
|
||||||
<span class="sr-only">{$_('action')}</span>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="divide-y divide-gray-200">
|
|
||||||
{#each current_runners as runner}
|
|
||||||
{#if runner.firstname
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
searchvalue.toLowerCase()
|
|
||||||
) || runner.lastname
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
searchvalue.toLowerCase()
|
|
||||||
) || should_display_based_on_id(runner.id)}
|
|
||||||
{#if filterGroupIDs.includes(runner.group.id) || filterGroupIDs.includes(runner.group.parentGroup?.id) || filterGroupIDs.length === 0}
|
|
||||||
<tr
|
|
||||||
data-rowid="user_{runner.id}"
|
|
||||||
data-groupid={runner.group.id}>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
<input
|
|
||||||
bind:checked={runner.is_selected}
|
|
||||||
type="checkbox"
|
|
||||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="ml-4">
|
|
||||||
<div class="text-sm font-medium text-gray-900">
|
|
||||||
{runner.firstname}
|
|
||||||
{runner.middlename || ''}
|
|
||||||
{runner.lastname}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
{#if runner.email}
|
|
||||||
<div class="text-sm text-gray-500">{runner.email}</div>
|
|
||||||
{/if}
|
|
||||||
{#if runner.phone}
|
|
||||||
<div class="text-sm text-gray-500">{runner.phone}</div>
|
|
||||||
{/if}
|
|
||||||
{#if runner.address.address1 !== null}
|
|
||||||
{runner.address.address1}<br />
|
|
||||||
{runner.address.address2 || ''}<br />
|
|
||||||
{runner.address.postalcode}
|
|
||||||
{runner.address.city}
|
|
||||||
{runner.address.country}
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
{#if runner.group.responseType === 'RUNNERTEAM'}
|
|
||||||
<a
|
|
||||||
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>
|
|
||||||
{/if}
|
|
||||||
{#if runner.group.responseType === 'RUNNERORGANIZATION'}
|
|
||||||
<a
|
|
||||||
href="../orgs/{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>
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
{runner.distance}
|
|
||||||
</td>
|
|
||||||
{#if active_deletes[runner.id] === true}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[runner.id] = false;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
RunnerService.runnerControllerRemove(runner.id, true)
|
|
||||||
.then((resp) => {
|
|
||||||
current_runners = current_runners.filter((obj) => obj.id !== runner.id);
|
|
||||||
})
|
|
||||||
.catch((err) => {});
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
|
||||||
</td>
|
|
||||||
{:else}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<a
|
|
||||||
href="./{runner.id}"
|
|
||||||
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[runner.id] = true;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
{/if}
|
{/if}
|
||||||
</tr>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{#if header.column.getCanFilter()}
|
||||||
|
<div class="relative max-w-xs">
|
||||||
|
<input
|
||||||
|
title="name-search"
|
||||||
|
value={header.column.getFilterValue() || ""}
|
||||||
|
on:keyup={(e) => {
|
||||||
|
header.column.setFilterValue(e.target.value);
|
||||||
|
}}
|
||||||
|
type="text"
|
||||||
|
class="block rounded-md border-gray-200 py-2 pl-8 text-xs focus:border-blue-500 focus:ring-blue-500"
|
||||||
|
placeholder=""
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="h-3.5 w-3.5 text-gray-400"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</th>
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
{/each}
|
||||||
</div>
|
</thead>
|
||||||
{/if}
|
<tbody>
|
||||||
{:catch error}
|
{#each $table.getRowModel().rows as row}
|
||||||
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
<tr>
|
||||||
<span class="inline-block align-middle mr-8">
|
<td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
|
||||||
<b class="capitalize">{$_('general_promise_error')}</b>
|
<InputElement
|
||||||
{error}
|
type="checkbox"
|
||||||
|
checked={row.getIsSelected()}
|
||||||
|
on:change={() => row.toggleSelected()}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
{#each row.getVisibleCells() as cell}
|
||||||
|
<td>
|
||||||
|
<svelte:component
|
||||||
|
this={flexRender(
|
||||||
|
cell.column.columnDef.cell,
|
||||||
|
cell.getContext()
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
{/each}
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="h-2" />
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<button
|
||||||
|
class="border rounded p-1"
|
||||||
|
on:click={() => $table.setPageIndex(0)}
|
||||||
|
disabled={!$table.getCanPreviousPage()}
|
||||||
|
>
|
||||||
|
{"<<"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="border rounded p-1"
|
||||||
|
on:click={() => $table.previousPage()}
|
||||||
|
disabled={!$table.getCanPreviousPage()}
|
||||||
|
>
|
||||||
|
{"<"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="border rounded p-1"
|
||||||
|
on:click={() => $table.nextPage()}
|
||||||
|
disabled={!$table.getCanNextPage()}
|
||||||
|
>
|
||||||
|
{">"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="border rounded p-1"
|
||||||
|
on:click={() => $table.setPageIndex($table.getPageCount() - 1)}
|
||||||
|
disabled={!$table.getCanNextPage()}
|
||||||
|
>
|
||||||
|
{">>"}
|
||||||
|
</button>
|
||||||
|
<span class="flex items-center gap-1">
|
||||||
|
<div>Page</div>
|
||||||
|
<strong>
|
||||||
|
{$table.getState().pagination.pageIndex + 1} of{" "}
|
||||||
|
{$table.getPageCount()}
|
||||||
|
</strong>
|
||||||
</span>
|
</span>
|
||||||
|
<span class="flex items-center gap-1">
|
||||||
|
| Go to page:
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
defaultValue={$table.getState().pagination.pageIndex + 1}
|
||||||
|
on:change={(e) => {
|
||||||
|
const page = e.target.value ? Number(e.target.value) - 1 : 0;
|
||||||
|
$table.setPageIndex(page);
|
||||||
|
}}
|
||||||
|
class="border p-1 rounded w-16"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<select
|
||||||
|
value={$table.getState().pagination.pageSize}
|
||||||
|
on:input={(e) => {
|
||||||
|
const ps = Number(e.target.value);
|
||||||
|
console.log({ ps });
|
||||||
|
$table.setPageSize(Number(e.target.value));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#each tablePageCount as pageSize}
|
||||||
|
<option value={pageSize}>{pageSize}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
{/await}
|
<!-- <pre>{JSON.stringify($table.getState(), null, 2)}</pre> -->
|
||||||
|
<div>
|
||||||
|
{Object.keys(selected).length} of{" "}
|
||||||
|
{$table.getPreFilteredRowModel().rows.length} Total Rows Selected
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
thead {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
thead {
|
||||||
|
position: sticky;
|
||||||
|
inset-block-start: 0;
|
||||||
|
}
|
||||||
|
tbody td {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
tbody tr:nth-child(even) {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
tbody tr {
|
||||||
|
transition: all, 0.2s;
|
||||||
|
}
|
||||||
|
tbody tr:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
export let groups;
|
||||||
|
export let handler;
|
||||||
|
let selected = "all";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<th style="border-bottom: 1px solid #ddd;">
|
||||||
|
<select
|
||||||
|
on:input={() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (`${selected}`.trim()) {
|
||||||
|
const value = selected;
|
||||||
|
handler.filter(value, (runner) => {
|
||||||
|
if (
|
||||||
|
runner.group.id === value ||
|
||||||
|
runner?.group?.parentGroup?.id === value ||
|
||||||
|
value === "all"
|
||||||
|
)
|
||||||
|
return runner;
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}}
|
||||||
|
bind:value={selected}
|
||||||
|
name="groupfilter"
|
||||||
|
id="groupfilter"
|
||||||
|
>
|
||||||
|
<option value="all">{$_('all')}</option>
|
||||||
|
{#each groups as g}
|
||||||
|
<option value={g.value}>{g.label}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</th>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import {
|
import {
|
||||||
RunnerService,
|
RunnerService,
|
||||||
ScanService,
|
ScanService,
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||||
const filterRunners = (label, filterText, option) =>
|
const filterRunners = (label, filterText, option) =>
|
||||||
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||||
option.value.toString().startsWith(filterText.toLowerCase());
|
option.value.id.toString().startsWith(filterText.toLowerCase());
|
||||||
function focus(el) {
|
function focus(el) {
|
||||||
el.focus();
|
el.focus();
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -1,186 +1,219 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import {
|
import { ScanService, TrackService } from "@odit/lfk-client-js";
|
||||||
ScanService,
|
|
||||||
} from "@odit/lfk-client-js";
|
|
||||||
import store from "../../store";
|
import store from "../../store";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import ScansEmptyState from "./ScansEmptyState.svelte";
|
import ScansEmptyState from "./ScansEmptyState.svelte";
|
||||||
$: searchvalue = "";
|
import ThFilterRunner from "./ThFilterRunner.svelte";
|
||||||
|
import ThFilterTrack from "./ThFilterTrack.svelte";
|
||||||
$: active_deletes = [];
|
$: active_deletes = [];
|
||||||
export let current_scans = [];
|
export let current_scans = [];
|
||||||
|
const handler = new DataHandler(current_scans, { rowsPerPage: 20 });
|
||||||
|
const rows = handler.getRows();
|
||||||
const scans_promise = ScanService.scanControllerGetAll().then((val) => {
|
const scans_promise = ScanService.scanControllerGetAll().then((val) => {
|
||||||
current_scans = val;
|
current_scans = val;
|
||||||
|
handler.setRows(val);
|
||||||
});
|
});
|
||||||
function should_display_based_on_id(id) {
|
$: allTracks = [];
|
||||||
if (searchvalue.toString().slice(-1) === "*") {
|
TrackService.trackControllerGetAll().then((val) => {
|
||||||
return id.toString().startsWith(searchvalue.replace("*", ""));
|
allTracks = val;
|
||||||
|
});
|
||||||
|
function format_laptime(laptime) {
|
||||||
|
if (laptime == 0 || laptime == null) {
|
||||||
|
return $_("first-scan-of-the-day");
|
||||||
}
|
}
|
||||||
return id.toString() === searchvalue;
|
if (laptime < 60) {
|
||||||
}
|
return `${laptime}s`;
|
||||||
function format_laptime(laptime){
|
}
|
||||||
if(laptime == 0 || laptime == null){return $_('first-scan-of-the-day')}
|
if (laptime < 3600) {
|
||||||
if(laptime < 60){return `${laptime}s`}
|
return `${Math.floor(laptime / 60)}min ${
|
||||||
if(laptime < 3600){return `${Math.floor(laptime / 60)}min ${laptime - (Math.floor(laptime / 60)*60)}s`}
|
laptime - Math.floor(laptime / 60) * 60
|
||||||
return `${Math.floor(laptime / 3600)}h ${laptime - (Math.floor(laptime / 3600)*3600)}min ${laptime - (Math.floor(laptime / 3600)*3600) - (Math.floor(laptime / 60)*60)}`
|
}s`;
|
||||||
|
}
|
||||||
|
return `${Math.floor(laptime / 3600)}h ${
|
||||||
|
laptime - Math.floor(laptime / 3600) * 3600
|
||||||
|
}min ${
|
||||||
|
laptime -
|
||||||
|
Math.floor(laptime / 3600) * 3600 -
|
||||||
|
Math.floor(laptime / 60) * 60
|
||||||
|
}`;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:GET')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:GET")}
|
||||||
{#await scans_promise}
|
{#await scans_promise}
|
||||||
<div
|
<div
|
||||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||||
role="alert">
|
role="alert"
|
||||||
<p class="font-bold">{$_('scans-are-being-loaded')}</p>
|
>
|
||||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
<p class="font-bold">{$_("scans-are-being-loaded")}</p>
|
||||||
|
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
|
||||||
</div>
|
</div>
|
||||||
{:then}
|
{:then}
|
||||||
{#if current_scans.length === 0}
|
{#if current_scans.length === 0}
|
||||||
<ScansEmptyState />
|
<ScansEmptyState />
|
||||||
{:else}
|
{:else}
|
||||||
<input
|
|
||||||
type="search"
|
|
||||||
bind:value={searchvalue}
|
|
||||||
placeholder={$_('datatable.search')}
|
|
||||||
aria-label={$_('datatable.search')}
|
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
|
||||||
<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"
|
||||||
|
>
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
<tr>
|
<tr>
|
||||||
|
<Th {handler} orderBy="id">ID</Th>
|
||||||
|
<Th {handler}>
|
||||||
|
{$_("runner")}
|
||||||
|
</Th>
|
||||||
|
<Th {handler}>
|
||||||
|
{$_("distance")}
|
||||||
|
</Th>
|
||||||
|
<Th {handler}>
|
||||||
|
{$_("track")}
|
||||||
|
</Th>
|
||||||
|
<Th {handler}>
|
||||||
|
{$_("laptime")}
|
||||||
|
</Th>
|
||||||
|
<Th {handler}>
|
||||||
|
{$_("status")}
|
||||||
|
</Th>
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="relative px-6 py-3"
|
||||||
{$_('runner')}
|
style="border-bottom: 1px solid #ddd;"
|
||||||
</th>
|
>
|
||||||
<th
|
{$_("action")}
|
||||||
scope="col"
|
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{$_('distance-track')}
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
scope="col"
|
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{$_('laptime')}
|
|
||||||
</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">
|
|
||||||
<span class="sr-only">{$_('action')}</span>
|
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<ThFilter {handler} filterBy="id" />
|
||||||
|
<ThFilterRunner {handler} />
|
||||||
|
<th style="border-bottom: 1px solid #ddd;" />
|
||||||
|
<ThFilterTrack tracks={allTracks} {handler} />
|
||||||
|
<!-- <th style="border-bottom: 1px solid #ddd;" /> -->
|
||||||
|
<th style="border-bottom: 1px solid #ddd;" />
|
||||||
|
<th style="border-bottom: 1px solid #ddd;" />
|
||||||
|
<!-- TODO: filter status -->
|
||||||
|
<th style="border-bottom: 1px solid #ddd;" />
|
||||||
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200">
|
<tbody class="divide-y divide-gray-200">
|
||||||
{#each current_scans as scan}
|
{#each $rows as scan}
|
||||||
{#if scan.track?.name
|
<tr data-rowid="scan_{scan.id}">
|
||||||
.toLowerCase()
|
<td class="px-6 py-4 whitespace-nowrap text-left">
|
||||||
.includes(
|
<div class="text-sm font-medium text-gray-900">
|
||||||
searchvalue.toLowerCase()
|
{scan.id}
|
||||||
) || scan.runner?.firstname
|
</div>
|
||||||
.toLowerCase()
|
</td>
|
||||||
.includes(
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
searchvalue.toLowerCase()
|
<div class="flex items-center">
|
||||||
) || scan.runner?.lastname
|
<a
|
||||||
.toLowerCase()
|
href="../runners/{scan.runner.id}"
|
||||||
.includes(
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
|
||||||
searchvalue.toLowerCase()
|
>{scan.runner.firstname}
|
||||||
) || should_display_based_on_id(scan.id)}
|
{scan.runner.middlename || ""}
|
||||||
<tr data-rowid="scan_{scan.id}">
|
{scan.runner.lastname}</a
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
>
|
||||||
<div class="flex items-center">
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-left">
|
||||||
|
<div class="text-sm font-medium text-gray-900">
|
||||||
|
{#if scan.distance < 1000}
|
||||||
|
{scan.distance}m
|
||||||
|
{:else}{scan.distance / 1000}km{/if}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-left">
|
||||||
|
<div class="text-sm font-medium text-gray-900">
|
||||||
|
{#if scan.track}
|
||||||
<a
|
<a
|
||||||
href="../runners/{scan.runner.id}"
|
href="../tracks"
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{scan.runner.firstname}
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
|
||||||
{scan.runner.middlename || ''}
|
>{scan.track.name}
|
||||||
{scan.runner.lastname}</a>
|
</a>
|
||||||
</div>
|
{/if}
|
||||||
</td>
|
</div>
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-left">
|
||||||
|
{#if scan.responseType === "TRACKSCAN"}
|
||||||
<div class="text-sm font-medium text-gray-900">
|
<div class="text-sm font-medium text-gray-900">
|
||||||
{#if scan.distance < 1000}
|
{format_laptime(scan.lapTime)}
|
||||||
{scan.distance}m
|
|
||||||
{:else}{scan.distance / 1000}km{/if}
|
|
||||||
{#if scan.track}
|
|
||||||
<a
|
|
||||||
href="../tracks"
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{scan.track.name}
|
|
||||||
</a>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
{:else}
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<div class="text-sm font-medium text-gray-900">
|
||||||
{#if scan.responseType === "TRACKSCAN"}
|
{$_("scan-with-fixed-distance")}
|
||||||
<div class="text-sm font-medium text-gray-900">
|
</div>
|
||||||
{format_laptime(scan.lapTime)}
|
{/if}
|
||||||
</div>
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="flex items-center">
|
||||||
|
{#if scan.valid}
|
||||||
|
<span
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"
|
||||||
|
>{$_("valid")}</span
|
||||||
|
>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="text-sm font-medium text-gray-900">
|
<span
|
||||||
{$_('scan-with-fixed-distance')}
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800"
|
||||||
</div>
|
>{$_("invalid")}</span
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{#if active_deletes[scan.id] === true}
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[scan.id] = false;
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer"
|
||||||
|
>{$_("cancel-delete")}</button
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
ScanService.scanControllerRemove(scan.id, false).then(
|
||||||
|
(resp) => {
|
||||||
|
current_scans = current_scans.filter(
|
||||||
|
(obj) => obj.id !== scan.id
|
||||||
|
);
|
||||||
|
Toastify({
|
||||||
|
text: "Scan deleted",
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor:
|
||||||
|
"linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer"
|
||||||
|
>{$_("confirm-delete")}</button
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
{:else}
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="./{scan.id}"
|
||||||
|
class="text-indigo-600 hover:text-indigo-900"
|
||||||
|
>{$_("details")}</a
|
||||||
|
>
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:DELETE")}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[scan.id] = true;
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer"
|
||||||
|
>{$_("delete")}</button
|
||||||
|
>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
{/if}
|
||||||
<div class="flex items-center">
|
</tr>
|
||||||
{#if scan.valid}
|
|
||||||
<span
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('valid')}</span>
|
|
||||||
{:else}
|
|
||||||
<span
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('invalid')}</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{#if active_deletes[scan.id] === true}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[scan.id] = false;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
ScanService.scanControllerRemove(scan.id, false).then(
|
|
||||||
(resp) => {
|
|
||||||
current_scans = current_scans.filter(
|
|
||||||
(obj) => obj.id !== scan.id
|
|
||||||
);
|
|
||||||
Toastify({
|
|
||||||
text: 'Scan deleted',
|
|
||||||
duration: 500,
|
|
||||||
backgroundColor:
|
|
||||||
'linear-gradient(to right, #00b09b, #96c93d)',
|
|
||||||
}).showToast();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
|
||||||
</td>
|
|
||||||
{:else}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<a
|
|
||||||
href="./{scan.id}"
|
|
||||||
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:DELETE')}
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[scan.id] = true;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
{/if}
|
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -189,7 +222,7 @@
|
|||||||
{:catch error}
|
{:catch error}
|
||||||
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
||||||
<span class="inline-block align-middle mr-8">
|
<span class="inline-block align-middle mr-8">
|
||||||
<b class="capitalize">{$_('general_promise_error')}</b>
|
<b class="capitalize">{$_("general_promise_error")}</b>
|
||||||
{error}
|
{error}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<script>
|
||||||
|
export let handler;
|
||||||
|
let filterValue = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<input
|
||||||
|
on:input={() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const v = filterValue.toLowerCase();
|
||||||
|
handler.filter(v, (c) => {
|
||||||
|
if (v.startsWith("#")) {
|
||||||
|
return `#${c.runner?.id}`;
|
||||||
|
}
|
||||||
|
if (c.runner) {
|
||||||
|
let runnerName = `${c.runner.firstname} ${c.runner.lastname}`;
|
||||||
|
if (c.runner.middlename) {
|
||||||
|
runnerName = `${c.runner.firstname} ${c.runner.middlename} ${c.runner.lastname}`;
|
||||||
|
}
|
||||||
|
runnerName = runnerName.toLowerCase();
|
||||||
|
return runnerName;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
}, 150);
|
||||||
|
}}
|
||||||
|
placeholder="Filter"
|
||||||
|
bind:value={filterValue}
|
||||||
|
type="text"
|
||||||
|
name="runnerfilter"
|
||||||
|
id="runnerfilter"
|
||||||
|
/>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
th {
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
margin: -1px 0 0 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 24px;
|
||||||
|
border: none;
|
||||||
|
text-align: left;
|
||||||
|
background: inherit;
|
||||||
|
outline: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
export let tracks;
|
||||||
|
export let handler;
|
||||||
|
let selected = "all";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<th style="border-bottom: 1px solid #ddd;">
|
||||||
|
<select
|
||||||
|
on:input={() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (`${selected}`.trim()) {
|
||||||
|
const value = selected;
|
||||||
|
handler.filter(value, (scan) => {
|
||||||
|
// TODO: fix filter
|
||||||
|
if (scan.track.id === value || value === "all") return scan.track.id;
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}}
|
||||||
|
bind:value={selected}
|
||||||
|
name="trackfilter"
|
||||||
|
id="trackfilter"
|
||||||
|
>
|
||||||
|
<option value="all">{$_("all")}</option>
|
||||||
|
{#each tracks as track}
|
||||||
|
<option value={track.id}>{track.name}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</th>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { ScanStationService, TrackService } from "@odit/lfk-client-js";
|
import { ScanStationService, TrackService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import Select from "svelte-select";
|
import Select from "svelte-select";
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { ScanStationService } from "@odit/lfk-client-js";
|
import { ScanStationService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from "svelte";
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={cancelDelete}>
|
on:click_outside={cancelDelete}>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import { tick, createEventDispatcher } from "svelte";
|
import { tick, createEventDispatcher } from "svelte";
|
||||||
export let copy_modal_open;
|
export let copy_modal_open;
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
{#if valueCopy != null}
|
{#if valueCopy != null}
|
||||||
<textarea bind:this={areaDom}>{valueCopy}</textarea>
|
<textarea bind:this={areaDom}>{valueCopy}</textarea>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="fixed z-10 inset-0 overflow-y-auto" use:focusTrap>
|
<div class="fixed z-10 inset-0 overflow-y-auto" >
|
||||||
<div
|
<div
|
||||||
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
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="fixed inset-0 transition-opacity" aria-hidden="true">
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
bind:value={searchvalue}
|
bind:value={searchvalue}
|
||||||
placeholder={$_('datatable.search')}
|
placeholder={$_('datatable.search')}
|
||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="mb-4" />
|
||||||
<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">
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { MeService } from "@odit/lfk-client-js";
|
import { MeService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from "svelte";
|
||||||
@@ -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();
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={cancelDelete}>
|
on:click_outside={cancelDelete}>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
import { MeService } from "@odit/lfk-client-js";
|
import { MeService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import ConfirmProfileDeletion from "./ConfirmProfileDeletion.svelte";
|
import ConfirmProfileDeletion from "./ConfirmProfileDeletion.svelte";
|
||||||
|
import PasswordStrength, {
|
||||||
|
password_strong_enough_and_equal,
|
||||||
|
} from "../auth/PasswordStrength.svelte";
|
||||||
$: data_loaded = false;
|
$: data_loaded = false;
|
||||||
$: delete_triggered = false;
|
$: delete_triggered = false;
|
||||||
$: original_data = {};
|
$: original_data = {};
|
||||||
@@ -15,8 +18,10 @@
|
|||||||
JSON.stringify(editable) === JSON.stringify(original_data)
|
JSON.stringify(editable) === JSON.stringify(original_data)
|
||||||
);
|
);
|
||||||
$: save_enabled = changes_performed && isEmail(editable.email);
|
$: save_enabled = changes_performed && isEmail(editable.email);
|
||||||
$: update_password_enabled =
|
$: update_password_enabled = password_strong_enough_and_equal(
|
||||||
password_change.length > 0 && password_change === password_confirm;
|
password_change,
|
||||||
|
password_confirm
|
||||||
|
);
|
||||||
const user_promise = MeService.meControllerGet().then((data) => {
|
const user_promise = MeService.meControllerGet().then((data) => {
|
||||||
data_loaded = true;
|
data_loaded = true;
|
||||||
data.groups = data.groups.map((g) => g.id);
|
data.groups = data.groups.map((g) => g.id);
|
||||||
@@ -45,7 +50,7 @@
|
|||||||
function changePassword() {
|
function changePassword() {
|
||||||
if (data_loaded === true && update_password_enabled) {
|
if (data_loaded === true && update_password_enabled) {
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_('changing-your-password'),
|
text: $_("changing-your-password"),
|
||||||
duration: 2500,
|
duration: 2500,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
let postdata = Object.assign({}, original_data);
|
let postdata = Object.assign({}, original_data);
|
||||||
@@ -56,7 +61,7 @@
|
|||||||
password_change = "";
|
password_change = "";
|
||||||
postdata = {};
|
postdata = {};
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_('password-changed'),
|
text: $_("password-changed"),
|
||||||
duration: 2500,
|
duration: 2500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
@@ -242,10 +247,7 @@
|
|||||||
class="border-gray-300 placeholder-gray-500 appearance-none rounded-md relative block w-full px-3 py-2 border focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
|
class="border-gray-300 placeholder-gray-500 appearance-none rounded-md relative block w-full px-3 py-2 border focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
|
||||||
placeholder={$_('password')} />
|
placeholder={$_('password')} />
|
||||||
</div>
|
</div>
|
||||||
{#if password_change != password_confirm && password_change.length > 0}
|
<PasswordStrength bind:password_change bind:password_confirm />
|
||||||
<span
|
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">{$_('passwords-dont-match')}</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
|
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
|
||||||
<button
|
<button
|
||||||
@@ -257,9 +259,9 @@
|
|||||||
{$_('update-password')}
|
{$_('update-password')}
|
||||||
</button>
|
</button>
|
||||||
{#if update_password_enabled}
|
{#if update_password_enabled}
|
||||||
<p>
|
<p>
|
||||||
{$_('after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that')}
|
{$_('after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that')}
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<script>
|
||||||
|
let className = "";
|
||||||
|
export { className as class };
|
||||||
|
|
||||||
|
export let type;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input
|
||||||
|
class={`border-1 border-stone-300 border rounded-md shadow ${className} ${
|
||||||
|
type === "checkbox" && "w-5 h-5 text-orange-400"
|
||||||
|
}`}
|
||||||
|
{type}
|
||||||
|
{...$$restProps}
|
||||||
|
on:click
|
||||||
|
on:change
|
||||||
|
on:keydown
|
||||||
|
on:keyup
|
||||||
|
on:mouseenter
|
||||||
|
on:mouseleave
|
||||||
|
/>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
export const groupFilter = (row, columnId, value) => {
|
||||||
|
const group = row.getValue(columnId);
|
||||||
|
if (group.responseType === "RUNNERORGANIZATION") {
|
||||||
|
return group.name.toLowerCase().includes(value.toLowerCase());
|
||||||
|
} else if (value.includes(">")) {
|
||||||
|
value = value.split(">")[1];
|
||||||
|
if (value.length == 0) {
|
||||||
|
return group.name.toLowerCase().includes(value.toLowerCase());
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
group.name.toLowerCase().includes(value.toLowerCase()) ||
|
||||||
|
group.parentGroup.name.toLowerCase().includes(value.toLowerCase())
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
group.name.toLowerCase().includes(value.toLowerCase()) ||
|
||||||
|
group.parentGroup.name.toLowerCase().includes(value.toLowerCase())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
|
||||||
|
import { StatsClientService } from "@odit/lfk-client-js";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
export let modal_open;
|
||||||
|
export let new_client;
|
||||||
|
export let current_clients;
|
||||||
|
export let copy_modal_open;
|
||||||
|
function focus(el) {
|
||||||
|
el.focus();
|
||||||
|
}
|
||||||
|
$: description = "";
|
||||||
|
$: createbtnenabled = description != "";
|
||||||
|
$: processed_last_submit = true;
|
||||||
|
(() => {
|
||||||
|
document.onkeydown = (e) => {
|
||||||
|
e = e || window.event;
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
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: $_("statsclient-is-being-added"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
|
||||||
|
StatsClientService.statsClientControllerPost({description})
|
||||||
|
.then((result) => {
|
||||||
|
description = "";
|
||||||
|
modal_open = false;
|
||||||
|
//
|
||||||
|
Toastify({
|
||||||
|
text: $_("scanstation-added"),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
current_clients.push(result);
|
||||||
|
current_clients = current_clients;
|
||||||
|
new_client = result;
|
||||||
|
copy_modal_open = true;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
processed_last_submit = true;
|
||||||
|
//
|
||||||
|
toast.hideToast();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if modal_open}
|
||||||
|
<div
|
||||||
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
|
|
||||||
|
use:clickOutside
|
||||||
|
on:click_outside={() => {
|
||||||
|
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">​</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
|
||||||
|
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></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">
|
||||||
|
{$_('create-a-new-statsclient')}
|
||||||
|
</h3>
|
||||||
|
<div class="mt-2 mb-6">
|
||||||
|
<p class="text-sm text-gray-500">
|
||||||
|
{$_('please-provide-the-required-information-to-create-a-new-statsclient')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-6 gap-6">
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="description"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('description')}</label>
|
||||||
|
<input
|
||||||
|
use:focus
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('description')}
|
||||||
|
bind:value={description}
|
||||||
|
type="text"
|
||||||
|
name="description"
|
||||||
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
||||||
|
</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">
|
||||||
|
{$_('create')}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
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}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
|
||||||
|
import { ScanStationService } from "@odit/lfk-client-js";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
export let modal_open;
|
||||||
|
export let delete_station;
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
function cancelDelete() {
|
||||||
|
modal_open = false;
|
||||||
|
dispatch("cancelDelete", { id: delete_station.id });
|
||||||
|
}
|
||||||
|
function deleteClient() {
|
||||||
|
ScanStationService.donorControllerRemove(
|
||||||
|
delete_station.id,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
.then((resp) => {
|
||||||
|
Toastify({
|
||||||
|
text: $_('statsclient-deleted'),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
location.replace("./");
|
||||||
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if modal_open}
|
||||||
|
<div
|
||||||
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
|
|
||||||
|
use:clickOutside
|
||||||
|
on:click_outside={cancelDelete}>
|
||||||
|
<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">​</span>
|
||||||
|
<div
|
||||||
|
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden 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"><path fill="none" d="M0 0h24v24H0z"/><path d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z"/></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">
|
||||||
|
{$_('attention')}
|
||||||
|
</h3>
|
||||||
|
<div class="mt-2 mb-6">
|
||||||
|
<p class="text-sm text-gray-500">
|
||||||
|
{$_(
|
||||||
|
'do-you-want-to-delete-this-donor-with-all-related-donations'
|
||||||
|
)}
|
||||||
|
<br />
|
||||||
|
{$_('all-associated-scans-will-get-deleted-as-well')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||||
|
<button
|
||||||
|
on:click={deleteClient}
|
||||||
|
type="button"
|
||||||
|
class="w-full inline-flex justify-center 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 sm:ml-3 sm:w-auto sm:text-sm">
|
||||||
|
{$_('confirm-delete-statsclient')}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
on:click={cancelDelete}
|
||||||
|
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-keep-statsclient')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import { tick, createEventDispatcher } from "svelte";
|
||||||
|
export let copy_modal_open;
|
||||||
|
export let new_client;
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
let valueCopy = null;
|
||||||
|
let areaDom;
|
||||||
|
let copied = false;
|
||||||
|
function close() {
|
||||||
|
copy_modal_open = false;
|
||||||
|
}
|
||||||
|
async function copy() {
|
||||||
|
valueCopy = new_client.key;
|
||||||
|
await tick();
|
||||||
|
areaDom.focus();
|
||||||
|
areaDom.select();
|
||||||
|
try {
|
||||||
|
const successful = document.execCommand("copy");
|
||||||
|
if (!successful) {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
Toastify({
|
||||||
|
text: $_("copied-token-to-clipboard"),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
copied = true;
|
||||||
|
} catch (err) {
|
||||||
|
Toastify({
|
||||||
|
text: $_("error-whyile-copying-to-clipboard"),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor:
|
||||||
|
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
||||||
|
}).showToast();
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can notifi by event or storage about copy status
|
||||||
|
valueCopy = null;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if copy_modal_open}
|
||||||
|
{#if valueCopy != null}
|
||||||
|
<textarea bind:this={areaDom}>{valueCopy}</textarea>
|
||||||
|
{/if}
|
||||||
|
<div class="fixed z-10 inset-0 overflow-y-auto" >
|
||||||
|
<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">​</span>
|
||||||
|
<div
|
||||||
|
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden 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"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
|
<path
|
||||||
|
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></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">
|
||||||
|
{$_('token')}
|
||||||
|
</h3>
|
||||||
|
<div class="mt-2 mb-6">
|
||||||
|
<p class="text-sm text-gray-500">
|
||||||
|
{$_('the-statsclient-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again')}
|
||||||
|
<br />
|
||||||
|
{$_('please-copy-the-token-and-store-it-somewhere-save')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 mb-6">
|
||||||
|
<label
|
||||||
|
for="token"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('token')}</label>
|
||||||
|
<div on:click={copy} class="inline-flex">
|
||||||
|
<p
|
||||||
|
name="token"
|
||||||
|
class:bg-green-200={copied}
|
||||||
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 p-2">
|
||||||
|
{new_client.key}
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="bg-gray-200 border-gray-300 border-t border-b border-r text-black rounded-r-md sm:text-sm p-2 mt-1 cursor-pointer">
|
||||||
|
<svg
|
||||||
|
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="M7 4V2h10v2h3l1 1v16a1 1 0 01-1 1H4a1 1 0 01-1-1V5l1-1h3zm0 2H5v14h14V6h-2v2H7V6zm2-2v2h6V4H9z" /></svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="text-gray-500 text-xs">
|
||||||
|
{$_('click-to-copy-token-to-clipboard')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||||
|
<button
|
||||||
|
on:click={close}
|
||||||
|
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-green-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||||
|
{$_('yes-i-copied-the-token')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
<script>
|
||||||
|
import { t, _ } from "svelte-i18n";
|
||||||
|
import store from "../../store";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import PromiseError from "../base/PromiseError.svelte";
|
||||||
|
import ConfirmStatsClientDeletion from "./ConfirmStatsClientDeletion.svelte";
|
||||||
|
import { StatsClientService } from "@odit/lfk-client-js";
|
||||||
|
let data_loaded = false;
|
||||||
|
let modal_open;
|
||||||
|
let delete_client;
|
||||||
|
export let params;
|
||||||
|
$: delete_triggered = false;
|
||||||
|
$: original_data = {};
|
||||||
|
const promise = StatsClientService.statsClientControllerGetOne(
|
||||||
|
params.clientid
|
||||||
|
).then((data) => {
|
||||||
|
data_loaded = true;
|
||||||
|
original_data = Object.assign(original_data, data);
|
||||||
|
});
|
||||||
|
function deleteClient() {
|
||||||
|
StatsClientService.statsClientControllerRemove(original_data.id, false)
|
||||||
|
.then((resp) => {
|
||||||
|
Toastify({
|
||||||
|
text: $_("statsclient-deleted"),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
location.replace("./");
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
modal_open = true;
|
||||||
|
delete_client = original_data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ConfirmStatsClientDeletion bind:modal_open bind:delete_client />
|
||||||
|
{#await promise}
|
||||||
|
{$_('loading-statsclient-details')}
|
||||||
|
{:then}
|
||||||
|
<section class="container p-5 select-none">
|
||||||
|
<div class="flex flex-row mb-4">
|
||||||
|
<div class="w-full">
|
||||||
|
<nav class="w-full flex">
|
||||||
|
<ol class="list-none flex flex-row items-center justify-start">
|
||||||
|
<li class="flex items-center">
|
||||||
|
<svg
|
||||||
|
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
|
||||||
|
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center ml-2">
|
||||||
|
<a class="mr-2" href="./">{$_('statsclient')}</a><svg
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="h-3 w-3 mr-2 stroke-current"
|
||||||
|
height="1em"
|
||||||
|
width="1em"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"><line
|
||||||
|
x1="5"
|
||||||
|
y1="12"
|
||||||
|
x2="19"
|
||||||
|
y2="12" />
|
||||||
|
<polyline points="12 5 19 12 12 19" /></svg>
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center">
|
||||||
|
<span class="mr-2">#{original_data.id}</span>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||||
|
#{original_data.id}
|
||||||
|
<span data-id="stations_actions_${original_data.id}">
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('STATSCLIENT:DELETE')}
|
||||||
|
{#if delete_triggered}
|
||||||
|
<button
|
||||||
|
on:click={deleteClient}
|
||||||
|
class="w-full justify-center 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 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-deletion')}</button>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
delete_triggered = !delete_triggered;
|
||||||
|
}}
|
||||||
|
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button>
|
||||||
|
{/if}
|
||||||
|
{#if !delete_triggered}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
delete_triggered = true;
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
class="w-full justify-center 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 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-statsclient')}</button>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!-- -->
|
||||||
|
<div class="text-sm w-full">
|
||||||
|
<label
|
||||||
|
for="description"
|
||||||
|
class="font-medium text-gray-700">{$_('description')}</label>
|
||||||
|
<p
|
||||||
|
name="description"
|
||||||
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" >
|
||||||
|
{original_data.description}</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{:catch error}
|
||||||
|
<PromiseError {error} />
|
||||||
|
{/await}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import store from "../../store";
|
||||||
|
import AddStatsClientModal from "./AddStatsClientModal.svelte";
|
||||||
|
import CopyStatsClientTokenModal from "./CopyStatsClientTokenModal.svelte";
|
||||||
|
import StatsClientsOverview from "./StatsClientsOverview.svelte";
|
||||||
|
export let modal_open = false;
|
||||||
|
export let copy_modal_open = false;
|
||||||
|
export let new_client = {};
|
||||||
|
let current_clients = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="container p-5">
|
||||||
|
<span class="mb-1 text-3xl font-extrabold leading-tight">
|
||||||
|
{$_('statsclients')}
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('STATSCLIENT:CREATE')}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
modal_open = true;
|
||||||
|
}}
|
||||||
|
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">
|
||||||
|
{$_('create-a-new-statsclient')}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
<StatsClientsOverview bind:current_clients bind:modal_open bind:new_client bind:copy_modal_open />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('STATSCLIENT:CREATE')}
|
||||||
|
<AddStatsClientModal bind:modal_open bind:current_clients bind:new_client bind:copy_modal_open/>
|
||||||
|
<CopyStatsClientTokenModal bind:copy_modal_open bind:new_client />
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import AddStatsClientModal from "./AddStatsClientModal.svelte";
|
||||||
|
import CopyScanStationTokenModal from "./CopyStatsClientTokenModal.svelte";
|
||||||
|
import scanstations_empty from "./statsclients_empty.svg";
|
||||||
|
let modal_open = false;
|
||||||
|
let copy_modal_open = false;
|
||||||
|
let new_client = {};
|
||||||
|
let current_clients = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="text-center items-center justify-center">
|
||||||
|
<p class="mb-16 text-lg text-gray-500">
|
||||||
|
<img class="w-full h-44" src={scanstations_empty} alt="" />
|
||||||
|
<span class="font-bold">{$_('you-dont-have-any-scanclients-yet')}.</span><br />
|
||||||
|
<span>{$_('add-the-first-statsclient')}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<AddStatsClientModal bind:modal_open bind:current_clients bind:new_client bind:copy_modal_open/>
|
||||||
|
<CopyScanStationTokenModal bind:copy_modal_open bind:new_client />
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import { StatsClientService } from "@odit/lfk-client-js";
|
||||||
|
const promise = StatsClientService.statsClientControllerGetAll().then(
|
||||||
|
(result) => {
|
||||||
|
current_clients = result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
import store from "../../store";
|
||||||
|
import StatsClientsEmptyState from "./StatsClientsEmptyState.svelte";
|
||||||
|
import ConfirmStatsClientDeletion from "./ConfirmStatsClientDeletion.svelte";
|
||||||
|
$: searchvalue = "";
|
||||||
|
$: active_deletes = [];
|
||||||
|
let delete_client = {};
|
||||||
|
let modal_open = false;
|
||||||
|
export let current_clients = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ConfirmStatsClientDeletion
|
||||||
|
on:cancelDelete={(event) => {
|
||||||
|
modal_open = false;
|
||||||
|
active_deletes[event.detail.id] = false;
|
||||||
|
}}
|
||||||
|
bind:modal_open
|
||||||
|
bind:delete_client />
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('STATSCLIENT:GET')}
|
||||||
|
{#await promise}
|
||||||
|
<div
|
||||||
|
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||||
|
role="alert">
|
||||||
|
<p class="font-bold">{$_('statsclients-are-being-loaded')}</p>
|
||||||
|
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
||||||
|
</div>
|
||||||
|
{:then}
|
||||||
|
{#if current_clients.length === 0}
|
||||||
|
<StatsClientsEmptyState />
|
||||||
|
{:else}
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
bind:value={searchvalue}
|
||||||
|
placeholder={$_('datatable.search')}
|
||||||
|
aria-label={$_('datatable.search')}
|
||||||
|
class="mb-4" />
|
||||||
|
<div
|
||||||
|
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
||||||
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
|
<thead class="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th
|
||||||
|
scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
{$_('description')}
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
{$_('prefix')}
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="relative px-6 py-3">
|
||||||
|
<span class="sr-only">{$_('action')}</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200">
|
||||||
|
{#each current_clients as c}
|
||||||
|
{#if Object.values(c)
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchvalue)}
|
||||||
|
<tr data-rowid="station_{c.id}">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="ml-4">
|
||||||
|
<div class="text-sm font-medium text-gray-900">
|
||||||
|
{c.description}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="ml-4">
|
||||||
|
<div class="text-sm font-medium text-gray-900">
|
||||||
|
{c.prefix}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{#if active_deletes[c.id] === true}
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[c.id] = false;
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
StatsClientService.statsClientControllerRemove(c.id, false)
|
||||||
|
.then((resp) => {
|
||||||
|
current_clients = current_clients.filter((obj) => obj.id !== c.id);
|
||||||
|
Toastify({
|
||||||
|
text: $_('statsclient-deleted'),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor:
|
||||||
|
'linear-gradient(to right, #00b09b, #96c93d)',
|
||||||
|
}).showToast();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
modal_open = true;
|
||||||
|
delete_client = c;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||||
|
</td>
|
||||||
|
{:else}
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
|
<a
|
||||||
|
href="/statsclients/{c.id}"
|
||||||
|
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('STATSCLIENT:DELETE')}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[c.id] = true;
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
{/if}
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{:catch error}
|
||||||
|
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
||||||
|
<span class="inline-block align-middle mr-8">
|
||||||
|
<b class="capitalize">{$_('general_promise_error')}</b>
|
||||||
|
{error}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/await}
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 920.11 411.95" width="920.11" height="411.95"><path d="M436.53 410h195.59c7.72 0 7.73-12 0-12h-195.6c-7.71 0-7.73 12 0 12z" fill="#e6e6e6"/><path d="M383.72 149.23H188.79a7.78 7.78 0 00-7.77 7.77v38.72c9.72.23 16.03 8.26 17.56 18v35.1h.74a.44.44 0 01.45.45v18.68a.44.44 0 01-.45.44h-.74v112.9l-.02 7.02h185.16a7.78 7.78 0 007.77-7.77V157a7.78 7.78 0 00-7.77-7.77z" fill="#6c63ff"/><path d="M745.9 21.81v211.9H404.97v-93.3a16 16 0 00-15.98-15.97h-63.94V21.8z" fill="#6c63ff"/><path d="M766.95 263.58h-361.6v-1.47h360.12V12.55A11.09 11.09 0 00754.4 1.48H312.14a11.09 11.09 0 00-11.08 11.07v110.93h-1.47V12.55A12.57 12.57 0 01312.14 0H754.4a12.57 12.57 0 0112.55 12.55z" fill="#3f3d56"/><path d="M732.69 308.62H405.35v-1.48h327.34a32.82 32.82 0 0032.78-32.78v-10.78H405.35v-1.47h361.6v12.25a34.3 34.3 0 01-34.26 34.26z" fill="#3f3d56"/><path d="M635.54 380.98c-18.25-17.52-30.25-40.39-34.11-72.36h-134.5c-1.36 29.91-13.29 52.35-34.8 72.28l-2.28.08c22.2-20.12 34.43-42.72 35.64-73.13l.03-.7h137.22l.08.65c3.79 32.51 16.04 55.52 34.74 73.06zM388.63 411.52H181.46v-1.47h207.17a16 16 0 0015.98-15.98V140.75a16 16 0 00-15.98-15.97H181.46a16 16 0 00-15.98 15.97v54.67h-1.47v-54.67a17.47 17.47 0 0117.45-17.45h207.17a17.47 17.47 0 0117.46 17.45v253.32a17.47 17.47 0 01-17.46 17.45z" fill="#3f3d56"/><path d="M285.05 141.98a5 5 0 115-5 5.01 5.01 0 01-5 5zm0-8.85a3.85 3.85 0 103.85 3.85 3.85 3.85 0 00-3.85-3.85zM285.05 405.86a6.39 6.39 0 116.39-6.38 6.4 6.4 0 01-6.4 6.38zm0-11.3a4.91 4.91 0 104.91 4.92 4.92 4.92 0 00-4.91-4.92zM179.38 411.95H110.8a19.5 19.5 0 01-19.47-19.47V214.89a19.5 19.5 0 0119.47-19.47h68.58a19.5 19.5 0 0119.47 19.47v31.78a1.92 1.92 0 011.19 1.78v20.67a1.92 1.92 0 01-1.19 1.78v121.58a19.5 19.5 0 01-19.47 19.47zM110.8 196.9a18.02 18.02 0 00-18 18v177.58a18.02 18.02 0 0018 18h68.58a18.02 18.02 0 0018-18V269.57h.74a.44.44 0 00.44-.45v-20.67a.44.44 0 00-.44-.45h-.74v-33.1a18.02 18.02 0 00-18-18z" fill="#3f3d56"/><path d="M180.14 201.03h-8.96a6.65 6.65 0 01-6.15 9.16h-39.29a6.65 6.65 0 01-6.15-9.16h-8.36a14 14 0 00-14 14v177.32a14 14 0 0014 13.99h68.9a14 14 0 0014-14V215.04a14 14 0 00-14-14z" fill="#6c63ff"/><path d="M919.23 411.66H.88a.88.88 0 110-1.76h918.35a.88.88 0 110 1.76z" fill="#3f3d56"/><path d="M636 411.25H431.48a15.5 15.5 0 110-31.01H636a15.5 15.5 0 010 31zm-204.52-29.53a14.03 14.03 0 000 28.05H636a14.03 14.03 0 000-28.05z" fill="#3f3d56"/><path fill="#ffb8b8" d="M784.5 293.2l5.72 11.97 48.92-16.4-8.45-17.67-46.2 22.1z"/><path d="M790.15 333.59l-18-37.64 14.54-6.96 11.58 24.21a14.89 14.89 0 01-7 19.85l-1.12.54z" fill="#2f2e41"/><path fill="#ffb8b8" d="M772.96 400.14l13.27-.45.56-51.64-15.55.92 1.72 51.17z"/><path d="M811.97 411.86h-41.72v-16.12h26.84a14.89 14.89 0 0114.88 14.88v1.24zM774.06 392.38a4.97 4.97 0 01-4.84-3.78c-7.26-29.2-34.3-176.34-10.4-205.23l.22-.26.31-.08c1.68-.42 33.33-10.22 51.9 5.08l.21.17 10.34 29.92 27.86 41.35a20.4 20.4 0 01-6.04 28.66l-36.58 23.08a5 5 0 01-5.75-.4 5.06 5.06 0 01-1.5-2.1l-7.69-19.21a5.03 5.03 0 012.4-6.33l17.15-8.57a3.67 3.67 0 001.83-2.5 2.96 2.96 0 00-1.03-2.55l-19.9-17.15a3 3 0 00-4.95 2.38l4.93 130.2a5 5 0 01-4.22 5.13l-13.46 2.13a5.05 5.05 0 01-.8.06z" fill="#2f2e41"/><path d="M808.38 193.41l-.34-.01-49.62-3.68a4.5 4.5 0 01-3.91-5.97 47.1 47.1 0 001.07-27.31c-3.23-12.75-3.3-36.44-3.06-49.42a8.75 8.75 0 018.28-8.53v-.01h1c8.08.12 22.91.7 35.05 3.22a18.39 18.39 0 0114.66 17.7c.28 12.06.32 28.38-1.05 37.66-1.16 7.83.98 22.86 2.35 31.12a4.5 4.5 0 01-4.43 5.23z" fill="#3f3d56"/><path d="M826.09 240.71a10.02 10.02 0 01-3.81-14.9L799.36 127h17.33l20.22 96.87a10.08 10.08 0 01-10.82 16.84zM717.56 137.7l27.43-25.95 10.34 14.47-25.84 22.74 33.89 26.91c.24-.01.49-.04.74-.04a10.85 10.85 0 11-10.75 12.3l-.1.1-35.28-30.56a13.47 13.47 0 01-.43-19.97z" fill="#ffb8b8"/><path d="M801.19 133.33a4.47 4.47 0 01-4.05-2.55 52.81 52.81 0 01-4.47-14.57c-1.2-8.25 4.54-13.15 10.37-14.22 5.67-1.04 12.58 1.45 14.34 9.38a20.45 20.45 0 01.35 2.04c.7 6 1.37 10.68 1.97 13.9a4.5 4.5 0 01-4.2 5.31l-14.08.7-.23.01z" fill="#3f3d56"/><circle cx="781.54" cy="59.98" r="30" fill="#2f2e41"/><circle cx="781.73" cy="67.77" r="24.56" fill="#ffb8b8"/><path d="M738.13 121.38a4.47 4.47 0 01-1.26-4.62 52.81 52.81 0 016.55-13.76c4.7-6.88 12.23-6.63 17.25-3.48 4.89 3.07 8.3 9.57 4.24 16.61a20.45 20.45 0 01-1.12 1.73c-3.54 4.91-6.21 8.8-7.93 11.58a4.5 4.5 0 01-6.7 1.09l-10.85-9q-.1-.07-.18-.15z" fill="#3f3d56"/><path d="M775.72 33.19c-6.04-3.6-7.35-12.57-3.75-18.61s10.86-9.2 17.9-9.4c10.03-.3 19.72 4.7 26.75 11.87s11.66 16.36 15.2 25.76 6.06 19.15 9.54 28.57c1.79 4.83 3.99 9.8 8.07 12.93s10.59 3.7 14.08-.08c-.01 6.06-4.66 11.57-10.42 13.45s-12.29.46-17.34-2.9c-8.76-5.8-13-16.4-15.41-26.64s-3.61-20.95-8.48-30.27c-2.01-3.87-4.77-7.54-8.66-9.5s-9.06-1.85-12.19 1.19c-1.44 1.4-2.38 3.32-4.02 4.5a8.05 8.05 0 01-7.04.72 23.8 23.8 0 01-6.36-3.59" fill="#2f2e41"/><path d="M756.07 51.17a29.38 29.38 0 0042.13 5.26c2.38-1.94 4.6-4.61 4.45-7.68-.16-3.15-2.73-5.62Line truncated
|
||||||
|
After Width: | Height: | Size: 5.0 KiB |
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import {
|
import {
|
||||||
RunnerOrganizationService,
|
RunnerOrganizationService,
|
||||||
RunnerTeamService,
|
RunnerTeamService,
|
||||||
@@ -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();
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { RunnerTeamService } from "@odit/lfk-client-js";
|
import { RunnerTeamService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from "svelte";
|
||||||
@@ -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();
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={cancelDelete}>
|
on:click_outside={cancelDelete}>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -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={() => {
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -53,7 +57,7 @@
|
|||||||
bind:value={searchvalue}
|
bind:value={searchvalue}
|
||||||
placeholder={$_('datatable.search')}
|
placeholder={$_('datatable.search')}
|
||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="mb-4" />
|
||||||
<div class="h-12">
|
<div class="h-12">
|
||||||
<GenerateSponsoringContracts
|
<GenerateSponsoringContracts
|
||||||
bind:sponsoring_contracts_show
|
bind:sponsoring_contracts_show
|
||||||
@@ -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">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { tracks as tracksstore } from "../../store.js";
|
import { tracks as tracksstore } from "../../store.js";
|
||||||
import { TrackService } from "@odit/lfk-client-js";
|
import { TrackService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { UserService } from "@odit/lfk-client-js";
|
import { UserService } from "@odit/lfk-client-js";
|
||||||
import isEmail from "validator/es/lib/isEmail";
|
import isEmail from "validator/es/lib/isEmail";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
|
import PasswordStrength, {
|
||||||
|
password_strong_enough,
|
||||||
|
} from "../auth/PasswordStrength.svelte";
|
||||||
export let modal_open;
|
export let modal_open;
|
||||||
export let current_users;
|
export let current_users;
|
||||||
let firstname_input;
|
let firstname_input;
|
||||||
@@ -28,7 +31,10 @@
|
|||||||
$: isLastnameValid = lastname_input_value.trim().length !== 0;
|
$: isLastnameValid = lastname_input_value.trim().length !== 0;
|
||||||
$: isFirstnameValid = firstname_input_value.trim().length !== 0;
|
$: isFirstnameValid = firstname_input_value.trim().length !== 0;
|
||||||
$: createbtnenabled =
|
$: createbtnenabled =
|
||||||
isFirstnameValid && isLastnameValid && isPasswordValid && isEmailValid;
|
isFirstnameValid &&
|
||||||
|
isLastnameValid &&
|
||||||
|
password_strong_enough(password_input_value) &&
|
||||||
|
isEmailValid;
|
||||||
(function () {
|
(function () {
|
||||||
document.onkeydown = function (e) {
|
document.onkeydown = function (e) {
|
||||||
e = e || window.event;
|
e = e || window.event;
|
||||||
@@ -86,7 +92,7 @@
|
|||||||
{#if modal_open}
|
{#if modal_open}
|
||||||
<div
|
<div
|
||||||
class="fixed z-10 inset-0 overflow-y-auto"
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
use:focusTrap
|
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:click_outside={() => {
|
on:click_outside={() => {
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
@@ -203,12 +209,8 @@
|
|||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
||||||
{#if !isPasswordValid}
|
<PasswordStrength
|
||||||
<span
|
bind:password_change={password_input_value} />
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
|
||||||
{$_('password-is-required')}
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-6">
|
<div class="col-span-6">
|
||||||
<label
|
<label
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
bind:value={searchvalue}
|
bind:value={searchvalue}
|
||||||
placeholder={$_('datatable.search')}
|
placeholder={$_('datatable.search')}
|
||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="mb-4" />
|
||||||
<!-- {/if} -->
|
<!-- {/if} -->
|
||||||
<!-- <button
|
<!-- <button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
@@ -82,14 +82,6 @@
|
|||||||
<tr data-rowid="user_{u.id}">
|
<tr data-rowid="user_{u.id}">
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
{#if u.profilePic}
|
|
||||||
<div class="flex-shrink-0 h-10 w-10">
|
|
||||||
<img
|
|
||||||
class="h-10 w-10 rounded-full"
|
|
||||||
src={u.profilePic}
|
|
||||||
alt="" />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<div class="text-sm font-medium text-gray-900">
|
<div class="text-sm font-medium text-gray-900">
|
||||||
{u.firstname}
|
{u.firstname}
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
+478
-420
@@ -1,421 +1,479 @@
|
|||||||
{
|
{
|
||||||
"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-or-update-a-payment": "Zahlung hinzufügen oder bearbeiten",
|
||||||
"add-the-first-scanstation": "Erstelle deine erste Scannerstation.",
|
"add-scan": "Scan erstellen",
|
||||||
"add-user-group": "Neue Gruppe erstellen",
|
"add-the-first-scanstation": "Erstelle deine erste Scannerstation.",
|
||||||
"add-your-first-card": "Erstelle deine erste Läuferkarte",
|
"add-the-first-statsclient": "Erstelle deinen ersten Statsclient.",
|
||||||
"add-your-first-contact": "Erstelle den ersten Kontakt",
|
"add-user-group": "Neue Gruppe erstellen",
|
||||||
"add-your-first-donor": "Erstelle die erste Sponsor:in",
|
"add-your-first-card": "Erstelle deine erste Läuferkarte",
|
||||||
"add-your-first-group": "Erstelle die erste Gruppe",
|
"add-your-first-contact": "Erstelle den ersten Kontakt",
|
||||||
"add-your-first-organization": "Erstelle die erste Organisation",
|
"add-your-first-donor": "Erstelle die erste Sponsor:in",
|
||||||
"add-your-first-runner": "Erstelle die erste Läufer:in",
|
"add-your-first-group": "Erstelle die erste Gruppe",
|
||||||
"add-your-first-team": "Erstelle das erste Team",
|
"add-your-first-organization": "Erstelle die erste Organisation",
|
||||||
"add-your-first-track": "Erstelle den ersten Track (Laufstrecke).",
|
"add-your-first-runner": "Erstelle die erste Läufer:in",
|
||||||
"add-your-first-user": "Erstelle die erste Benutzer:in",
|
"add-your-first-team": "Erstelle das erste Team",
|
||||||
"add-your-fist-donation": "Erstelle dein erstes Sponsoring",
|
"add-your-first-track": "Erstelle den ersten Track (Laufstrecke).",
|
||||||
"add-your-fist-scan": "Füge deinen ersten Scan hinzu",
|
"add-your-first-user": "Erstelle die erste Benutzer:in",
|
||||||
"adding-card": "Karte wird erstellt",
|
"add-your-fist-donation": "Erstelle dein erstes Sponsoring",
|
||||||
"adding-scan": "Scan wird hinzugefügt",
|
"add-your-fist-scan": "Füge deinen ersten Scan hinzu",
|
||||||
"address": "Adresse",
|
"adding-card": "Karte wird erstellt",
|
||||||
"address-is-required": "Du musst eine Adresse angeben",
|
"adding-donation": "Sponsoring wird erstellt...",
|
||||||
"after-deletion-we-cant-restore-your-old-profile": "Nach der Löschung können auch die Admins dein Profil nicht wiederherstellen!",
|
"adding-scan": "Scan wird hinzugefügt",
|
||||||
"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.",
|
"address": "Adresse",
|
||||||
"all-associated-donations-will-get-deleted-as-well": "Alle Sponsorings dieser Sponsor:in werden ebenfalls gelöscht",
|
"address-is-required": "Du musst eine Adresse angeben",
|
||||||
"all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!",
|
"after-deletion-we-cant-restore-your-old-profile": "Nach der Löschung können auch die Admins dein Profil nicht wiederherstellen!",
|
||||||
"all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch 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.",
|
||||||
"amount": "Anzahl",
|
"all": "Alle",
|
||||||
"amount-per-kilometer": "Betrag pro Kilometer",
|
"all-associated-donations-will-get-deleted-as-well": "Alle Sponsorings dieser Sponsor:in werden ebenfalls gelöscht",
|
||||||
"apartment-suite-etc": "Apartment, Wohnung, etc.",
|
"all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!",
|
||||||
"application_name": "Lauf für Kaya! - Admin",
|
"all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!",
|
||||||
"applying-changes": "Änderungen anwenden",
|
"already-paid": "Bereits bezahlt",
|
||||||
"attention": "Achtung!",
|
"amount": "Anzahl",
|
||||||
"author": "Autor:in",
|
"amount-per-kilometer": "Betrag pro Kilometer",
|
||||||
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer:innen für den Import bestätigen.",
|
"apartment-suite-etc": "Apartment, Wohnung, etc.",
|
||||||
"by": "von",
|
"application_name": "Lauf für Kaya! - Admin",
|
||||||
"cancel": "Abbrechen",
|
"applying-changes": "Änderungen anwenden",
|
||||||
"cancel-delete": "Löschen abbrechen",
|
"attention": "Achtung!",
|
||||||
"cancel-keep-donor": "Abbrechen, Sponsor:in behalten",
|
"author": "Autor:in",
|
||||||
"cancel-keep-my-profile": "Abbrechen, mein Profil behalten",
|
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer:innen für den Import bestätigen.",
|
||||||
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
|
"by": "von",
|
||||||
"cancel-keep-team": "Abbrechen, Team behalten",
|
"cancel": "Abbrechen",
|
||||||
"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-delete": "Löschen abbrechen",
|
||||||
"card-added": "Karte wurde hinzugefügt",
|
"cancel-keep-donor": "Abbrechen, Sponsor:in behalten",
|
||||||
"card-deleted": "Karte gelöscht",
|
"cancel-keep-my-profile": "Abbrechen, mein Profil behalten",
|
||||||
"card-updated": "Karte aktualisiert",
|
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
|
||||||
"cards": "Läuferkarten",
|
"cancel-keep-statsclient": "Abbrechen und Statsclient behalten",
|
||||||
"change-your-password-here": "Hier kannst du dein Passwort ändern",
|
"cancel-keep-team": "Abbrechen, Team behalten",
|
||||||
"changing-your-password": "Passwort wird geändert",
|
"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.",
|
||||||
"city": "Stadt",
|
"card-added": "Karte wurde hinzugefügt",
|
||||||
"click-to-copy-the-link-into-your-clipboard": "Klicke auf den Link, um ihn in deine Zwischenablage zu kopieren",
|
"card-deleted": "Karte gelöscht",
|
||||||
"click-to-copy-token-to-clipboard": "Klicke auf den Token, um ihn in deine Zwischenablage zu kopieren",
|
"card-updated": "Karte aktualisiert",
|
||||||
"close": "Schließen",
|
"cards": "Läuferkarten",
|
||||||
"code": "Code",
|
"certificates": "Urkunden",
|
||||||
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
|
"change-your-password-here": "Hier kannst du dein Passwort ändern",
|
||||||
"confirm": "Bestätigen",
|
"changing-your-password": "Passwort wird geändert",
|
||||||
"confirm-delete": "Löschung Bestätigen",
|
"city": "Stadt",
|
||||||
"confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen",
|
"click-to-copy-the-link-into-your-clipboard": "Klicke auf den Link, um ihn in deine Zwischenablage zu kopieren",
|
||||||
"confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil löschen",
|
"click-to-copy-token-to-clipboard": "Klicke auf den Token, um ihn in deine Zwischenablage zu kopieren",
|
||||||
"confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.",
|
"close": "Schließen",
|
||||||
"confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.",
|
"code": "Code",
|
||||||
"confirm-deletion": "Löschung Bestätigen",
|
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
|
||||||
"confirm-the-new-password": "Neues Passwort bestätigen",
|
"confirm": "Bestätigen",
|
||||||
"contact": "Kontakt",
|
"confirm-delete": "Löschung Bestätigen",
|
||||||
"contact-deleted": "Kontakt gelöscht",
|
"confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen",
|
||||||
"contact-information": "Kontaktinformation",
|
"confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil löschen",
|
||||||
"contact-is-being-updated": "Kontakt wird aktualisiert ...",
|
"confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.",
|
||||||
"contact-is-not-a-member-in-any-group": "Kontakt gehört zu keiner Gruppe",
|
"confirm-delete-statsclient": "Bestätigung, Statsclient löschen",
|
||||||
"contacts": "Kontakte",
|
"confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.",
|
||||||
"contacts-are-being-loaded": "Kontakte werden geladen ...",
|
"confirm-deletion": "Löschung Bestätigen",
|
||||||
"copied-link-to-clipboard": "Link wurde in die Zwischenablage kopiert",
|
"confirm-the-new-password": "Neues Passwort bestätigen",
|
||||||
"copied-token-to-clipboard": "Token wurde in die Zwischenablage kopiert",
|
"contact": "Kontakt",
|
||||||
"count_organizations": "Organisationen (Anzahl)",
|
"contact-added": "Kontakt wurde hinzugefügt",
|
||||||
"count_teams": "Teams (Anzahl)",
|
"contact-deleted": "Kontakt gelöscht",
|
||||||
"create": "Erstellen",
|
"contact-information": "Kontaktinformation",
|
||||||
"create-a-new": "Erstelle eine neue",
|
"contact-is-being-added": "Kontakt wird erstellt...",
|
||||||
"create-a-new-card": "Neue Läuferkarte erstellen",
|
"contact-is-being-updated": "Kontakt wird aktualisiert ...",
|
||||||
"create-a-new-contact": "Kontakt erstellen",
|
"contact-is-not-a-member-in-any-group": "Kontakt gehört zu keiner Gruppe",
|
||||||
"create-a-new-distance-donation": "Erstelle ein neues Sponsoring",
|
"contacts": "Kontakte",
|
||||||
"create-a-new-donor": "Neue Sponsor:in erstellen",
|
"contacts-are-being-loaded": "Kontakte werden geladen ...",
|
||||||
"create-a-new-fixed-donation": "Erstelle eine neue Festbetragsspende",
|
"copied-link-to-clipboard": "Link wurde in die Zwischenablage kopiert",
|
||||||
"create-a-new-organization": "Neue Organisation anlegen",
|
"copied-token-to-clipboard": "Token wurde in die Zwischenablage kopiert",
|
||||||
"create-a-new-runner": "Neue Läufer:in erstellen",
|
"count_organizations": "Organisationen (Anzahl)",
|
||||||
"create-a-new-scan-fixed-only": "Neuen Scan erstellen (nur mit Festdistanz)",
|
"count_teams": "Teams (Anzahl)",
|
||||||
"create-a-new-scanstation": "Neue Station erstellen",
|
"create": "Erstellen",
|
||||||
"create-a-new-team": "Erstelle ein neues Team",
|
"create-a-new": "Erstelle eine neue",
|
||||||
"create-a-new-track": "Neuen Track erstellen",
|
"create-a-new-card": "Neue Läuferkarte erstellen",
|
||||||
"create-a-new-user": "Neue Benutzer:in anlegen",
|
"create-a-new-contact": "Kontakt erstellen",
|
||||||
"create-a-new-user-group": "Erstelle eine neue Gruppe",
|
"create-a-new-distance-donation": "Erstelle ein neues Sponsoring",
|
||||||
"create-bulk-blanco-cards": "Blankokarten erstellen",
|
"create-a-new-donor": "Neue Sponsor:in erstellen",
|
||||||
"create-bulk-cards": "Blankokarten erstellen",
|
"create-a-new-fixed-donation": "Erstelle eine neue Festbetragsspende",
|
||||||
"create-organization": "Organisation erstellen",
|
"create-a-new-organization": "Neue Organisation anlegen",
|
||||||
"create-team": "Team erstellen",
|
"create-a-new-runner": "Neue Läufer:in erstellen",
|
||||||
"create-track": "Track erstellen",
|
"create-a-new-scan-fixed-only": "Neuen Scan erstellen (nur mit Festdistanz)",
|
||||||
"create-user": "Benutzer anlegen",
|
"create-a-new-scanstation": "Neue Station erstellen",
|
||||||
"created-blanco-cards": "Blankokarten wurden erstellt",
|
"create-a-new-statsclient": "Neuen Statsclient erstellen",
|
||||||
"creating-blanco-cards": "Erstelle Blankokarten",
|
"create-a-new-team": "Erstelle ein neues Team",
|
||||||
"credits": "Credits",
|
"create-a-new-track": "Neuen Track erstellen",
|
||||||
"csv_import__class": "Klasse",
|
"create-a-new-user": "Neue Benutzer:in anlegen",
|
||||||
"csv_import__firstname": "Vorname",
|
"create-a-new-user-group": "Erstelle eine neue Gruppe",
|
||||||
"csv_import__lastname": "Nachname",
|
"create-and-generate-pdf": "Erstellen und PDF herunterladen",
|
||||||
"csv_import__middlename": "Mittelname",
|
"create-bulk-blanco-cards": "Blankokarten erstellen",
|
||||||
"csv_import__team": "Team",
|
"create-bulk-cards": "Blankokarten erstellen",
|
||||||
"danger-zone": "Gefahrenzone",
|
"create-organization": "Organisation erstellen",
|
||||||
"dashboard-greeting": "Hallo",
|
"create-team": "Team erstellen",
|
||||||
"dashboard-title": "Dashboard",
|
"create-track": "Track erstellen",
|
||||||
"datatable": {
|
"create-user": "Benutzer anlegen",
|
||||||
"search": "🔍 Suche ...",
|
"create-without-pdf": "Ohne PDF erstellen",
|
||||||
"an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten",
|
"created-blanco-cards": "Blankokarten wurden erstellt",
|
||||||
"loading": "Wird geladen...",
|
"creating-blanco-cards": "Erstelle Blankokarten",
|
||||||
"next": "Nächste",
|
"credits": "Credits",
|
||||||
"of": "von",
|
"csv_import__class": "Klasse",
|
||||||
"previous": "Vorherige",
|
"csv_import__firstname": "Vorname",
|
||||||
"to": "bis",
|
"csv_import__lastname": "Nachname",
|
||||||
"showing": "Zeige",
|
"csv_import__middlename": "Mittelname",
|
||||||
"no_matching_records_found": "Keine passenden Einträge gefunden",
|
"csv_import__team": "Team",
|
||||||
"page": "Seite",
|
"danger-zone": "Gefahrenzone",
|
||||||
"records": "Einträge",
|
"dashboard-greeting": "Hallo",
|
||||||
"sort_column_ascending": "Spalte aufsteigend sortieren",
|
"dashboard-title": "Dashboard",
|
||||||
"sort_column_descending": "Spalte absteigend sortieren"
|
"datatable": {
|
||||||
},
|
"search": "🔍 Suche ...",
|
||||||
"delete": "Löschen",
|
"an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten",
|
||||||
"delete-contact": "Kontakt löschen",
|
"loading": "Wird geladen...",
|
||||||
"delete-donation": "Sponsporing löschen",
|
"next": "Nächste",
|
||||||
"delete-donor": "Sponsor:in löschen",
|
"of": "von",
|
||||||
"delete-group": "Gruppe löschen",
|
"previous": "Vorherige",
|
||||||
"delete-organization": "Organisation löschen",
|
"to": "bis",
|
||||||
"delete-profile": "Profil löschen",
|
"showing": "Zeige",
|
||||||
"delete-runner": "Läufer:in löschen",
|
"no_matching_records_found": "Keine passenden Einträge gefunden",
|
||||||
"delete-scan": "Scan löschen",
|
"page": "Seite",
|
||||||
"delete-station": "Station löschen",
|
"records": "Einträge",
|
||||||
"delete-team": "Team Löschen",
|
"sort_column_ascending": "Spalte aufsteigend sortieren",
|
||||||
"delete-user": "Benutzer:in löschen",
|
"sort_column_descending": "Spalte absteigend sortieren"
|
||||||
"deleted-scan": "Scan wurde gelöscht",
|
},
|
||||||
"dependency_name": "Name",
|
"delete": "Löschen",
|
||||||
"description": "Beschreibung",
|
"delete-contact": "Kontakt löschen",
|
||||||
"description-optional": "Beschreibung (optional)",
|
"delete-donation": "Sponsoring löschen",
|
||||||
"deselect-all": "Alle abwählen",
|
"delete-donor": "Sponsor:in löschen",
|
||||||
"details": "Details",
|
"delete-group": "Gruppe löschen",
|
||||||
"disabled": "deaktiviert",
|
"delete-organization": "Organisation löschen",
|
||||||
"distance": "Distanz",
|
"delete-profile": "Profil löschen",
|
||||||
"distance-donation": "Sponsoring",
|
"delete-runner": "Läufer:in löschen",
|
||||||
"distance-in-km": "Distanz (in KM)",
|
"delete-scan": "Scan löschen",
|
||||||
"distance-track": "Distanz (+Track)",
|
"delete-station": "Station löschen",
|
||||||
"do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?",
|
"delete-statsclient": "Statsclient löschen",
|
||||||
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
|
"delete-team": "Team Löschen",
|
||||||
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?",
|
"delete-user": "Benutzer:in löschen",
|
||||||
"do-you-want-to-delete-this-donor-with-all-related-donations": "Möchtest du diese Sponsor:in mit all ihren Sponsorings löschen?",
|
"deleted-scan": "Scan wurde gelöscht",
|
||||||
"documentation": "Dokumentation",
|
"dependency_name": "Name",
|
||||||
"donation-amount": "Sponsoringbetrag",
|
"description": "Beschreibung",
|
||||||
"donation-amount-must-be-greater-that-0-00eur": "Der Sponsoringbetrag muss größer als 0.00€ sein.",
|
"description-optional": "Beschreibung (optional)",
|
||||||
"donations": "Sponsorings",
|
"deselect-all": "Alle abwählen",
|
||||||
"donor": "Sponsor:in",
|
"details": "Details",
|
||||||
"donor-added": "Sponsor:in hinzugefügt",
|
"disabled": "deaktiviert",
|
||||||
"donor-deleted": "Sponsor:in gelöscht",
|
"distance": "Distanz",
|
||||||
"donor-has-no-associated-donations": "Zur Sponsor:in gibt es noch keine Sponsorings",
|
"distance-donation": "Sponsoring",
|
||||||
"donor-is-being-added": "Sponsor:in wird hinzugefügt...",
|
"distance-in-km": "Distanz (in KM)",
|
||||||
"donor-is-being-updated": "Sponsor:in wird aktualisiert",
|
"distance-track": "Distanz (+Track)",
|
||||||
"donors": "Sponsor:innen",
|
"do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?",
|
||||||
"donors-are-being-loaded": "Sponsor:innen werden geladen",
|
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
|
||||||
"dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?",
|
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?",
|
||||||
"dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌",
|
"do-you-want-to-delete-this-donor-with-all-related-donations": "Möchtest du diese Sponsor:in mit all ihren Sponsorings löschen?",
|
||||||
"e-mail-adress": "E-Mail-Adresse",
|
"documentation": "Dokumentation",
|
||||||
"edit": "Bearbeiten",
|
"donation-amount": "Sponsoringbetrag",
|
||||||
"edit-a-card": "Läuferkarte bearbeiten",
|
"donation-amount-must-be-greater-that-0-00eur": "Der Sponsoringbetrag muss größer als 0.00€ sein.",
|
||||||
"edit-permissions": "Berechtigungen bearbeiten",
|
"donation-deleted": "Sponsoring gelöscht",
|
||||||
"email_address_or_username": "E-Mail-Adresse/ Benutzername",
|
"donation-updated": "Sponsoring wurde aktualisiert",
|
||||||
"enabled": "aktiviert",
|
"donation_added": "Sponsoring hinzugefügt",
|
||||||
"enabled_large": "Aktiviert",
|
"donations": "Sponsorings",
|
||||||
"english": "Englisch",
|
"donor": "Sponsor:in",
|
||||||
"error-during-import": "Fehler beim Importieren",
|
"donor-added": "Sponsor:in hinzugefügt",
|
||||||
"error-whyile-copying-to-clipboard": "Fehler beim Kopieren in die Zwischenablage",
|
"donor-deleted": "Sponsor:in gelöscht",
|
||||||
"error_on_login": "😢Fehler beim Login",
|
"donor-has-no-associated-donations": "Zur Sponsor:in gibt es noch keine Sponsorings",
|
||||||
"erteilte": "Direkt erteilte",
|
"donor-is-being-added": "Sponsor:in wird hinzugefügt...",
|
||||||
"everything-concerning-your-profile": "Alles zu deinem Profil",
|
"donor-is-being-updated": "Sponsor:in wird aktualisiert",
|
||||||
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃♂️🏃♀️🏃♂️",
|
"donors": "Sponsor:innen",
|
||||||
"faq": "FAQ",
|
"donors-are-being-loaded": "Sponsor:innen werden geladen",
|
||||||
"filter-by-organization-team": "Filtern nach Organisation / Team",
|
"dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?",
|
||||||
"first-name": "Vorname",
|
"dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌",
|
||||||
"first-name-is-required": "Vorname muss angegeben werden",
|
"e-mail-adress": "E-Mail-Adresse",
|
||||||
"first-scan-of-the-day": "Erster Scan des Tages",
|
"edit": "Bearbeiten",
|
||||||
"fixed-donation": "Festbetragsspende",
|
"edit-a-card": "Läuferkarte bearbeiten",
|
||||||
"forgot_password": "Passwort vergessen?",
|
"edit-permissions": "Berechtigungen bearbeiten",
|
||||||
"geerbte": "geerbte",
|
"email_address_or_username": "E-Mail-Adresse/ Benutzername",
|
||||||
"general-stats": "Allgemeine Statistiken",
|
"enabled": "aktiviert",
|
||||||
"general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten",
|
"enabled_large": "Aktiviert",
|
||||||
"generate-runnercards": "Läuferkarten generieren",
|
"english": "Englisch",
|
||||||
"generate-sponsoring-contract": "Sponsoringvertrag generieren",
|
"enter-payment": "Zahlung eingeben",
|
||||||
"generate-sponsoring-contracts": "Sponsoringverträge generieren",
|
"error-during-import": "Fehler beim Importieren",
|
||||||
"generating-pdf": "Pdf wird generiert...",
|
"error-whyile-copying-to-clipboard": "Fehler beim Kopieren in die Zwischenablage",
|
||||||
"generating-pdfs": "PDFs werden generiert...",
|
"error_on_login": "😢Fehler beim Login",
|
||||||
"generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.",
|
"erteilte": "Direkt erteilte",
|
||||||
"german": "Deutsch",
|
"everything-concerning-your-profile": "Alles zu deinem Profil",
|
||||||
"go-to-login": "Zum Login",
|
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃♂️🏃♀️🏃♂️",
|
||||||
"goback": "Zur Startseite",
|
"faq": "FAQ",
|
||||||
"granted": "Gewährt",
|
"filename_sponsoringquittungsliste": "SponsoringQuittungsListe",
|
||||||
"group": "Gruppe",
|
"filter-by-organization-team": "Filtern nach Organisation / Team",
|
||||||
"group-added": "Gruppe hinzugefügt",
|
"first-name": "Vorname",
|
||||||
"group-is-being-added": "Gruppe wird erstellt",
|
"first-name-is-required": "Vorname muss angegeben werden",
|
||||||
"group-name-is-required": "Der Gruppenname muss angegeben werden.",
|
"first-scan-of-the-day": "Erster Scan des Tages",
|
||||||
"group-updated": "Gruppe aktualisiert",
|
"fixed-donation": "Festbetragsspende",
|
||||||
"groups": "Gruppen",
|
"forgot_password": "Passwort vergessen?",
|
||||||
"groups-are-being-loaded": "Gruppen werden geladen",
|
"geerbte": "geerbte",
|
||||||
"home": "Start",
|
"general-stats": "Allgemeine Statistiken",
|
||||||
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
|
"general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten",
|
||||||
"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.",
|
"generate-runner-certificate": "Urkunde generieren",
|
||||||
"import-finished": "Import abgeschlossen",
|
"generate-runner-certificates": "Urkunden generieren",
|
||||||
"import-runners": "Läufer:innen importieren",
|
"generate-runnercards": "Läuferkarten generieren",
|
||||||
"import__target-organization": "Ziel Organisation",
|
"generate-sponsoring-contract": "Sponsoringvertrag generieren",
|
||||||
"imprint": "Impressum ",
|
"generate-sponsoring-contracts": "Sponsoringverträge generieren",
|
||||||
"imprint-loading": "Impressum lädt...",
|
"generating-pdf": "PDF wird generiert...",
|
||||||
"inactive": "Inaktiv",
|
"generating-pdfs": "PDFs werden generiert...",
|
||||||
"installed-version": "Installierte Version",
|
"generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.",
|
||||||
"internal-error": "Interner Fehler",
|
"german": "Deutsch",
|
||||||
"invalid": "Ungültig",
|
"go-to-login": "Zum Login",
|
||||||
"invalid-mail-reset": "Das ist keine gültige E-Mail",
|
"goback": "Zur Startseite",
|
||||||
"just-enter-how-many-you-want-and-the-system-will-create-them": "Gebe einfach ein, wie viele Blankokarten das System erstellen soll.",
|
"granted": "Gewährt",
|
||||||
"laeufer-hinzufuegen": "Läufer:in hinzufügen",
|
"group": "Gruppe",
|
||||||
"laeufer-importieren": "Läufer:innen importieren",
|
"group-added": "Gruppe hinzugefügt",
|
||||||
"laptime": "Rundenzeit",
|
"group-is-being-added": "Gruppe wird erstellt",
|
||||||
"last-name": "Nachname",
|
"group-name-is-required": "Der Gruppenname muss angegeben werden.",
|
||||||
"last-name-is-required": "Nachname muss angegeben werden",
|
"group-updated": "Gruppe aktualisiert",
|
||||||
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
|
"groups": "Gruppen",
|
||||||
"license": "Lizenz",
|
"groups-are-being-loaded": "Gruppen werden geladen",
|
||||||
"licenses-are-being-loaded": "Lizenzen werden geladen...",
|
"home": "Start",
|
||||||
"loading-cards": "Läuferkarten werden geladen",
|
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
|
||||||
"loading-contact-details": "Kontaktdaten werden geladen ...",
|
"if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button": "Wenn du mehrere Blankokarten erstellen willst, nutze doch den \"Blankokarten erstellen\" Knopf.",
|
||||||
"loading-donation-details": "Lade Sponsoringdetails",
|
"import-finished": "Import abgeschlossen",
|
||||||
"loading-donor-details": "Lade Details",
|
"import-runners": "Läufer:innen importieren",
|
||||||
"loading-group-detail": "Lade Gruppendetails...",
|
"import__target-organization": "Ziel Organisation",
|
||||||
"loading-profile-data": "Lade Profildaten",
|
"imprint": "Impressum ",
|
||||||
"loading-runners": "Läufer:innen werden geladen...",
|
"imprint-loading": "Impressum lädt...",
|
||||||
"loading-station-details": "Lade Scanstation-Details ...",
|
"inactive": "Inaktiv",
|
||||||
"log_in": "Anmelden",
|
"installed-version": "Installierte Version",
|
||||||
"log_in_to_your_account": "Bitte melde dich an",
|
"internal-error": "Interner Fehler",
|
||||||
"login_is_checked": "Login wird überprüft",
|
"invalid": "Ungültig",
|
||||||
"logout": "Abmelden",
|
"invalid-mail-reset": "Das ist keine gültige E-Mail",
|
||||||
"mail-validation-in-progress": "E-Mail Verifizierung läuft... ",
|
"just-enter-how-many-you-want-and-the-system-will-create-them": "Gebe einfach ein, wie viele Blankokarten das System erstellen soll.",
|
||||||
"manage-admin-users": "Nutzer verwalten",
|
"key": "Schlüssel",
|
||||||
"middle-name": "Mittelname",
|
"laeufer-hinzufuegen": "Läufer:in hinzufügen",
|
||||||
"minimum-lap-time-in-s": "Minimale Rundenzeit (in Sekunden)",
|
"laeufer-importieren": "Läufer:innen importieren",
|
||||||
"minimum-lap-time-must-be-a-positive-number-or-0": "Die minimale Rundenzeit muss eine positive Zahl oder 0 sein",
|
"laptime": "Rundenzeit",
|
||||||
"name": "Name",
|
"last-name": "Nachname",
|
||||||
"name-is-required": "Der Gruppenname muss angegeben werden",
|
"last-name-is-required": "Nachname muss angegeben werden",
|
||||||
"new-password": "Neues Passwort",
|
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
|
||||||
"no-contact-found": "Keine Kontakte gefunden",
|
"license": "Lizenz",
|
||||||
"no-contact-selected": "Kein Kontakt ausgewählt",
|
"licenses-are-being-loaded": "Lizenzen werden geladen...",
|
||||||
"no-contact-specified": "Kein Kontakt angegeben",
|
"loading-cards": "Läuferkarten werden geladen",
|
||||||
"no-donors-found": "Keine Spender:innen gefunden",
|
"loading-contact-details": "Kontaktdaten werden geladen ...",
|
||||||
"no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢",
|
"loading-donation-details": "Lade Sponsoringdetails",
|
||||||
"no-organization-or-team-found": "Keine Organisationen oder Teams gefunden",
|
"loading-donor-details": "Lade Details",
|
||||||
"no-organization-specified": "Keine Organisation angegeben",
|
"loading-group-detail": "Lade Gruppendetails...",
|
||||||
"no-organizations-found": "Keine Organisationen gefunden",
|
"loading-profile-data": "Lade Profildaten",
|
||||||
"no-runners-found": "Keine Läufer:innen gefunden",
|
"loading-runners": "Läufer:innen werden geladen...",
|
||||||
"no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.",
|
"loading-station-details": "Lade Scanstation-Details ...",
|
||||||
"non-blanko": "Keine/Blankokarte",
|
"log_in": "Anmelden",
|
||||||
"organization": "Organisation",
|
"log_in_to_your_account": "Bitte melde dich an",
|
||||||
"organization-added": "Organisation hinzugefügt",
|
"login_is_checked": "Login wird überprüft",
|
||||||
"organization-deleted": "Organisation gelöscht",
|
"logout": "Abmelden",
|
||||||
"organization-detail-is-being-loaded": "Organisationsdetails werden geladen ...",
|
"mail-validation-in-progress": "E-Mail Verifizierung läuft... ",
|
||||||
"organization-is-being-added": "Organisation wird hinzugefügt ...",
|
"manage-admin-users": "Nutzer verwalten",
|
||||||
"organization-name-is-required": "Der Name muss angegeben werden",
|
"middle-name": "Mittelname",
|
||||||
"organizations": "Organisationen",
|
"minimum-lap-time-in-s": "Minimale Rundenzeit (in Sekunden)",
|
||||||
"organizations-are-being-loaded": "Organisationen werden geladen ...",
|
"minimum-lap-time-must-be-a-positive-number-or-0": "Die minimale Rundenzeit muss eine positive Zahl oder 0 sein",
|
||||||
"orgs": "Organisationen",
|
"must-be-at-least-10-characters-long": "Passwort muss mindestens 10 Zeichen lang sein!",
|
||||||
"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!",
|
"must-contain-a-lowercase-letter": "Passwort muss einen Großbuchstaben enthalten!",
|
||||||
"password": "Passwort",
|
"must-contain-a-number": "Passwort muss eine Zahl enthalten!",
|
||||||
"password-changed": "Passwort wurde aktualisiert!",
|
"must-contain-a-uppercase-letter": "Passwort muss einen Kleinbuchstaben enthalten!",
|
||||||
"password-is-required": "Passwort muss angegeben werden",
|
"name": "Name",
|
||||||
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
|
"name-is-required": "Der Gruppenname muss angegeben werden",
|
||||||
"password-reset-in-progress": "Passwort wird zurückgesetzt...",
|
"new-password": "Neues Passwort",
|
||||||
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
|
"no-contact-found": "Keine Kontakte gefunden",
|
||||||
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
|
"no-contact-selected": "Kein Kontakt ausgewählt",
|
||||||
"passwords-dont-match": "Die Passwörter stimmen nicht überein.",
|
"no-contact-specified": "Kein Kontakt angegeben",
|
||||||
"pdf-generation-failed": "PDF Generierung fehlgeschlagen!",
|
"no-donors-found": "Keine Spender:innen gefunden",
|
||||||
"pdf-successfully-generated": "PDF wurde erfolgreich generiert!",
|
"no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢",
|
||||||
"pdfs-successfully-generated": "Alle PDFs wurden generiert!",
|
"no-organization-or-team-found": "Keine Organisationen oder Teams gefunden",
|
||||||
"per-kilometer": "pro Kilometer",
|
"no-organization-specified": "Keine Organisation angegeben",
|
||||||
"permissions": "Berechtigungen",
|
"no-organizations-found": "Keine Organisationen gefunden",
|
||||||
"permissions-updated": "Berechtigungen aktualisiert!",
|
"no-runners-found": "Keine Läufer:innen gefunden",
|
||||||
"phone": "Telefon",
|
"no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.",
|
||||||
"please-copy-the-token-and-store-it-somewhere-save": "Bitte kopiere dir den Token und bewahre ihn gut auf.",
|
"non-blanko": "Keine/Blankokarte",
|
||||||
"please-provide-a-password": "Bitte gebe ein Passwort an...",
|
"open": "OFFEN",
|
||||||
"please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen",
|
"organization": "Organisation",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.",
|
"organization-added": "Organisation hinzugefügt",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-scan": "Bitte gebe alle notwendigen Informationen an, um einen neuen Scan zu erstellen.",
|
"organization-deleted": "Organisation gelöscht",
|
||||||
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
|
"organization-detail-is-being-loaded": "Organisationsdetails werden geladen ...",
|
||||||
"please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.",
|
"organization-is-being-added": "Organisation wird hinzugefügt ...",
|
||||||
"please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.",
|
"organization-name-is-required": "Der Name muss angegeben werden",
|
||||||
"please-provide-the-required-information-to-add-a-new-organization": "Bitte gebe alle nötigen Informationen an, im die neue Organisation zu erstellen.",
|
"organizations": "Organisationen",
|
||||||
"please-provide-the-required-information-to-add-a-new-runner": "Bitte die benötigten Informationen angeben.",
|
"organizations-are-being-loaded": "Organisationen werden geladen ...",
|
||||||
"please-provide-the-required-information-to-add-a-new-team": "Bitte gebe alle nötigen Informationen an, im das neue Team zu erstellen.",
|
"orgs": "Organisationen",
|
||||||
"please-provide-the-required-information-to-add-a-new-track": "Bitte die benötigten Informationen angeben.",
|
"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-provide-the-required-information-to-add-a-new-user": "Bitte gebe alle nötigen Informationen an, im die neue Benutzer:in zu erstellen.",
|
"paid": "BEZAHLT",
|
||||||
"please-provide-the-required-information-to-create-a-new-scanstation": "Bitte gebe alle für eine Scannerstation notwendigen Informationen an",
|
"paid-amount": "Gezahlter Betrag",
|
||||||
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
|
"password": "Passwort",
|
||||||
"privacy": "Datenschutz",
|
"password-changed": "Passwort wurde aktualisiert!",
|
||||||
"privacy-loading": "Datenschutzerklärung lädt...",
|
"password-is-required": "Passwort muss angegeben werden",
|
||||||
"profile": "Profil",
|
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
|
||||||
"profile-picture": "Profilbild",
|
"password-reset-in-progress": "Passwort wird zurückgesetzt...",
|
||||||
"profile-updated": "Profil wurde aktualisiert!",
|
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
|
||||||
"read-license": "Lizenz-Text lesen",
|
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
|
||||||
"receipt-needed": "Spendenquittung benötigt",
|
"passwords-dont-match": "Die Passwörter stimmen nicht überein!",
|
||||||
"repo_link": "Link",
|
"payment-amount-must-be-greater-than-0-00eur": "Der Zahlungsbetrag muss größer als 0.00€ sein!",
|
||||||
"request-a-new-reset-mail": "Neue Reset-Mail anfordern",
|
"pdf-generation-failed": "PDF Generierung fehlgeschlagen!",
|
||||||
"reset-my-password": "Passwort zurücksetzen",
|
"pdf-successfully-generated": "PDF wurde erfolgreich generiert!",
|
||||||
"reset-password": "Passwort zurücksetzen",
|
"pdfs-successfully-generated": "Alle PDFs wurden generiert!",
|
||||||
"runner": "Läufer:in",
|
"per-kilometer": "pro Kilometer",
|
||||||
"runner-added": "Läufer:in hinzugefügt",
|
"permissions": "Berechtigungen",
|
||||||
"runner-import": "Läufer:innen Import",
|
"permissions-updated": "Berechtigungen aktualisiert!",
|
||||||
"runner-is-being-added": "Läufer:in wird hinzugefügt...",
|
"phone": "Telefon",
|
||||||
"runner-updated": "Läufer:in aktualisiert!",
|
"please-copy-the-token-and-store-it-somewhere-save": "Bitte kopiere dir den Token und bewahre ihn gut auf.",
|
||||||
"runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen",
|
"please-provide-a-password": "Bitte gebe ein Passwort an...",
|
||||||
"runners": "Läufer",
|
"please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen",
|
||||||
"runners-are-being-imported": "Läufer:innen werden importiert ...",
|
"please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.",
|
||||||
"runners-are-being-loaded": "Läufer:innen werden geladen ...",
|
"please-provide-the-nessecary-information-to-create-a-new-scan": "Bitte gebe alle notwendigen Informationen an, um einen neuen Scan zu erstellen.",
|
||||||
"save": "Speichern",
|
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
|
||||||
"save-changes": "Änderungen speichern",
|
"please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.",
|
||||||
"scan-added": "Scan hinzugefügt",
|
"please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.",
|
||||||
"scan-is-being-updated": "Scan wird aktualisiert",
|
"please-provide-the-required-information-to-add-a-new-organization": "Bitte gebe alle nötigen Informationen an, im die neue Organisation zu erstellen.",
|
||||||
"scan-with-fixed-distance": "Scan mit Festdistanz",
|
"please-provide-the-required-information-to-add-a-new-runner": "Bitte die benötigten Informationen angeben.",
|
||||||
"scans": "Scans",
|
"please-provide-the-required-information-to-add-a-new-team": "Bitte gebe alle nötigen Informationen an, im das neue Team zu erstellen.",
|
||||||
"scans-are-being-loaded": "Scans werden geladen",
|
"please-provide-the-required-information-to-add-a-new-track": "Bitte die benötigten Informationen angeben.",
|
||||||
"scanstation": "Scanner Station",
|
"please-provide-the-required-information-to-add-a-new-user": "Bitte gebe alle nötigen Informationen an, im die neue Benutzer:in zu erstellen.",
|
||||||
"scanstation-added": "Station wurde erstellt",
|
"please-provide-the-required-information-to-create-a-new-scanstation": "Bitte gebe alle für eine Scannerstation notwendigen Informationen an",
|
||||||
"scanstation-is-being-added": "Scannerstation wird angelegt...",
|
"please-provide-the-required-information-to-create-a-new-statsclient": "Bitte gebe alle für einen Statsclient notwendigen Informationen an",
|
||||||
"scanstations": "Scanner Stationen",
|
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
|
||||||
"scanstations-are-being-loaded": "Scannerstationen werden geladen...",
|
"please-wait-a-moment-your-login-is-still-being-processed": "Bitte warte einen Moment, deine Anmeldung wird verarbeitet",
|
||||||
"search-for-an-organization-by-name-or-id": "Suche eine Organisation (via Name oder Id)",
|
"prefix": "Prefix",
|
||||||
"search-for-an-organization-or-team-by-name-or-id": "Suche eine Organisation oder ein Team (via Name oder Id)",
|
"privacy": "Datenschutz",
|
||||||
"search-for-donor-name-or-id": "Suche eine Spender:in (via Name oder Id)",
|
"privacy-loading": "Datenschutzerklärung lädt...",
|
||||||
"search-for-permission": "Berechtigungen durchsuchen",
|
"profile": "Profil",
|
||||||
"search-for-runner-by-name-or-id": "Suche eine Läufer:in (via Name oder Id)",
|
"profile-deleted": "Profil gelöscht!",
|
||||||
"select-all": "Alle auswählen",
|
"profile-picture": "Profilbild",
|
||||||
"select-language": "Sprache auswählen",
|
"profile-updated": "Profil wurde aktualisiert!",
|
||||||
"selfservice-registration": "Selfservice Registrierung",
|
"read-license": "Lizenz-Text lesen",
|
||||||
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
|
"receipt-needed": "Spendenquittung benötigt",
|
||||||
"set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen",
|
"repo_link": "Link",
|
||||||
"settings": "Einstellungen",
|
"request-a-new-reset-mail": "Neue Reset-Mail anfordern",
|
||||||
"settings-for-your-profile": "Die Einstellungen deines Accounts",
|
"reset-my-password": "Passwort zurücksetzen",
|
||||||
"something-about-the-group": "Infos zur Gruppe",
|
"reset-password": "Passwort zurücksetzen",
|
||||||
"stats-are-being-loaded": "Die Statistiken werden geladen...",
|
"runner": "Läufer:in",
|
||||||
"status": "Status",
|
"runner-added": "Läufer:in hinzugefügt",
|
||||||
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
|
"runner-import": "Läufer:innen Import",
|
||||||
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
|
"runner-is-being-added": "Läufer:in wird hinzugefügt...",
|
||||||
"team": "Team",
|
"runner-updated": "Läufer:in aktualisiert!",
|
||||||
"team-detail-is-being-loaded": "Team wird geladen...",
|
"runnercards": "Laeuferkarten",
|
||||||
"team-name": "Teamname",
|
"runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen",
|
||||||
"team-name-is-required": "Teamname ist erforderlich",
|
"runners": "Läufer",
|
||||||
"teams": "Teams",
|
"runners-are-being-imported": "Läufer:innen werden importiert ...",
|
||||||
"teams-are-being-loaded": "Teams werden geladen ...",
|
"runners-are-being-loaded": "Läufer:innen werden geladen ...",
|
||||||
"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...",
|
"save": "Speichern",
|
||||||
"the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.",
|
"save-changes": "Änderungen speichern",
|
||||||
"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!",
|
"scan-added": "Scan hinzugefügt",
|
||||||
"there-are-no-cards-yet": "Es gibt noch keine Läuferkarten.",
|
"scan-is-being-updated": "Scan wird aktualisiert",
|
||||||
"there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.",
|
"scan-with-fixed-distance": "Scan mit Festdistanz",
|
||||||
"there-are-no-donations-yet": "Es gibt noch keine Sponsorings",
|
"scans": "Scans",
|
||||||
"there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen",
|
"scans-are-being-loaded": "Scans werden geladen",
|
||||||
"there-are-no-groups-yet": "Es gibt noch keine Gruppen",
|
"scanstation": "Scanner Station",
|
||||||
"there-are-no-organizations-added-yet": "Es wurden noch keine Organisationen hinzugefügt.",
|
"scanstation-added": "Station wurde erstellt",
|
||||||
"there-are-no-runners-added-yet": "Es wurden noch keine Läufer:innen hinzugefügt.",
|
"scanstation-is-being-added": "Scannerstation wird angelegt...",
|
||||||
"there-are-no-scans-yet": "Es gibt noch keine Scans",
|
"scanstations": "Scanner Stationen",
|
||||||
"there-are-no-teams-added-yet": "Es wurden noch keine Teams hinzugefügt.",
|
"scanstations-are-being-loaded": "Scannerstationen werden geladen...",
|
||||||
"there-are-no-users-added-yet": "Es wurden noch keine Benutzer hinzugefügt.",
|
"search-for-an-organization-by-name-or-id": "Suche eine Organisation (via Name oder Id)",
|
||||||
"this-card-is": "Diese Karte ist",
|
"search-for-an-organization-or-team-by-name-or-id": "Suche eine Organisation oder ein Team (via Name oder Id)",
|
||||||
"this-might-take-a-moment": "Das könnte einen kleinen Moment dauern",
|
"search-for-donor-name-or-id": "Suche eine Spender:in (via Name oder Id)",
|
||||||
"this-scanstation-is": "Diese Station ist",
|
"search-for-permission": "Berechtigungen durchsuchen",
|
||||||
"token": "Token",
|
"search-for-runner-by-name-or-id": "Suche eine Läufer:in (via Name oder Id)",
|
||||||
"total-distance": "gelaufene Strecke",
|
"select-all": "Alle auswählen",
|
||||||
"total-donation-amount": "Gesamtbetrag",
|
"select-language": "Sprache auswählen",
|
||||||
"total-donations": "Spendensumme",
|
"selfservice-registration": "Selfservice Registrierung",
|
||||||
"total-scans": "gesamte Scans",
|
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
|
||||||
"track": "Track",
|
"set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen",
|
||||||
"track-added": "Track hinzugefügt",
|
"settings": "Einstellungen",
|
||||||
"track-data-is-being-loaded": "Trackdaten werden geladen",
|
"settings-for-your-profile": "Die Einstellungen deines Accounts",
|
||||||
"track-is-being-added": "Track wird hinzugefügt...",
|
"something-about-the-group": "Infos zur Gruppe",
|
||||||
"track-length-in-m": "Tracklänge (in Metern)",
|
"sponsoring-quittungs-liste_herunterladen": "Sponsoring-Quittungs-Liste herunterladen",
|
||||||
"track-length-must-be-greater-than-0": "Die Länge muss größer als 0 (Meter) sein",
|
"sponsorings": "Sponsoringerklaerungen",
|
||||||
"track-name": "Trackname",
|
"stats-are-being-loaded": "Die Statistiken werden geladen...",
|
||||||
"track-name-must-not-be-empty": "Der Name muss angegeben werden",
|
"statsclient-deleted": "Statsclient wurde gelöscht",
|
||||||
"tracks": "Tracks",
|
"statsclient-is-being-added": "Statsclient wird angelegt...",
|
||||||
"update-password": "Passwort ändern",
|
"statsclients": "Statsclient (aka Beamershow)",
|
||||||
"updated-contact": "Kontakt aktualisiert!",
|
"statsclients-are-being-loaded": "Statsclients werden geladen",
|
||||||
"updated-donor": "Sponsor:in wurde aktualisiert",
|
"status": "Status",
|
||||||
"updated-organization": "Organisation wurde aktualisiert",
|
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
|
||||||
"updated-scan": "Scan wurde aktualisiert",
|
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
|
||||||
"updateing-group": "Gruppe wird aktualisiert...",
|
"team": "Team",
|
||||||
"updating-card": "Karte wird aktualisiert",
|
"team-added": "Team wurde hinzugefügt",
|
||||||
"updating-organization": "Organisation wird aktualisiert",
|
"team-deleted": "Team gelöscht",
|
||||||
"updating-permissions": "Berechtigungen werden aktualisiert...",
|
"team-detail-is-being-loaded": "Team wird geladen...",
|
||||||
"updating-runner": "Läufer:in wird aktualisiert.",
|
"team-is-being-added": "Team wird erstellt...",
|
||||||
"updating-user": "Benutzer:in wird aktualisiert...",
|
"team-name": "Teamname",
|
||||||
"updating-your-profile": "Profil wird aktualisiert...",
|
"team-name-is-required": "Teamname ist erforderlich",
|
||||||
"user-added": "Benutzer hinzugefügt",
|
"teams": "Teams",
|
||||||
"user-groups": "Benutzergruppen",
|
"teams-are-being-loaded": "Teams werden geladen ...",
|
||||||
"user-is-being-added": "Benutzer wird hinzugefügt ...",
|
"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...",
|
||||||
"user-updated": "Benutzer:in wurde aktualisiert",
|
"the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.",
|
||||||
"username": "Benutzername",
|
"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!",
|
||||||
"users": "Benutzer",
|
"the-statsclient-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again": "Der Statsclient Token wird nur einmal angezeigt - du kannst ihn nicht ändern oder ihn dir nochmal anzeigen lassen!",
|
||||||
"valid": "Gültig",
|
"there-are-no-cards-yet": "Es gibt noch keine Läuferkarten.",
|
||||||
"valid-city-is-required": "Du musst eine Stadt angeben",
|
"there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.",
|
||||||
"valid-email-is-required": "Es wird eine valide E-Mail Adresse benötigt",
|
"there-are-no-donations-yet": "Es gibt noch keine Sponsorings",
|
||||||
"valid-international-phone-number-is-required": "Du musst eine Telefonnummer im internationalen Format angeben...",
|
"there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen",
|
||||||
"valid-zipcode-postal-code-is-required": "Du musst eine valide Postleitzahl angeben",
|
"there-are-no-groups-yet": "Es gibt noch keine Gruppen",
|
||||||
"verfuegbare": "Verfügbar",
|
"there-are-no-organizations-added-yet": "Es wurden noch keine Organisationen hinzugefügt.",
|
||||||
"welcome_wavinghand": "Willkommen 👋",
|
"there-are-no-runners-added-yet": "Es wurden noch keine Läufer:innen hinzugefügt.",
|
||||||
"yes-i-copied-the-token": "Ja, ich habe den Token kopiert",
|
"there-are-no-scans-yet": "Es gibt noch keine Scans",
|
||||||
"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!",
|
"there-are-no-teams-added-yet": "Es wurden noch keine Teams hinzugefügt.",
|
||||||
"you-can-now-use-your-new-password-to-log-in-to-your-account": "Du kannst dich jetzt mit deinem neuen Passwort anmelden! 🎉",
|
"there-are-no-users-added-yet": "Es wurden noch keine Benutzer hinzugefügt.",
|
||||||
"you-can-provide-a-runner-but-you-dont-have-to": "Du kannst eine Läufer:in angeben, musst aber nicht.",
|
"this-card-is": "Diese Karte ist",
|
||||||
"you-dont-have-any-scanstations-yet": "Es gibt noch keine Scannerstationen",
|
"this-might-take-a-moment": "Das könnte einen kleinen Moment dauern",
|
||||||
"you-have-to-provide-an-organization": "Du musst eine Organisation angeben",
|
"this-scanstation-is": "Diese Station ist",
|
||||||
"you-have-to-save-your-changes-to-generate-a-link": "Du musst deine Änderungen speichern, um einen Link zu generieren.",
|
"token": "Token",
|
||||||
"you-must-create-at-least-one-card-or-cancel": "Du musst mindestens eine Blankokarte erstellen (oder abbrechen).",
|
"total-distance": "gelaufene Strecke",
|
||||||
"zip-postal-code": "Postleitzahl"
|
"total-donation-amount": "Gesamtbetrag",
|
||||||
}
|
"total-donations": "Spendensumme",
|
||||||
|
"total-paid-amount": "Gezahlter Gesamtbetrag",
|
||||||
|
"total-scans": "gesamte Scans",
|
||||||
|
"total_donation_amount_in_eur": "Gesamtbetrag in €",
|
||||||
|
"track": "Track",
|
||||||
|
"track-added": "Track hinzugefügt",
|
||||||
|
"track-data-is-being-loaded": "Trackdaten werden geladen",
|
||||||
|
"track-is-being-added": "Track wird hinzugefügt...",
|
||||||
|
"track-is-being-updated": "Track wird aktualisiert...",
|
||||||
|
"track-length-in-m": "Tracklänge (in Metern)",
|
||||||
|
"track-length-must-be-greater-than-0": "Die Länge muss größer als 0 (Meter) sein",
|
||||||
|
"track-name": "Trackname",
|
||||||
|
"track-name-must-not-be-empty": "Der Name muss angegeben werden",
|
||||||
|
"track-was-updated": "Track wurde aktualisiert",
|
||||||
|
"tracks": "Tracks",
|
||||||
|
"unpaid": "Offen",
|
||||||
|
"update-card": "Karte aktualisieren",
|
||||||
|
"update-password": "Passwort ändern",
|
||||||
|
"updated-contact": "Kontakt aktualisiert!",
|
||||||
|
"updated-donor": "Sponsor:in wurde aktualisiert",
|
||||||
|
"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-scanclients-yet": "Es gibt noch keine Statsclients",
|
||||||
|
"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",
|
||||||
|
"delete-cards": "Karten löschen",
|
||||||
|
"cards-deleted": "Karten gelöscht"
|
||||||
|
}
|
||||||
+478
-421
@@ -1,422 +1,479 @@
|
|||||||
{
|
{
|
||||||
"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-the-first-statsclient": "Add your first statsclient.",
|
||||||
"add-your-first-contact": "Add your first contact",
|
"add-user-group": "Add User Group",
|
||||||
"add-your-first-donor": "add your first donor",
|
"add-your-first-card": "Add your first card",
|
||||||
"add-your-first-group": "Add your first group",
|
"add-your-first-contact": "Add your first contact",
|
||||||
"add-your-first-organization": "Add your first organization",
|
"add-your-first-donor": "add your first donor",
|
||||||
"add-your-first-runner": "Add your first runner",
|
"add-your-first-group": "Add your first group",
|
||||||
"add-your-first-team": "Add your first team",
|
"add-your-first-organization": "Add your first organization",
|
||||||
"add-your-first-track": "Add your first track.",
|
"add-your-first-runner": "Add your first runner",
|
||||||
"add-your-first-user": "Add your first user",
|
"add-your-first-team": "Add your first team",
|
||||||
"add-your-fist-donation": "Add your fist donation",
|
"add-your-first-track": "Add your first track.",
|
||||||
"add-your-fist-scan": "Add your fist scan",
|
"add-your-first-user": "Add your first user",
|
||||||
"adding-card": "Adding Card",
|
"add-your-fist-donation": "Add your fist donation",
|
||||||
"adding-scan": "Adding Scan",
|
"add-your-fist-scan": "Add your fist scan",
|
||||||
"address": "Address",
|
"adding-card": "Adding Card",
|
||||||
"address-is-required": "Address is required",
|
"adding-donation": "Adding donation...",
|
||||||
"after-deletion-we-cant-restore-your-old-profile": "After deletion we can't restore your old profile!",
|
"adding-scan": "Adding Scan",
|
||||||
"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": "Address",
|
||||||
"all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well",
|
"address-is-required": "Address is required",
|
||||||
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
|
"after-deletion-we-cant-restore-your-old-profile": "After deletion we can't restore your old profile!",
|
||||||
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and 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.",
|
||||||
"amount": "Amount",
|
"all": "all",
|
||||||
"amount-per-kilometer": "Amount per kilometer",
|
"all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well",
|
||||||
"apartment-suite-etc": "Apartment, suite, etc.",
|
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
|
||||||
"application_name": "Lauf für Kaya! - Admin",
|
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!",
|
||||||
"applying-changes": "Applying Changes",
|
"already-paid": "Already paid",
|
||||||
"attention": "Attention!",
|
"amount": "Amount",
|
||||||
"author": "Author",
|
"amount-per-kilometer": "Amount per kilometer",
|
||||||
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.",
|
"apartment-suite-etc": "Apartment, suite, etc.",
|
||||||
"by": "by",
|
"application_name": "Lauf für Kaya! - Admin",
|
||||||
"cancel": "Cancel",
|
"applying-changes": "Applying Changes",
|
||||||
"cancel-delete": "Cancel Delete",
|
"attention": "Attention!",
|
||||||
"cancel-keep-donor": "Cancel, keep donor",
|
"author": "Author",
|
||||||
"cancel-keep-my-profile": "Cancel, keep my profile",
|
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.",
|
||||||
"cancel-keep-organization": "Cancel, keep organization",
|
"by": "by",
|
||||||
"cancel-keep-team": "Cancel, keep team",
|
"cancel": "Cancel",
|
||||||
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
|
"cancel-delete": "Cancel Delete",
|
||||||
"card-added": "Card added",
|
"cancel-keep-donor": "Cancel, keep donor",
|
||||||
"card-deleted": "Card deleted",
|
"cancel-keep-my-profile": "Cancel, keep my profile",
|
||||||
"card-updated": "Card updated",
|
"cancel-keep-organization": "Cancel, keep organization",
|
||||||
"cards": "Cards",
|
"cancel-keep-statsclient": "Cancel and keep statsclient",
|
||||||
"change-your-password-here": "Change your password here",
|
"cancel-keep-team": "Cancel, keep team",
|
||||||
"changing-your-password": "Changing your password",
|
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
|
||||||
"city": "City",
|
"card-added": "Card added",
|
||||||
"click-to-copy-the-link-into-your-clipboard": "Click to copy the link into your clipboard",
|
"card-deleted": "Card deleted",
|
||||||
"click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard",
|
"card-updated": "Card updated",
|
||||||
"close": "Close",
|
"cards": "Cards",
|
||||||
"code": "Code",
|
"certificates": "Certificates",
|
||||||
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
|
"change-your-password-here": "Change your password here",
|
||||||
"confirm": "Confirm",
|
"changing-your-password": "Changing your password",
|
||||||
"confirm-delete": "Confirm Delete",
|
"city": "City",
|
||||||
"confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations",
|
"click-to-copy-the-link-into-your-clipboard": "Click to copy the link into your clipboard",
|
||||||
"confirm-delete-my-user-profile": "Confirm, delete my user profile",
|
"click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard",
|
||||||
"confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.",
|
"close": "Close",
|
||||||
"confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.",
|
"code": "Code",
|
||||||
"confirm-deletion": "Confirm Deletion",
|
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
|
||||||
"confirm-the-new-password": "Confirm the new password",
|
"confirm": "Confirm",
|
||||||
"contact": "Contact",
|
"confirm-delete": "Confirm Delete",
|
||||||
"contact-deleted": "Contact deleted",
|
"confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations",
|
||||||
"contact-information": "Contact Information",
|
"confirm-delete-my-user-profile": "Confirm, delete my user profile",
|
||||||
"contact-is-being-updated": "Contact is being updated...",
|
"confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.",
|
||||||
"contact-is-not-a-member-in-any-group": "Contact is not a member in any group",
|
"confirm-delete-statsclient": "Confirm, delete statsclient",
|
||||||
"contacts": "Contacts",
|
"confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.",
|
||||||
"contacts-are-being-loaded": "contacts are being loaded...",
|
"confirm-deletion": "Confirm Deletion",
|
||||||
"copied-link-to-clipboard": "Copied link to clipboard",
|
"confirm-the-new-password": "Confirm the new password",
|
||||||
"copied-token-to-clipboard": "Copied token to clipboard",
|
"contact": "Contact",
|
||||||
"count_organizations": "# Organizations",
|
"contact-added": "Contact added",
|
||||||
"count_teams": "# Teams",
|
"contact-deleted": "Contact deleted",
|
||||||
"create": "Create",
|
"contact-information": "Contact Information",
|
||||||
"create-a-new": "Create a new",
|
"contact-is-being-added": "Contact is being added...",
|
||||||
"create-a-new-card": "Create a new card",
|
"contact-is-being-updated": "Contact is being updated...",
|
||||||
"create-a-new-contact": "Create a new contact",
|
"contact-is-not-a-member-in-any-group": "Contact is not a member in any group",
|
||||||
"create-a-new-distance-donation": "Create a new distance donation",
|
"contacts": "Contacts",
|
||||||
"create-a-new-donor": "Create a new donor",
|
"contacts-are-being-loaded": "contacts are being loaded...",
|
||||||
"create-a-new-fixed-donation": "Create a new fixed donation",
|
"copied-link-to-clipboard": "Copied link to clipboard",
|
||||||
"create-a-new-organization": "Create a new Organization",
|
"copied-token-to-clipboard": "Copied token to clipboard",
|
||||||
"create-a-new-runner": "Create a new Runner",
|
"count_organizations": "# Organizations",
|
||||||
"create-a-new-scan-fixed-only": "Create a new scan (fixed only)",
|
"count_teams": "# Teams",
|
||||||
"create-a-new-scanstation": "Create a new station",
|
"create": "Create",
|
||||||
"create-a-new-team": "Create a new team",
|
"create-a-new": "Create a new",
|
||||||
"create-a-new-track": "Create a new Track",
|
"create-a-new-card": "Create a new card",
|
||||||
"create-a-new-user": "Create a new User",
|
"create-a-new-contact": "Create a new contact",
|
||||||
"create-a-new-user-group": "Create a new user group",
|
"create-a-new-distance-donation": "Create a new distance donation",
|
||||||
"create-bulk-blanco-cards": "Create bulk blanco cards",
|
"create-a-new-donor": "Create a new donor",
|
||||||
"create-bulk-cards": "Add blanco cards",
|
"create-a-new-fixed-donation": "Create a new fixed donation",
|
||||||
"create-organization": "Create Organization",
|
"create-a-new-organization": "Create a new Organization",
|
||||||
"create-team": "Create Team",
|
"create-a-new-runner": "Create a new Runner",
|
||||||
"create-track": "Create Track",
|
"create-a-new-scan-fixed-only": "Create a new scan (fixed only)",
|
||||||
"create-user": "Create User",
|
"create-a-new-scanstation": "Create a new station",
|
||||||
"created-blanco-cards": "Created blanco cards",
|
"create-a-new-statsclient": "Create a new statsclient",
|
||||||
"creating-blanco-cards": "Creating blanco cards",
|
"create-a-new-team": "Create a new team",
|
||||||
"credits": "Credits",
|
"create-a-new-track": "Create a new Track",
|
||||||
"csv_import__class": "Class",
|
"create-a-new-user": "Create a new User",
|
||||||
"csv_import__firstname": "Firstname",
|
"create-a-new-user-group": "Create a new user group",
|
||||||
"csv_import__lastname": "Lastname",
|
"create-and-generate-pdf": "Create and generate PDF",
|
||||||
"csv_import__middlename": "Middlename",
|
"create-bulk-blanco-cards": "Create bulk blanco cards",
|
||||||
"csv_import__team": "Team",
|
"create-bulk-cards": "Add blanco cards",
|
||||||
"danger-zone": "Danger zone",
|
"create-organization": "Create Organization",
|
||||||
"dashboard-greeting": "Hello",
|
"create-team": "Create Team",
|
||||||
"dashboard-title": "Dashboard",
|
"create-track": "Create Track",
|
||||||
"datatable": {
|
"create-user": "Create User",
|
||||||
"search": "🔍 Search...",
|
"create-without-pdf": "Create without PDF",
|
||||||
"sort_column_ascending": "Sort column ascending",
|
"created-blanco-cards": "Created blanco cards",
|
||||||
"sort_column_descending": "Sort column descending",
|
"creating-blanco-cards": "Creating blanco cards",
|
||||||
"previous": "Previous",
|
"credits": "Credits",
|
||||||
"next": "Next",
|
"csv_import__class": "Class",
|
||||||
"page": "Page",
|
"csv_import__firstname": "Firstname",
|
||||||
"showing": "Showing",
|
"csv_import__lastname": "Lastname",
|
||||||
"records": "Records",
|
"csv_import__middlename": "Middlename",
|
||||||
"of": "of",
|
"csv_import__team": "Team",
|
||||||
"to": "to",
|
"danger-zone": "Danger zone",
|
||||||
"loading": "Loading...",
|
"dashboard-greeting": "Hello",
|
||||||
"no_matching_records_found": "No matching records found",
|
"dashboard-title": "Dashboard",
|
||||||
"an_error_happened_while_fetching_the_data": "An error happened while fetching the data"
|
"datatable": {
|
||||||
},
|
"search": "🔍 Search...",
|
||||||
"delete": "Delete",
|
"sort_column_ascending": "Sort column ascending",
|
||||||
"delete-contact": "Delete Contact",
|
"sort_column_descending": "Sort column descending",
|
||||||
"delete-donation": "Delete Donation",
|
"previous": "Previous",
|
||||||
"delete-donor": "Delete donor",
|
"next": "Next",
|
||||||
"delete-group": "Delete Group",
|
"page": "Page",
|
||||||
"delete-organization": "Delete Organization",
|
"showing": "Showing",
|
||||||
"delete-profile": "Delete Profile",
|
"records": "Records",
|
||||||
"delete-runner": "Delete Runner",
|
"of": "of",
|
||||||
"delete-scan": "Delete scan",
|
"to": "to",
|
||||||
"delete-station": "Delete station",
|
"loading": "Loading...",
|
||||||
"delete-team": "Delete Team",
|
"no_matching_records_found": "No matching records found",
|
||||||
"delete-user": "Delete User",
|
"an_error_happened_while_fetching_the_data": "An error happened while fetching the data"
|
||||||
"deleted-scan": "Deleted scan",
|
},
|
||||||
"dependency_name": "Name",
|
"delete": "Delete",
|
||||||
"description": "description",
|
"delete-contact": "Delete Contact",
|
||||||
"description-optional": "Description (optional)",
|
"delete-donation": "Delete Donation",
|
||||||
"deselect-all": "deselect all",
|
"delete-donor": "Delete donor",
|
||||||
"details": "Details",
|
"delete-group": "Delete Group",
|
||||||
"disabled": "disabled",
|
"delete-organization": "Delete Organization",
|
||||||
"distance": "Distance",
|
"delete-profile": "Delete Profile",
|
||||||
"distance-donation": "distance donation",
|
"delete-runner": "Delete Runner",
|
||||||
"distance-in-km": "Distance in km",
|
"delete-scan": "Delete scan",
|
||||||
"distance-track": "Distance (+Track)",
|
"delete-station": "Delete station",
|
||||||
"do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?",
|
"delete-statsclient": "Delete statsclient",
|
||||||
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
|
"delete-team": "Delete Team",
|
||||||
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
|
"delete-user": "Delete User",
|
||||||
"do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations",
|
"deleted-scan": "Deleted scan",
|
||||||
"documentation": "Documentation",
|
"dependency_name": "Name",
|
||||||
"donation-amount": "Donation amount",
|
"description": "description",
|
||||||
"donation-amount-must-be-greater-that-0-00eur": "Donation amount must be greater that 0.00€",
|
"description-optional": "Description (optional)",
|
||||||
"donations": "Donations",
|
"deselect-all": "deselect all",
|
||||||
"donor": "Donor",
|
"details": "Details",
|
||||||
"donor-added": "Donor added",
|
"disabled": "disabled",
|
||||||
"donor-deleted": "donor deleted",
|
"distance": "Distance",
|
||||||
"donor-has-no-associated-donations": "Donor has no associated donations.",
|
"distance-donation": "distance donation",
|
||||||
"donor-is-being-added": "Donor is being added...",
|
"distance-in-km": "Distance in km",
|
||||||
"donor-is-being-updated": "Donor is being updated",
|
"distance-track": "Distance (+Track)",
|
||||||
"donors": "Donors",
|
"do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?",
|
||||||
"donors-are-being-loaded": "donors are being loaded",
|
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
|
||||||
"dont-have-your-email-connected": "Don't have your email connected?",
|
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
|
||||||
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
|
"do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations",
|
||||||
"e-mail-adress": "E-Mail Adress",
|
"documentation": "Documentation",
|
||||||
"edit": "Edit",
|
"donation-amount": "Donation amount",
|
||||||
"edit-a-card": "Edit a card",
|
"donation-amount-must-be-greater-that-0-00eur": "Donation amount must be greater that 0.00€",
|
||||||
"edit-permissions": "edit permissions",
|
"donation-deleted": "Donation deleted",
|
||||||
"email_address_or_username": "Email / username",
|
"donation-updated": "Donation updated",
|
||||||
"enabled": "enabled",
|
"donation_added": "Donation_added",
|
||||||
"enabled_large": "Enabled",
|
"donations": "Donations",
|
||||||
"english": "English",
|
"donor": "Donor",
|
||||||
"error-during-import": "Error during import",
|
"donor-added": "Donor added",
|
||||||
"error-whyile-copying-to-clipboard": "Error while copying to clipboard",
|
"donor-deleted": "donor deleted",
|
||||||
"error_on_login": "Error on login",
|
"donor-has-no-associated-donations": "Donor has no associated donations.",
|
||||||
"erteilte": "Directly granted",
|
"donor-is-being-added": "Donor is being added...",
|
||||||
"everything-concerning-your-profile": "Everything concerning your profile",
|
"donor-is-being-updated": "Donor is being updated",
|
||||||
"everything-is-more-fun-together": "everything is more fun together 🏃♂️🏃♀️🏃♂️",
|
"donors": "Donors",
|
||||||
"faq": "FAQ",
|
"donors-are-being-loaded": "donors are being loaded",
|
||||||
"filter-by-organization-team": "Filter by Organization/ Team",
|
"dont-have-your-email-connected": "Don't have your email connected?",
|
||||||
"first-name": "First name",
|
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
|
||||||
"first-name-is-required": "First Name is required",
|
"e-mail-adress": "E-Mail Adress",
|
||||||
"first-scan-of-the-day": "First scan of the day.",
|
"edit": "Edit",
|
||||||
"fixed-donation": "fixed donation",
|
"edit-a-card": "Edit a card",
|
||||||
"forgot_password": "Forgot your password?",
|
"edit-permissions": "edit permissions",
|
||||||
"geerbte": "inherited",
|
"email_address_or_username": "Email / username",
|
||||||
"general-stats": "General Stats",
|
"enabled": "enabled",
|
||||||
"general_promise_error": "😢 Error",
|
"enabled_large": "Enabled",
|
||||||
"generate-runnercards": "Generate Runnercards",
|
"english": "English",
|
||||||
"generate-sponsoring-contract": "generate sponsoring contract",
|
"enter-payment": "Enter payment",
|
||||||
"generate-sponsoring-contracts": "generate sponsoring contracts",
|
"error-during-import": "Error during import",
|
||||||
"generating-pdf": "generating PDF...",
|
"error-whyile-copying-to-clipboard": "Error while copying to clipboard",
|
||||||
"generating-pdfs": "generating PDFs...",
|
"error_on_login": "Error on login",
|
||||||
"generic-ui-logic-error": "Something went wrong in the UI logic",
|
"erteilte": "Directly granted",
|
||||||
"german": "German",
|
"everything-concerning-your-profile": "Everything concerning your profile",
|
||||||
"go-to-login": "Go To Login",
|
"everything-is-more-fun-together": "everything is more fun together 🏃♂️🏃♀️🏃♂️",
|
||||||
"goback": "Go Home",
|
"faq": "FAQ",
|
||||||
"granted": "granted",
|
"filename_sponsoringquittungsliste": "DonorReceiptList",
|
||||||
"group": "Group",
|
"filter-by-organization-team": "Filter by Organization/ Team",
|
||||||
"group-added": "Group added",
|
"first-name": "First name",
|
||||||
"group-is-being-added": "Group is being added...",
|
"first-name-is-required": "First Name is required",
|
||||||
"group-name-is-required": "Group name is required",
|
"first-scan-of-the-day": "First scan of the day.",
|
||||||
"group-updated": "group updated",
|
"fixed-donation": "fixed donation",
|
||||||
"groups": "Groups",
|
"forgot_password": "Forgot your password?",
|
||||||
"groups-are-being-loaded": "Groups are being loaded",
|
"geerbte": "inherited",
|
||||||
"home": "Home",
|
"general-stats": "General Stats",
|
||||||
"icon-image-credits": "We also want to thank these projects for illustrations and icons:",
|
"general_promise_error": "😢 Error",
|
||||||
"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.",
|
"generate-runner-certificate": "Generate runner certificate",
|
||||||
"import-finished": "Import finished",
|
"generate-runner-certificates": "Generate runner certificates",
|
||||||
"import-runners": "Import runners",
|
"generate-runnercards": "Generate Runnercards",
|
||||||
"import__target-organization": "Target Organization",
|
"generate-sponsoring-contract": "generate sponsoring contract",
|
||||||
"imprint": "Imprint",
|
"generate-sponsoring-contracts": "generate sponsoring contracts",
|
||||||
"imprint-loading": "Imprint loading...",
|
"generating-pdf": "generating PDF...",
|
||||||
"inactive": "Inactive",
|
"generating-pdfs": "generating PDFs...",
|
||||||
"installed-version": "Installed version",
|
"generic-ui-logic-error": "Something went wrong in the UI logic",
|
||||||
"internal-error": "Internal Error",
|
"german": "German",
|
||||||
"invalid": "Invalid",
|
"go-to-login": "Go To Login",
|
||||||
"invalid-mail-reset": "the provided email is invalid",
|
"goback": "Go Home",
|
||||||
"just-enter-how-many-you-want-and-the-system-will-create-them": "Just enter how many you want and the system will create them",
|
"granted": "granted",
|
||||||
"laeufer-hinzufuegen": "Add runner",
|
"group": "Group",
|
||||||
"laeufer-importieren": "Läufer importieren",
|
"group-added": "Group added",
|
||||||
"laptime": "Laptime",
|
"group-is-being-added": "Group is being added...",
|
||||||
"last-name": "Last name",
|
"group-name-is-required": "Group name is required",
|
||||||
"last-name-is-required": "Last Name is required",
|
"group-updated": "group updated",
|
||||||
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
|
"groups": "Groups",
|
||||||
"license": "License",
|
"groups-are-being-loaded": "Groups are being loaded",
|
||||||
"licenses-are-being-loaded": "Licenses are being loaded...",
|
"home": "Home",
|
||||||
"loading-cards": "Loading cards",
|
"icon-image-credits": "We also want to thank these projects for illustrations and icons:",
|
||||||
"loading-contact-details": "Loading contact details...",
|
"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.",
|
||||||
"loading-donation-details": "Loading donation details",
|
"import-finished": "Import finished",
|
||||||
"loading-donor-details": "Loading donor details",
|
"import-runners": "Import runners",
|
||||||
"loading-group-detail": "Loading group detail...",
|
"import__target-organization": "Target Organization",
|
||||||
"loading-profile-data": "Loading profile data",
|
"imprint": "Imprint",
|
||||||
"loading-runners": "loading runners...",
|
"imprint-loading": "Imprint loading...",
|
||||||
"loading-station-details": "Loading station details",
|
"inactive": "Inactive",
|
||||||
"log_in": "Log in",
|
"installed-version": "Installed version",
|
||||||
"log_in_to_your_account": "Log in to your account",
|
"internal-error": "Internal Error",
|
||||||
"login_is_checked": "Login is being checked...",
|
"invalid": "Invalid",
|
||||||
"logout": "Logout",
|
"invalid-mail-reset": "the provided email is invalid",
|
||||||
"mail-validation-in-progress": "mail validation in progress...",
|
"just-enter-how-many-you-want-and-the-system-will-create-them": "Just enter how many you want and the system will create them",
|
||||||
"manage-admin-users": "manage admin users",
|
"key": "Key",
|
||||||
"middle-name": "Middle name",
|
"laeufer-hinzufuegen": "Add runner",
|
||||||
"minimum-lap-time-in-s": "minimum lap time in s",
|
"laeufer-importieren": "Läufer importieren",
|
||||||
"minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0",
|
"laptime": "Laptime",
|
||||||
"name": "Name",
|
"last-name": "Last name",
|
||||||
"name-is-required": "Name is required",
|
"last-name-is-required": "Last Name is required",
|
||||||
"new-password": "New password",
|
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
|
||||||
"no-contact-found": "No contacts found",
|
"license": "License",
|
||||||
"no-contact-selected": "No contact selected",
|
"licenses-are-being-loaded": "Licenses are being loaded...",
|
||||||
"no-contact-specified": "no contact specified",
|
"loading-cards": "Loading cards",
|
||||||
"no-donors-found": "No donors found",
|
"loading-contact-details": "Loading contact details...",
|
||||||
"no-license-text-could-be-found": "No license text could be found 😢",
|
"loading-donation-details": "Loading donation details",
|
||||||
"no-organization-or-team-found": "No organization or team found",
|
"loading-donor-details": "Loading donor details",
|
||||||
"no-organization-specified": "no organization specified",
|
"loading-group-detail": "Loading group detail...",
|
||||||
"no-organizations-found": "No organizations found",
|
"loading-profile-data": "Loading profile data",
|
||||||
"no-runners-found": "No runners found",
|
"loading-runners": "loading runners...",
|
||||||
"no-tracks-added-yet": "there are no tracks added yet.",
|
"loading-station-details": "Loading station details",
|
||||||
"non-blanko": "Non/Blanko",
|
"log_in": "Log in",
|
||||||
"organization": "Organization",
|
"log_in_to_your_account": "Log in to your account",
|
||||||
"organization-added": "Organization added",
|
"login_is_checked": "Login is being checked...",
|
||||||
"organization-deleted": "Organization deleted",
|
"logout": "Logout",
|
||||||
"organization-detail-is-being-loaded": "organization detail is being loaded...",
|
"mail-validation-in-progress": "mail validation in progress...",
|
||||||
"organization-is-being-added": "Organization is being added...",
|
"manage-admin-users": "manage admin users",
|
||||||
"organization-name-is-required": "Organization name is required",
|
"middle-name": "Middle name",
|
||||||
"organizations": "Organizations",
|
"minimum-lap-time-in-s": "minimum lap time in s",
|
||||||
"organizations-are-being-loaded": "organizations are being loaded...",
|
"minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0",
|
||||||
"orgs": "Organizations",
|
"must-be-at-least-10-characters-long": "Must be at least 10 characters long!",
|
||||||
"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!",
|
"must-contain-a-lowercase-letter": "Must contain a lowercase letter!",
|
||||||
"password": "Password",
|
"must-contain-a-number": "Must contain a number!",
|
||||||
"password-changed": "Password changed!",
|
"must-contain-a-uppercase-letter": "Must contain a uppercase letter!",
|
||||||
"password-is-required": "Password is required",
|
"name": "Name",
|
||||||
"password-reset-failed": "Password reset failed!",
|
"name-is-required": "Name is required",
|
||||||
"password-reset-in-progress": "Password Reset in Progress...",
|
"new-password": "New password",
|
||||||
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
|
"no-contact-found": "No contacts found",
|
||||||
"password-reset-successful": "Password Reset successful!",
|
"no-contact-selected": "No contact selected",
|
||||||
"passwords-dont-match": "Passwords don't match",
|
"no-contact-specified": "no contact specified",
|
||||||
"pdf-generation-failed": "PDF generation failed!",
|
"no-donors-found": "No donors found",
|
||||||
"pdf-successfully-generated": "PDF successfully generated!",
|
"no-license-text-could-be-found": "No license text could be found 😢",
|
||||||
"pdfs-successfully-generated": "PDFs successfully generated!",
|
"no-organization-or-team-found": "No organization or team found",
|
||||||
"per-kilometer": "per Kilometer",
|
"no-organization-specified": "no organization specified",
|
||||||
"permissions": "Permissions",
|
"no-organizations-found": "No organizations found",
|
||||||
"permissions-updated": "Permissions updated!",
|
"no-runners-found": "No runners found",
|
||||||
"phone": "Phone",
|
"no-tracks-added-yet": "there are no tracks added yet.",
|
||||||
"please-copy-the-token-and-store-it-somewhere-save": "Please copy the token and store it somewhere safe.",
|
"non-blanko": "Non/Blanko",
|
||||||
"please-provide-a-password": "Please provide a password...",
|
"open": "OPEN",
|
||||||
"please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor",
|
"organization": "Organization",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation",
|
"organization-added": "Organization added",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-scan": "Please provide the nessecary information to create a new scan.",
|
"organization-deleted": "Organization deleted",
|
||||||
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
|
"organization-detail-is-being-loaded": "organization detail is being loaded...",
|
||||||
"please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.",
|
"organization-is-being-added": "Organization is being added...",
|
||||||
"please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.",
|
"organization-name-is-required": "Organization name is required",
|
||||||
"please-provide-the-required-information-to-add-a-new-organization": "Please provide the required information to add a new organization.",
|
"organizations": "Organizations",
|
||||||
"please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.",
|
"organizations-are-being-loaded": "organizations are being loaded...",
|
||||||
"please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.",
|
"orgs": "Organizations",
|
||||||
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
|
"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-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.",
|
"paid": "PAID",
|
||||||
"please-provide-the-required-information-to-create-a-new-scanstation": "Please provide the required information to create a new scanstation",
|
"paid-amount": "Paid amount",
|
||||||
"please-request-a-new-reset-mail": "Please request a new reset mail...",
|
"password": "Password",
|
||||||
"privacy": "Privacy",
|
"password-changed": "Password changed!",
|
||||||
"privacy-loading": "Privacy loading...",
|
"password-is-required": "Password is required",
|
||||||
"profile": "Profile",
|
"password-reset-failed": "Password reset failed!",
|
||||||
"profile-picture": "Profile Picture",
|
"password-reset-in-progress": "Password Reset in Progress...",
|
||||||
"profile-updated": "Profile updated!",
|
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
|
||||||
"read-license": "Read License",
|
"password-reset-successful": "Password Reset successful!",
|
||||||
"receipt-needed": "Receipt needed",
|
"passwords-dont-match": "Passwords don't match!",
|
||||||
"repo_link": "Link",
|
"payment-amount-must-be-greater-than-0-00eur": "Payment amount must be greater than 0.00€!",
|
||||||
"request-a-new-reset-mail": "Request a new reset mail",
|
"pdf-generation-failed": "PDF generation failed!",
|
||||||
"reset-my-password": "Reset my password",
|
"pdf-successfully-generated": "PDF successfully generated!",
|
||||||
"reset-password": "Reset your password",
|
"pdfs-successfully-generated": "PDFs successfully generated!",
|
||||||
"runner": "Runner",
|
"per-kilometer": "per Kilometer",
|
||||||
"runner-added": "Runner added",
|
"permissions": "Permissions",
|
||||||
"runner-import": "Runner Import",
|
"permissions-updated": "Permissions updated!",
|
||||||
"runner-is-being-added": "Runner is being added...",
|
"phone": "Phone",
|
||||||
"runner-updated": "Runner updated!",
|
"please-copy-the-token-and-store-it-somewhere-save": "Please copy the token and store it somewhere safe.",
|
||||||
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
|
"please-provide-a-password": "Please provide a password...",
|
||||||
"runners": "Runners",
|
"please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor",
|
||||||
"runners-are-being-imported": "Runners are being imported...",
|
"please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation",
|
||||||
"runners-are-being-loaded": "runners are being loaded...",
|
"please-provide-the-nessecary-information-to-create-a-new-scan": "Please provide the nessecary information to create a new scan.",
|
||||||
"save": "Save",
|
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
|
||||||
"save-changes": "Save Changes",
|
"please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.",
|
||||||
"scan-added": "Scan added",
|
"please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.",
|
||||||
"scan-is-being-updated": "Scan is being updated",
|
"please-provide-the-required-information-to-add-a-new-organization": "Please provide the required information to add a new organization.",
|
||||||
"scan-with-fixed-distance": "Scan with fixed distance",
|
"please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.",
|
||||||
"scans": "Scans",
|
"please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.",
|
||||||
"scans-are-being-loaded": "Scans are being loaded",
|
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
|
||||||
"scanstation": "Scanstation",
|
"please-provide-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.",
|
||||||
"scanstation-added": "Scanstation added",
|
"please-provide-the-required-information-to-create-a-new-scanstation": "Please provide the required information to create a new scanstation",
|
||||||
"scanstation-is-being-added": "Adding scanstation...",
|
"please-provide-the-required-information-to-create-a-new-statsclient": "Please provide the required information to create a new statsclient",
|
||||||
"scanstations": "Scanstations",
|
"please-request-a-new-reset-mail": "Please request a new reset mail...",
|
||||||
"scanstations-are-being-loaded": "Loading scanstations...",
|
"please-wait-a-moment-your-login-is-still-being-processed": "Please wait a moment, your login is still being processed",
|
||||||
"search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)",
|
"prefix": "Prefix",
|
||||||
"search-for-an-organization-or-team-by-name-or-id": "Search for an organization or team (by name or id)",
|
"privacy": "Privacy",
|
||||||
"search-for-donor-name-or-id": "Search for donor (by name or id)",
|
"privacy-loading": "Privacy loading...",
|
||||||
"search-for-permission": "Search for permission",
|
"profile": "Profile",
|
||||||
"search-for-runner-by-name-or-id": "Search for runner (by name or id)",
|
"profile-deleted": "Profile deleted!",
|
||||||
"select-all": "select all",
|
"profile-picture": "Profile Picture",
|
||||||
"select-language": "Select language",
|
"profile-updated": "Profile updated!",
|
||||||
"selfservice-registration": "Selfservice registration",
|
"read-license": "Read License",
|
||||||
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
|
"receipt-needed": "Receipt needed",
|
||||||
"set-the-user-active-inactive": "set the user active/ inactive",
|
"repo_link": "Link",
|
||||||
"settings": "Settings",
|
"request-a-new-reset-mail": "Request a new reset mail",
|
||||||
"settings-for-your-profile": "Settings for your profile",
|
"reset-my-password": "Reset my password",
|
||||||
"something-about-the-group": "Something about the group...",
|
"reset-password": "Reset your password",
|
||||||
"stats-are-being-loaded": "stats are being loaded...",
|
"runner": "Runner",
|
||||||
"status": "Status",
|
"runner-added": "Runner added",
|
||||||
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
|
"runner-import": "Runner Import",
|
||||||
"successful-password-reset": "Successful password reset!",
|
"runner-is-being-added": "Runner is being added...",
|
||||||
"team": "Team",
|
"runner-updated": "Runner updated!",
|
||||||
"team-detail-is-being-loaded": "team detail is being loaded...",
|
"runnercards": "Runnercards",
|
||||||
"team-name": "Team name",
|
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
|
||||||
"team-name-is-required": "team name is required",
|
"runners": "Runners",
|
||||||
"teams": "Teams",
|
"runners-are-being-imported": "Runners are being imported...",
|
||||||
"teams-are-being-loaded": "teams are being loaded...",
|
"runners-are-being-loaded": "runners are being loaded...",
|
||||||
"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...",
|
"save": "Save",
|
||||||
"the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m",
|
"save-changes": "Save Changes",
|
||||||
"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!",
|
"scan-added": "Scan added",
|
||||||
"there-are-no-cards-yet": "There are no cards yet.",
|
"scan-is-being-updated": "Scan is being updated",
|
||||||
"there-are-no-contacts-added-yet": "There are no contacts added yet.",
|
"scan-with-fixed-distance": "Scan with fixed distance",
|
||||||
"there-are-no-donations-yet": "There are no donations yet",
|
"scans": "Scans",
|
||||||
"there-are-no-donors-yet": "There are no donors yet",
|
"scans-are-being-loaded": "Scans are being loaded",
|
||||||
"there-are-no-groups-yet": "There are no groups yet",
|
"scanstation": "Scanstation",
|
||||||
"there-are-no-organizations-added-yet": "There are no organizations added yet.",
|
"scanstation-added": "Scanstation added",
|
||||||
"there-are-no-runners-added-yet": "There are no runners added yet.",
|
"scanstation-is-being-added": "Adding scanstation...",
|
||||||
"there-are-no-scans-yet": "There are no scans yet",
|
"scanstations": "Scanstations",
|
||||||
"there-are-no-teams-added-yet": "There are no teams added yet.",
|
"scanstations-are-being-loaded": "Loading scanstations...",
|
||||||
"there-are-no-users-added-yet": "There are no users added yet.",
|
"search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)",
|
||||||
"this-card-is": "This card is",
|
"search-for-an-organization-or-team-by-name-or-id": "Search for an organization or team (by name or id)",
|
||||||
"this-might-take-a-moment": "This might take a moment 👀",
|
"search-for-donor-name-or-id": "Search for donor (by name or id)",
|
||||||
"this-scanstation-is": "This scanstation is",
|
"search-for-permission": "Search for permission",
|
||||||
"token": "Token",
|
"search-for-runner-by-name-or-id": "Search for runner (by name or id)",
|
||||||
"total-distance": "total distance",
|
"select-all": "select all",
|
||||||
"total-donation-amount": "total donation amount",
|
"select-language": "Select language",
|
||||||
"total-donations": "total donations",
|
"selfservice-registration": "Selfservice registration",
|
||||||
"total-scans": "total scans",
|
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
|
||||||
"track": "Track",
|
"set-the-user-active-inactive": "set the user active/ inactive",
|
||||||
"track-added": "Track added",
|
"settings": "Settings",
|
||||||
"track-data-is-being-loaded": "Track data is being loaded",
|
"settings-for-your-profile": "Settings for your profile",
|
||||||
"track-is-being-added": "Track is being added...",
|
"something-about-the-group": "Something about the group...",
|
||||||
"track-length-in-m": "Track Length in m",
|
"sponsoring-quittungs-liste_herunterladen": "Download donor receipt list",
|
||||||
"track-length-must-be-greater-than-0": "Track length must be greater than 0",
|
"sponsorings": "Sponsorings",
|
||||||
"track-name": "Track name",
|
"stats-are-being-loaded": "stats are being loaded...",
|
||||||
"track-name-must-not-be-empty": "Track name must not be empty",
|
"statsclient-deleted": "Deleted statsclient",
|
||||||
"tracks": "Tracks",
|
"statsclient-is-being-added": "Statsclient is being added...",
|
||||||
"update-card": "Update Card",
|
"statsclients": "Statsclients (aka Beamershow)",
|
||||||
"update-password": "Update password",
|
"statsclients-are-being-loaded": "Loading statsclients",
|
||||||
"updated-contact": "Updated contact!",
|
"status": "Status",
|
||||||
"updated-donor": "updated donor",
|
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
|
||||||
"updated-organization": "updated organization",
|
"successful-password-reset": "Successful password reset!",
|
||||||
"updated-scan": "updated scan",
|
"team": "Team",
|
||||||
"updateing-group": "updateing group...",
|
"team-added": "Team added",
|
||||||
"updating-card": "Updating card",
|
"team-deleted": "Team deleted",
|
||||||
"updating-organization": "updating organization",
|
"team-detail-is-being-loaded": "team detail is being loaded...",
|
||||||
"updating-permissions": "updating permissions...",
|
"team-is-being-added": "Team is being added...",
|
||||||
"updating-runner": "Updating runner...",
|
"team-name": "Team name",
|
||||||
"updating-user": "updating user...",
|
"team-name-is-required": "team name is required",
|
||||||
"updating-your-profile": "Updating your profile...",
|
"teams": "Teams",
|
||||||
"user-added": "User added",
|
"teams-are-being-loaded": "teams are being loaded...",
|
||||||
"user-groups": "User Groups",
|
"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...",
|
||||||
"user-is-being-added": "User is being added...",
|
"the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m",
|
||||||
"user-updated": "User updated",
|
"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!",
|
||||||
"username": "Username",
|
"the-statsclient-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again": "The statsclient api token will only get displayed once - you won't be able to change or view it again!",
|
||||||
"users": "Users",
|
"there-are-no-cards-yet": "There are no cards yet.",
|
||||||
"valid": "Valid",
|
"there-are-no-contacts-added-yet": "There are no contacts added yet.",
|
||||||
"valid-city-is-required": "Valid city is required",
|
"there-are-no-donations-yet": "There are no donations yet",
|
||||||
"valid-email-is-required": "valid email is required",
|
"there-are-no-donors-yet": "There are no donors yet",
|
||||||
"valid-international-phone-number-is-required": "valid international phone number is required...",
|
"there-are-no-groups-yet": "There are no groups yet",
|
||||||
"valid-zipcode-postal-code-is-required": "Valid zipcode/ postal code is required",
|
"there-are-no-organizations-added-yet": "There are no organizations added yet.",
|
||||||
"verfuegbare": "availdable",
|
"there-are-no-runners-added-yet": "There are no runners added yet.",
|
||||||
"welcome_wavinghand": "Welcome 👋",
|
"there-are-no-scans-yet": "There are no scans yet",
|
||||||
"yes-i-copied-the-token": "Yes, I copied the token",
|
"there-are-no-teams-added-yet": "There are no teams added yet.",
|
||||||
"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!",
|
"there-are-no-users-added-yet": "There are no users added yet.",
|
||||||
"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! 🎉",
|
"this-card-is": "This card is",
|
||||||
"you-can-provide-a-runner-but-you-dont-have-to": "You can provide a runner, but you don't have to.",
|
"this-might-take-a-moment": "This might take a moment 👀",
|
||||||
"you-dont-have-any-scanstations-yet": "You don't have any scanstations yet",
|
"this-scanstation-is": "This scanstation is",
|
||||||
"you-have-to-provide-an-organization": "You have to provide an organization",
|
"token": "Token",
|
||||||
"you-have-to-save-your-changes-to-generate-a-link": "You have to save your changes to generate a link.",
|
"total-distance": "total distance",
|
||||||
"you-must-create-at-least-one-card-or-cancel": "You must create at least one card (or cancel).",
|
"total-donation-amount": "total donation amount",
|
||||||
"zip-postal-code": "ZIP/ postal code"
|
"total-donations": "total donations",
|
||||||
}
|
"total-paid-amount": "Total paid amount",
|
||||||
|
"total-scans": "total scans",
|
||||||
|
"total_donation_amount_in_eur": "Total donation amount in €",
|
||||||
|
"track": "Track",
|
||||||
|
"track-added": "Track added",
|
||||||
|
"track-data-is-being-loaded": "Track data is being loaded",
|
||||||
|
"track-is-being-added": "Track is being added...",
|
||||||
|
"track-is-being-updated": "Track is being updated...",
|
||||||
|
"track-length-in-m": "Track Length in m",
|
||||||
|
"track-length-must-be-greater-than-0": "Track length must be greater than 0",
|
||||||
|
"track-name": "Track name",
|
||||||
|
"track-name-must-not-be-empty": "Track name must not be empty",
|
||||||
|
"track-was-updated": "Track was updated!",
|
||||||
|
"tracks": "Tracks",
|
||||||
|
"unpaid": "Unpaid",
|
||||||
|
"update-card": "Update Card",
|
||||||
|
"update-password": "Update password",
|
||||||
|
"updated-contact": "Updated contact!",
|
||||||
|
"updated-donor": "updated donor",
|
||||||
|
"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-scanclients-yet": "You don't have any statsclients yet",
|
||||||
|
"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",
|
||||||
|
"delete-cards": "Delete cards",
|
||||||
|
"cards-deleted": "Cards deleted"
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
@@ -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}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
+10
-9
@@ -1,14 +1,15 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
purge: {
|
mode: 'jit',
|
||||||
content: [ './src/**/*.svelte' ]
|
content: [ './src/**/*.svelte' ],
|
||||||
},
|
|
||||||
// darkMode: 'media',
|
|
||||||
variants: {},
|
|
||||||
plugins: [],
|
|
||||||
theme: {
|
theme: {
|
||||||
container: {
|
extend: {
|
||||||
center: true,
|
colors: {
|
||||||
padding: '1.5rem'
|
reepolee: {
|
||||||
|
500: '#b40000',
|
||||||
|
600: '#9c0000',
|
||||||
|
700: '#750000'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Loaded 100 of 104 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user