Compare commits
397
Commits
0.8.6
..
d4ab76ea1b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
2ca63fd1f6 | ||
|
|
a5d25e7d92 | ||
|
|
4167819e7a | ||
|
|
5bd3a463f0 | ||
|
|
79c447b4c6 | ||
|
|
540304f947 | ||
|
|
75d8f7331b | ||
|
|
b2509e9e53 | ||
|
|
7862f44653 | ||
|
|
962dd0c1bb | ||
|
|
5d5f7c7f5c | ||
|
|
6aaf838451 | ||
|
|
ad3bd312e9 | ||
|
|
5fa9939696 | ||
|
|
4956bb0e9c | ||
|
|
c074c12be7 | ||
|
|
ddbc293e9c | ||
|
|
a3921b45c7 | ||
|
|
38e1c8c5a1 | ||
|
|
c2d29ff233 | ||
|
|
2316baa898 | ||
|
|
f185d559c0 | ||
|
|
73d95bc004 | ||
|
|
fcd55f89d7 | ||
|
|
f9fe793573 | ||
|
|
bc36411993 | ||
|
|
48506236bf | ||
|
|
ded9b589fe | ||
|
|
67c3732fad | ||
|
|
2932f4591e | ||
|
|
df53c07450 | ||
|
|
40899e9d80 | ||
|
|
f794af0950 | ||
|
|
1665a1a093 | ||
|
|
4a36fb6d95 | ||
|
|
acf78a8822 | ||
|
|
f5c1ec9939 | ||
|
|
4b3d38b05b | ||
|
|
23e0b53107 | ||
|
|
c907486c4d | ||
|
|
6b5945add8 | ||
|
|
55693de934 | ||
|
|
d467475b6d | ||
|
|
44bc14820f | ||
|
|
ec447e2e36 | ||
|
|
0af2647965 | ||
|
|
08442154f4 | ||
|
|
9f7d2234fb | ||
|
|
ddd82a71a7 | ||
|
|
014ba3bf67 | ||
|
|
c87321f804 | ||
|
|
8b451b3c67 | ||
|
|
0cfc87fbe6 | ||
|
|
ae9673070c | ||
|
|
008027db0e | ||
|
|
aec5e3473e | ||
|
|
95c8fde72f | ||
|
|
0f32968fae | ||
|
|
ae79e9fea1 | ||
|
|
1a52aaf8d1 | ||
|
|
d6c315ab8e | ||
|
|
983ce56048 | ||
|
|
de2fe0e9f1 | ||
|
|
fac059f02c | ||
|
|
0313f8cc49 | ||
|
|
7ad6b73574 | ||
|
|
3cd0468b19 | ||
|
|
f46ccb610e | ||
|
|
8a32569a3b | ||
|
|
535b23ae91 | ||
|
|
4715978f81 | ||
|
|
a516aa7775 | ||
|
|
77e9c205f9 | ||
|
|
e852305400 | ||
|
|
c6a15264b3 | ||
|
|
2d0beaaaad | ||
|
|
5c5ef95d2b | ||
|
|
9aa8e7edff |
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,
|
||||||
}
|
}
|
||||||
+481
-1
@@ -2,8 +2,488 @@
|
|||||||
|
|
||||||
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)
|
||||||
|
|
||||||
|
> 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)
|
||||||
|
- 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)
|
||||||
|
- You can now copy the selfservice links to your clipboard [`fcd55f8`](https://git.odit.services/lfk/frontend/commit/fcd55f89d72e6ceb9bb2bdd194cc3420145d6d0d)
|
||||||
|
- Formatting [`f185d55`](https://git.odit.services/lfk/frontend/commit/f185d559c0d6476f2f2b9ea74aaad3297411801d)
|
||||||
|
- Copy now 100% worX [`a3921b4`](https://git.odit.services/lfk/frontend/commit/a3921b45c70b410293db593a75d2fdd34c131733)
|
||||||
|
- Fixed changes in wrong file [`73d95bc`](https://git.odit.services/lfk/frontend/commit/73d95bc0042f8f586ba2f2345342e25da1d280c2)
|
||||||
|
- Added check if key exists [`c2d29ff`](https://git.odit.services/lfk/frontend/commit/c2d29ff233f6b3e9dd2555b7e0b845592da2ba35)
|
||||||
|
- Added check if key exists [`2316baa`](https://git.odit.services/lfk/frontend/commit/2316baa8984832382be9f3b4549ca62cf9ccb5a3)
|
||||||
|
- Added translations [`ddbc293`](https://git.odit.services/lfk/frontend/commit/ddbc293e9ca0525910bf3d995de970ee2c35c56a)
|
||||||
|
- new license file version [CI SKIP] [`ded9b58`](https://git.odit.services/lfk/frontend/commit/ded9b589fe087915176c5b54f3c55e412541bc8f)
|
||||||
|
- Merge pull request 'first merge to main 🚀' (#71) from dev into main [`9aa8e7e`](https://git.odit.services/lfk/frontend/commit/9aa8e7edffa7e51b00a5ab7a8f16828b7a469181)
|
||||||
|
|
||||||
|
#### [0.9.0](https://git.odit.services/lfk/frontend/compare/0.8.7...0.9.0)
|
||||||
|
|
||||||
|
> 26 March 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.9.0 [`67c3732`](https://git.odit.services/lfk/frontend/commit/67c3732fad5a7c64ae11dcbebaaa095e1a2b387c)
|
||||||
|
- Merge pull request 'Runner cards feature/94-runnercard_mgnt' (#111) from feature/94-runnercard_mgnt into dev [`2932f45`](https://git.odit.services/lfk/frontend/commit/2932f4591e62187a4903511051d110e9679c0993)
|
||||||
|
- Sorted translations 🌍 [`1665a1a`](https://git.odit.services/lfk/frontend/commit/1665a1a093862a13be78ec65dcdf64eb7d855593)
|
||||||
|
- Added translations [`6b5945a`](https://git.odit.services/lfk/frontend/commit/6b5945add86a77630c500872545bb91724b2047f)
|
||||||
|
- Sorted translations 🌍 [`d6c315a`](https://git.odit.services/lfk/frontend/commit/d6c315ab8e020bc65b967e2c3f4cd921392d66d5)
|
||||||
|
- Sorted translations [`de2fe0e`](https://git.odit.services/lfk/frontend/commit/de2fe0e9f171efb3deeea8cfe638f60e3ca90423)
|
||||||
|
- Added basic cards page [`5c5ef95`](https://git.odit.services/lfk/frontend/commit/5c5ef95d2be65c0e951dcd472113c8ce0593c9e0)
|
||||||
|
- Moved contract generation to it's own component [`0cfc87f`](https://git.odit.services/lfk/frontend/commit/0cfc87fbe6adfacab5c2fab732866aead3231fbf)
|
||||||
|
- Teams now use the new sponsoring contracts module [`014ba3b`](https://git.odit.services/lfk/frontend/commit/014ba3bf6718ff28f35c67c8f732b53aae50723c)
|
||||||
|
- Basic card generation worX 🎉🎉 [`d467475`](https://git.odit.services/lfk/frontend/commit/d467475b6d61d50bec3a043ea8792533e8593df6)
|
||||||
|
- Orgs now use the new sponsoring contracts module [`8b451b3`](https://git.odit.services/lfk/frontend/commit/8b451b3c6794e7df09898a687533ce8fadd56192)
|
||||||
|
- Added runnercard detail/edit modal [`0313f8c`](https://git.odit.services/lfk/frontend/commit/0313f8cc495088df1237d00e6b9ed1a94f019644)
|
||||||
|
- Implemented Add card modal [`535b23a`](https://git.odit.services/lfk/frontend/commit/535b23ae917de154e08962f5d486c50d6e091fe0)
|
||||||
|
- Added bulk card creation modal [`8a32569`](https://git.odit.services/lfk/frontend/commit/8a32569a3be1ad26ba163f4e2b67a368cfeeb422)
|
||||||
|
- Added basic card overview [`c6a1526`](https://git.odit.services/lfk/frontend/commit/c6a15264b3d13d516f3d97ea4b891ed1c328cead)
|
||||||
|
- Fixed org generation not hiding the generation toast [`c87321f`](https://git.odit.services/lfk/frontend/commit/c87321f804858f84fcccd85a15b9c3fb003c18be)
|
||||||
|
- Working runner runnercard generation [`c907486`](https://git.odit.services/lfk/frontend/commit/c907486c4d1c64114124deb3cd0d0cf11d38a6b1)
|
||||||
|
- Implemented bulk creation [`7ad6b73`](https://git.odit.services/lfk/frontend/commit/7ad6b73574174f24f2d6f23b3caf4823881a85e7)
|
||||||
|
- Now w/ working dialog🎉🎉🎉 [`ae96730`](https://git.odit.services/lfk/frontend/commit/ae9673070c3959ff6190a37123f3fc609b182c5a)
|
||||||
|
- Now w/working editing [`fac059f`](https://git.odit.services/lfk/frontend/commit/fac059f02cae84261443ee95448ec8db06dd755a)
|
||||||
|
- Added runnercard generation for teams [`23e0b53`](https://git.odit.services/lfk/frontend/commit/23e0b53107623c505d07a99a51ce836c9324acce)
|
||||||
|
- Added bulk creation modal to cards view [`f46ccb6`](https://git.odit.services/lfk/frontend/commit/f46ccb610e01654a4ee5e47d78ab500045dd494b)
|
||||||
|
- Added a new runenrcard logo [`acf78a8`](https://git.odit.services/lfk/frontend/commit/acf78a88221d0988f6501ae341e028a4113b578d)
|
||||||
|
- Moved modal import to overview for simplification [`1a52aaf`](https://git.odit.services/lfk/frontend/commit/1a52aaf8d1ad19b03d355aec0e1c48182db024f9)
|
||||||
|
- Added CardsEmptyState + Emtystate graphic [`2d0beaa`](https://git.odit.services/lfk/frontend/commit/2d0beaaaad4efefd036bbef09f10c8c22bdb2760)
|
||||||
|
- Added message for missing runner/blanco card) [`4715978`](https://git.odit.services/lfk/frontend/commit/4715978f810bbb283876f06d147b1ec86d373786)
|
||||||
|
- Fixed counting bug [`f5c1ec9`](https://git.odit.services/lfk/frontend/commit/f5c1ec9939d856804c9ec3ead4b3ed869fc2ea63)
|
||||||
|
- Added card generation/printing from detail [`4a36fb6`](https://git.odit.services/lfk/frontend/commit/4a36fb6d952d9fe4d5edbe1ed0779c7fbcd50ef0)
|
||||||
|
- Formatting [`a516aa7`](https://git.odit.services/lfk/frontend/commit/a516aa7775faa2244862bb2e3c4de623c6405e5b)
|
||||||
|
- Moved the pdf generation related componenets to their own folder [`ddd82a7`](https://git.odit.services/lfk/frontend/commit/ddd82a71a7b67ead892626addfd56ba4cc632750)
|
||||||
|
- Now routing the cards page [`e852305`](https://git.odit.services/lfk/frontend/commit/e852305400a139f8169350077c30012aed556828)
|
||||||
|
- Fuggin snowpack bs [`44bc148`](https://git.odit.services/lfk/frontend/commit/44bc14820fed26d5e0d8b12ecd6b46ca0608ae7b)
|
||||||
|
- Formatting [`9f7d223`](https://git.odit.services/lfk/frontend/commit/9f7d2234fb9603a7391ec9a64253724c2c25c333)
|
||||||
|
- Now with working org runenrcard generation [`4b3d38b`](https://git.odit.services/lfk/frontend/commit/4b3d38b05b3ed74fc3c0d77e00fa2ed245e6325c)
|
||||||
|
- Now importing runner overview [`77e9c20`](https://git.odit.services/lfk/frontend/commit/77e9c205f94cf56c2e3584444899adb1e8bdf3c6)
|
||||||
|
- CardsOverview - move to 'enabled' language key [`df53c07`](https://git.odit.services/lfk/frontend/commit/df53c0745035a220d4c07fdce1b5a5e4d763411d)
|
||||||
|
- ✒ typo - "Geb" -> "Gebe" [`f794af0`](https://git.odit.services/lfk/frontend/commit/f794af0950de59a7a7b468c30abdcb5c145f65fb)
|
||||||
|
- Bumped lfk client lib version [`3cd0468`](https://git.odit.services/lfk/frontend/commit/3cd0468b1921824b131178cb02677540b079f9b0)
|
||||||
|
- drop console log - CardDetailModal [`40899e9`](https://git.odit.services/lfk/frontend/commit/40899e9d80ba07a3fbbcac72782db53d98dc318e)
|
||||||
|
- Removed debug info [`55693de`](https://git.odit.services/lfk/frontend/commit/55693de93420c2d76af296fcacc6bcad644a3cbf)
|
||||||
|
|
||||||
|
#### [0.8.7](https://git.odit.services/lfk/frontend/compare/0.8.6...0.8.7)
|
||||||
|
|
||||||
|
> 25 March 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.8.7 [`0af2647`](https://git.odit.services/lfk/frontend/commit/0af26479656393b0baea88f6f83c778740a67e62)
|
||||||
|
- Fixed listen on wrong permission🐞 [`0844215`](https://git.odit.services/lfk/frontend/commit/08442154f4bf94fc1101808b4585dc1f95afe8b2)
|
||||||
|
|
||||||
#### [0.8.6](https://git.odit.services/lfk/frontend/compare/0.8.5...0.8.6)
|
#### [0.8.6](https://git.odit.services/lfk/frontend/compare/0.8.5...0.8.6)
|
||||||
|
|
||||||
|
> 25 March 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE v0.8.6 [`c3c95bf`](https://git.odit.services/lfk/frontend/commit/c3c95bf2916618efe6764a33d9a42d35764d15be)
|
||||||
- Merge pull request 'Know Production Bugs 🐞' (#109) from bugfix/107-prod_issues into dev [`d2050b5`](https://git.odit.services/lfk/frontend/commit/d2050b5948890a6077cbb41d82d1a6a1d1106652)
|
- Merge pull request 'Know Production Bugs 🐞' (#109) from bugfix/107-prod_issues into dev [`d2050b5`](https://git.odit.services/lfk/frontend/commit/d2050b5948890a6077cbb41d82d1a6a1d1106652)
|
||||||
- Errors now toast errors❌ [`17e0805`](https://git.odit.services/lfk/frontend/commit/17e0805fe64f6d181f55b81afa502ee6443ebabe)
|
- Errors now toast errors❌ [`17e0805`](https://git.odit.services/lfk/frontend/commit/17e0805fe64f6d181f55b81afa502ee6443ebabe)
|
||||||
- Sorted translations 👀 [`82b1811`](https://git.odit.services/lfk/frontend/commit/82b1811971b974b686e7618b8a381e1589c168f6)
|
- Sorted translations 👀 [`82b1811`](https://git.odit.services/lfk/frontend/commit/82b1811971b974b686e7618b8a381e1589c168f6)
|
||||||
@@ -849,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.8.6-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.8.6",
|
"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.6.4",
|
"@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.6.4","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 }
|
|
||||||
};
|
|
||||||
+20
-6
@@ -1,7 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import "./TailwindStyles.svelte";
|
|
||||||
import "toastify-js/src/toastify.css";
|
import "toastify-js/src/toastify.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);
|
||||||
@@ -53,7 +51,6 @@
|
|||||||
import { OpenAPI } from "@odit/lfk-client-js";
|
import { OpenAPI } from "@odit/lfk-client-js";
|
||||||
import UserDetail from "./components/users/UserDetail.svelte";
|
import UserDetail from "./components/users/UserDetail.svelte";
|
||||||
OpenAPI.BASE = config.baseurl;
|
OpenAPI.BASE = config.baseurl;
|
||||||
import { register as registerSW } from "./swmodule";
|
|
||||||
import TeamDetail from "./components/teams/TeamDetail.svelte";
|
import TeamDetail from "./components/teams/TeamDetail.svelte";
|
||||||
import UserPermissions from "./components/users/UserPermissions.svelte";
|
import UserPermissions from "./components/users/UserPermissions.svelte";
|
||||||
import GroupPermissions from "./components/groups/GroupPermissions.svelte";
|
import GroupPermissions from "./components/groups/GroupPermissions.svelte";
|
||||||
@@ -69,13 +66,14 @@
|
|||||||
import Donations from "./components/donations/Donations.svelte";
|
import Donations from "./components/donations/Donations.svelte";
|
||||||
import DonationDetail from "./components/donations/DonationDetail.svelte";
|
import DonationDetail from "./components/donations/DonationDetail.svelte";
|
||||||
import GroupDetail from "./components/groups/GroupDetail.svelte";
|
import GroupDetail from "./components/groups/GroupDetail.svelte";
|
||||||
import ScanStationsOverview from "./components/scanstations/ScanStationsOverview.svelte";
|
|
||||||
import ScanStations from "./components/scanstations/ScanStations.svelte";
|
import ScanStations from "./components/scanstations/ScanStations.svelte";
|
||||||
import ScanStationDetail from "./components/scanstations/ScanStationDetail.svelte";
|
import ScanStationDetail from "./components/scanstations/ScanStationDetail.svelte";
|
||||||
import Scans from "./components/scans/Scans.svelte";
|
import Scans from "./components/scans/Scans.svelte";
|
||||||
import ScanDetail from "./components/scans/ScanDetail.svelte";
|
import ScanDetail from "./components/scans/ScanDetail.svelte";
|
||||||
|
import Cards from "./components/cards/Cards.svelte";
|
||||||
|
import StatsClients from "./components/statsclients/StatsClients.svelte";
|
||||||
|
import StatsClientDetail from "./components/statsclients/StatsClientDetail.svelte";
|
||||||
store.init();
|
store.init();
|
||||||
registerSW();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Route>
|
<Route>
|
||||||
@@ -185,6 +183,14 @@ import ScanDetail from "./components/scans/ScanDetail.svelte";
|
|||||||
<DonationDetail {params} />
|
<DonationDetail {params} />
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/cards/*">
|
||||||
|
<Route path="/">
|
||||||
|
<Cards />
|
||||||
|
</Route>
|
||||||
|
<!-- <Route path="/:scanid" let:params>
|
||||||
|
<ScanDetail {params} />
|
||||||
|
</Route> -->
|
||||||
|
</Route>
|
||||||
<Route path="/scans/*">
|
<Route path="/scans/*">
|
||||||
<Route path="/">
|
<Route path="/">
|
||||||
<Scans />
|
<Scans />
|
||||||
@@ -201,6 +207,14 @@ import ScanDetail from "./components/scans/ScanDetail.svelte";
|
|||||||
<ScanStationDetail {params} />
|
<ScanStationDetail {params} />
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/statsclients/*">
|
||||||
|
<Route path="/">
|
||||||
|
<StatsClients />
|
||||||
|
</Route>
|
||||||
|
<Route path="/:clientid" let:params>
|
||||||
|
<StatsClientDetail {params} />
|
||||||
|
</Route>
|
||||||
|
</Route>
|
||||||
<Route path="/about">
|
<Route path="/about">
|
||||||
<About />
|
<About />
|
||||||
</Route>
|
</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>
|
||||||
@@ -0,0 +1,240 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
|
||||||
|
import { RunnerCardService } from "@odit/lfk-client-js";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
export let bulk_modal_open;
|
||||||
|
export let current_cards;
|
||||||
|
function focus(el) {
|
||||||
|
el.focus();
|
||||||
|
}
|
||||||
|
$: card_count = 0;
|
||||||
|
$: is_card_count_valid = card_count > 0;
|
||||||
|
$: processed_last_submit = true;
|
||||||
|
$: createbtnenabled = is_card_count_valid;
|
||||||
|
(() => {
|
||||||
|
document.onkeydown = (e) => {
|
||||||
|
e = e || window.event;
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
bulk_modal_open = false;
|
||||||
|
}
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
if (createbtnenabled === true) {
|
||||||
|
createbtnenabled = false;
|
||||||
|
submit_with_print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
function submit_without_print() {
|
||||||
|
if (processed_last_submit === true) {
|
||||||
|
processed_last_submit = false;
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("creating-blanco-cards"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
RunnerCardService.runnerCardControllerPostBlancoBulk(card_count, false)
|
||||||
|
.then((result) => {
|
||||||
|
bulk_modal_open = false;
|
||||||
|
//
|
||||||
|
Toastify({
|
||||||
|
text: $_("created-blanco-cards"),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
processed_last_submit = true;
|
||||||
|
//
|
||||||
|
toast.hideToast();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
{#if bulk_modal_open}
|
||||||
|
<div
|
||||||
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
|
|
||||||
|
use:clickOutside
|
||||||
|
on:click_outside={() => {
|
||||||
|
bulk_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-2xl 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- 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">
|
||||||
|
{$_('create-bulk-blanco-cards')}
|
||||||
|
</h3>
|
||||||
|
<div class="mt-2 mb-6">
|
||||||
|
<p class="text-sm text-gray-500">
|
||||||
|
{$_('just-enter-how-many-you-want-and-the-system-will-create-them')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-6 gap-6">
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="amount"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('amount')}</label>
|
||||||
|
<div class="mt-1 flex rounded-md shadow-sm">
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
class:border-red-500={!is_card_count_valid}
|
||||||
|
class:focus:border-red-500={!is_card_count_valid}
|
||||||
|
class:focus:ring-red-500={!is_card_count_valid}
|
||||||
|
bind:value={card_count}
|
||||||
|
type="number"
|
||||||
|
step="1"
|
||||||
|
name="amount"
|
||||||
|
class="focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 p-2"
|
||||||
|
placeholder="400" />
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-3 rounded-r-md border border-gray-300 bg-gray-50 text-gray-500 text-sm">{$_('cards')}</span>
|
||||||
|
</div>
|
||||||
|
{#if !is_card_count_valid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('you-must-create-at-least-one-card-or-cancel')}
|
||||||
|
</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_with_print}
|
||||||
|
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-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
|
||||||
|
on:click={() => {
|
||||||
|
bulk_modal_open = false;
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
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')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
|
||||||
|
import {
|
||||||
|
RunnerCardService,
|
||||||
|
RunnerService,
|
||||||
|
ScanService,
|
||||||
|
} from "@odit/lfk-client-js";
|
||||||
|
import Select from "svelte-select";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
export let modal_open;
|
||||||
|
export let current_cards;
|
||||||
|
|
||||||
|
const getRunnerLabel = (option) => {
|
||||||
|
if (option.middlename) {
|
||||||
|
return option.firstname + " " + option.middlename + " " + option.lastname;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
el.focus();
|
||||||
|
}
|
||||||
|
$: runner = 0;
|
||||||
|
$: enabled = true;
|
||||||
|
$: processed_last_submit = true;
|
||||||
|
|
||||||
|
let loading = true;
|
||||||
|
let runners = [];
|
||||||
|
RunnerService.runnerControllerGetAll().then((val) => {
|
||||||
|
runners = val.map((r) => {
|
||||||
|
return { label: getRunnerLabel(r), value: r };
|
||||||
|
});
|
||||||
|
loading = false;
|
||||||
|
});
|
||||||
|
$: createbtnenabled = 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: $_("adding-card"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
let postdata = {
|
||||||
|
runner,
|
||||||
|
enabled,
|
||||||
|
};
|
||||||
|
RunnerCardService.runnerCardControllerPost(postdata)
|
||||||
|
.then((result) => {
|
||||||
|
runner = 0;
|
||||||
|
modal_open = false;
|
||||||
|
//
|
||||||
|
Toastify({
|
||||||
|
text: $_("card-added"),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
current_cards.push(result);
|
||||||
|
current_cards = current_cards;
|
||||||
|
})
|
||||||
|
.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
|
||||||
|
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">
|
||||||
|
{$_("create-a-new-card")}
|
||||||
|
</h3>
|
||||||
|
<div class="mt-2 mb-6">
|
||||||
|
<p class="text-sm text-gray-500">
|
||||||
|
{$_("you-can-provide-a-runner-but-you-dont-have-to")}
|
||||||
|
{$_(
|
||||||
|
"if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-6 gap-6">
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="donor"
|
||||||
|
class="block text-sm font-medium text-gray-700"
|
||||||
|
>{$_("runner")}</label
|
||||||
|
>
|
||||||
|
<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"
|
||||||
|
itemFilter={(label, filterText, option) =>
|
||||||
|
filterRunners(label, filterText, option)}
|
||||||
|
items={runners}
|
||||||
|
bind:loading
|
||||||
|
showChevron={!loading}
|
||||||
|
placeholder={$_("search-for-runner-by-name-or-id")}
|
||||||
|
noOptionsMessage={$_("no-runners-found")}
|
||||||
|
on:select={(selectedValue) =>
|
||||||
|
(runner = selectedValue.detail.value.id)}
|
||||||
|
on:clear={() => (runner = null)}
|
||||||
|
/>
|
||||||
|
</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,199 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
|
||||||
|
import { RunnerCardService, RunnerService } from "@odit/lfk-client-js";
|
||||||
|
import Select from "svelte-select";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
export let edit_modal_open;
|
||||||
|
export let current_cards;
|
||||||
|
export let runner = {};
|
||||||
|
export let editable = {};
|
||||||
|
export let original_data = {};
|
||||||
|
const getRunnerLabel = (option) =>
|
||||||
|
option.firstname + " " + (option.middlename || "") + " " + 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) {
|
||||||
|
el.focus();
|
||||||
|
}
|
||||||
|
$: runners = [];
|
||||||
|
$: enabled = true;
|
||||||
|
$: processed_last_submit = true;
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
function dataUpdated() {
|
||||||
|
dispatch('dataUpdated',);
|
||||||
|
}
|
||||||
|
RunnerService.runnerControllerGetAll().then((val) => {
|
||||||
|
runners = val.map((r) => {
|
||||||
|
return { label: getRunnerLabel(r), value: r };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$: createbtnenabled = !(
|
||||||
|
JSON.stringify(editable) === JSON.stringify(original_data)
|
||||||
|
);
|
||||||
|
(() => {
|
||||||
|
document.onkeydown = (e) => {
|
||||||
|
e = e || window.event;
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
edit_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-card"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
RunnerCardService.runnerCardControllerPut(original_data.id, editable)
|
||||||
|
.then((result) => {
|
||||||
|
let id = original_data.id;
|
||||||
|
runner = {};
|
||||||
|
editable = {};
|
||||||
|
original_data = {};
|
||||||
|
edit_modal_open = false;
|
||||||
|
//
|
||||||
|
Toastify({
|
||||||
|
text: $_("card-updated"),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
current_cards[current_cards.findIndex((c) => c.id === id)] = result;
|
||||||
|
current_cards = current_cards;
|
||||||
|
dataUpdated();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
processed_last_submit = true;
|
||||||
|
//
|
||||||
|
toast.hideToast();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if edit_modal_open}
|
||||||
|
<div
|
||||||
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
|
|
||||||
|
use:clickOutside
|
||||||
|
on:click_outside={() => {
|
||||||
|
edit_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">
|
||||||
|
{$_('edit-a-card')}
|
||||||
|
</h3>
|
||||||
|
<div class="mt-2 mb-6">
|
||||||
|
<p class="text-sm text-gray-500">
|
||||||
|
{$_('you-can-provide-a-runner-but-you-dont-have-to')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-6 gap-6">
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="runner"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('runner')}</label>
|
||||||
|
<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"
|
||||||
|
itemFilter={(label, filterText, option) => filterRunners(label, filterText, option)}
|
||||||
|
items={runners}
|
||||||
|
showChevron={true}
|
||||||
|
placeholder={$_('search-for-runner-by-name-or-id')}
|
||||||
|
noOptionsMessage={$_('no-runners-found')}
|
||||||
|
bind:selectedValue={runner}
|
||||||
|
on:select={(selectedValue) => (editable.runner = selectedValue.detail.value.id)}
|
||||||
|
on:clear={() => (editable.runner = null)} />
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<p class="text-gray-500">
|
||||||
|
<input
|
||||||
|
id="enabled"
|
||||||
|
on:change={() => {
|
||||||
|
editable.enabled = !editable.enabled;
|
||||||
|
}}
|
||||||
|
name="enabled"
|
||||||
|
type="checkbox"
|
||||||
|
checked={editable.enabled}
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
|
{$_('this-card-is')}
|
||||||
|
{#if editable.enabled}
|
||||||
|
{$_('enabled')}
|
||||||
|
{:else}{$_('disabled')}{/if}
|
||||||
|
</p>
|
||||||
|
</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={() => {
|
||||||
|
edit_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,40 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import store from "../../store";
|
||||||
|
import AddCardBulkModal from "./AddCardBulkModal.svelte";
|
||||||
|
import AddCardModal from "./AddCardModal.svelte";
|
||||||
|
import CardsOverview from "./CardsOverview.svelte";
|
||||||
|
$: current_cards = [];
|
||||||
|
export let modal_open = false;
|
||||||
|
export let bulk_modal_open = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="container p-5">
|
||||||
|
<span class="mb-1 text-3xl font-extrabold leading-tight">
|
||||||
|
{$_('cards')}
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD: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">
|
||||||
|
{$_('add-card')}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
bulk_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-bulk-cards')}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
<CardsOverview bind:current_cards />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:CREATE')}
|
||||||
|
<AddCardModal bind:current_cards bind:modal_open />
|
||||||
|
<AddCardBulkModal bind:current_cards bind:bulk_modal_open />
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import cards_empty from "./cards.svg";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="text-center items-center justify-center">
|
||||||
|
<p class="mb-16 text-lg text-gray-500">
|
||||||
|
<img class="m-auto" style="height:15rem" src={cards_empty} alt="" />
|
||||||
|
<span class="font-bold">{$_('there-are-no-cards-yet')}</span><br />
|
||||||
|
<span>{$_('add-your-first-card')}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { RunnerCardService } from "@odit/lfk-client-js";
|
||||||
|
import store from "../../store";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import CardsEmptyState from "./CardsEmptyState.svelte";
|
||||||
|
import CardDetailModal from "./CardDetailModal.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 runner = {};
|
||||||
|
export let editable = {};
|
||||||
|
export let original_data = {};
|
||||||
|
export let current_cards = [];
|
||||||
|
const handler = new DataHandler(current_cards, { rowsPerPage: 50 });
|
||||||
|
const rows = handler.getRows();
|
||||||
|
$: active_deletes = [];
|
||||||
|
$: cards_show = generate_cards.length > 0;
|
||||||
|
$: generate_cards = [];
|
||||||
|
const cards_promise = RunnerCardService.runnerCardControllerGetAll().then(
|
||||||
|
(val) => {
|
||||||
|
current_cards = val;
|
||||||
|
handler.setRows(val);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const getRunnerLabel = (option) =>
|
||||||
|
option?.firstname +
|
||||||
|
" " +
|
||||||
|
(option?.middlename || "") +
|
||||||
|
" " +
|
||||||
|
(option?.lastname || "{$_('non-blanko')}");
|
||||||
|
function open_edit_modal(card) {
|
||||||
|
if (card.runner?.id) {
|
||||||
|
runner = Object.assign(
|
||||||
|
{ runner },
|
||||||
|
{ label: getRunnerLabel(card.runner), value: card.runner }
|
||||||
|
);
|
||||||
|
card.runner = card.runner.id;
|
||||||
|
} else {
|
||||||
|
card.runner = null;
|
||||||
|
runner = null;
|
||||||
|
}
|
||||||
|
editable = Object.assign(editable, card);
|
||||||
|
original_data = Object.assign(original_data, card);
|
||||||
|
edit_modal_open = true;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes("CARD:UPDATE")}
|
||||||
|
<CardDetailModal
|
||||||
|
bind:current_cards
|
||||||
|
bind:edit_modal_open
|
||||||
|
bind:runner
|
||||||
|
bind:editable
|
||||||
|
bind:original_data
|
||||||
|
on:dataUpdated={handler.setRows(current_cards)}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes("CARD:GET")}
|
||||||
|
{#await cards_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">{$_("loading-cards")}</p>
|
||||||
|
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
|
||||||
|
</div>
|
||||||
|
{:then}
|
||||||
|
{#if current_cards.length === 0}
|
||||||
|
<CardsEmptyState />
|
||||||
|
{:else}
|
||||||
|
<div class="h-12 mt-1">
|
||||||
|
{#if cards_show}
|
||||||
|
<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 inline-flex"
|
||||||
|
id="options-menu"
|
||||||
|
on:click={async () => {
|
||||||
|
const prom = [];
|
||||||
|
for (const card of generate_cards) {
|
||||||
|
prom.push(
|
||||||
|
RunnerCardService.runnerCardControllerRemove(card.id, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await Promise.all(prom);
|
||||||
|
Toastify({
|
||||||
|
text: $_("cards-deleted"),
|
||||||
|
duration: 3500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
//TODO: Delete cards from table
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{$_("delete-cards")}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="w-5 h-5"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
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"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
<GenerateRunnerCards bind:cards_show bind:generate_cards />
|
||||||
|
</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}
|
||||||
|
{: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}
|
||||||
|
|
||||||
|
<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>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 653.9 247.6"><path d="M272 211l-53 12s-11-2-1-17l4-4 27-14v-2l-6-41-2-16 17-17 4-3 44 41v1l-19 33z" fill="#ffb7b7"/><path d="M253 198l-54 13a6 6 0 01-5-7 16 16 0 012-5 48 48 0 016-9l28-14-4-24-1-12-2-8-2-16 21-19 22 21 22 20-3 5-3 7-17 30-3 6z" fill="#ffb7b7"/><path d="M346 190s-20-1-28-15a24 24 0 01-3-14l-8-17-11-23-30-4-2 1-21 19-7 6-10 9-49 44a37 37 0 01-7 9 50 50 0 01-9 7c-10 5-24 9-44 7L10 248 0 176l89-29 131-86 89 23 41 58z" fill="#ffb7b7"/><path d="M648 0H275a5 5 0 00-5 5v221a5 5 0 005 6h373a5 5 0 006-6V5a5 5 0 00-6-5z" fill="#fff"/><path d="M648 0H275a5 5 0 00-5 5v221a5 5 0 005 6h373a5 5 0 006-6V5a5 5 0 00-6-5zm4 226a4 4 0 01-4 4H275a4 4 0 01-3-4V5a4 4 0 013-3h373a4 4 0 014 3z" fill="#3f3d56"/><path d="M312 30a9 9 0 119-9 9 9 0 01-9 9zm0-17a8 8 0 107 8 8 8 0 00-7-8z" fill="#6c63ff"/><path d="M297 21a8 8 0 016-8 8 8 0 100 16 8 8 0 01-6-8zM349 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM368 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM386 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM415 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM434 130a7 7 0 01-7-7v-20a7 7 0 0113 0v20a7 7 0 01-6 7zM452 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM481 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM499 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM518 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM546 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM565 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7zM583 130a7 7 0 01-7-7v-20a7 7 0 0114 0v20a7 7 0 01-7 7z" fill="#6c63ff"/><path d="M396 208h-99a5 5 0 110-10h99a5 5 0 010 10zM364 188h-35a5 5 0 110-10h35a5 5 0 110 10z" fill="#e6e6e6"/><path fill="#3f3d56" d="M271 46h381v2H271z"/><path opacity=".1" d="M228 203l-1-2 33-15 8-27-12-10 1-1 13 10-8 30-34 15zM196 199l-9 4-17 2a50 50 0 01-9 7l-16-1-26-1 88-74 18 4-29 59z"/><path d="M318 175l-8 1-47 4-29 1-38 18-9 4-70 8 95-81 11 2 20 5 22 5 18 1 24 1 20 1a13 13 0 0112 13c0 7-5 14-21 17z" fill="#ffb7b7"/><path d="M325 170s-7-2-9-9c-2-4-1-9 3-15l1 1c-3 6-4 10-3 14 2 5 9 7 9 7zM197 197l34-16v2l-33 16zM218 135l48-19v2l-41 16 35 6v2l-42-7z" opacity=".1"/></svg>
|
||||||
|
After Width: | Height: | Size: 2.1 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 {
|
||||||
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">
|
||||||
|
|||||||
@@ -1,308 +1,361 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import localForage from "localforage";
|
import localForage from "localforage";
|
||||||
import store from "../../store";
|
import store from "../../store";
|
||||||
import { router } from "tinro";
|
import { router } from "tinro";
|
||||||
import NoComponentLoaded from "../base/NoComponentLoaded.svelte";
|
import NoComponentLoaded from "../base/NoComponentLoaded.svelte";
|
||||||
import { AuthService } from "@odit/lfk-client-js";
|
import { AuthService } from "@odit/lfk-client-js";
|
||||||
$: navOpen = false;
|
$: navOpen = false;
|
||||||
function logout() {
|
function logout() {
|
||||||
localForage.clear();
|
localForage.clear();
|
||||||
location.replace("/");
|
location.replace("/");
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="min-h-screen bg-gray-50">
|
<style>
|
||||||
<nav
|
.collapsed_navigation {
|
||||||
class:-translate-x-full={!navOpen}
|
transform: translateX(-100%);
|
||||||
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 md:translate-x-0 bg-gray-50">
|
@media (min-width: 768px) {
|
||||||
<a href="/" class="flex items-center px-4 py-5">
|
.collapsed_navigation {
|
||||||
<img src="/lfk-logo.png" alt="Logo" class="h-10" />
|
transform: translateX(0px);
|
||||||
<h3 class="text-lg">Lauf für Kaya! Admin</h3>
|
}
|
||||||
</a>
|
}
|
||||||
<nav class="text-sm font-medium text-gray-600" aria-label="Main Navigation">
|
</style>
|
||||||
<a
|
|
||||||
class:bg-gray-100={$router.path === '/'}
|
<section class="min-h-screen bg-gray-50">
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
<div
|
||||||
href="/">
|
class:collapsed_navigation={!navOpen}
|
||||||
<svg
|
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="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
<a href="/" class="flex items-center px-4 py-5">
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<img src="/lfk-logo.png" alt="Logo" class="h-10" />
|
||||||
viewBox="0 0 20 20"
|
<h3 class="text-lg">Lauf für Kaya! Admin</h3>
|
||||||
fill="currentColor">
|
</a>
|
||||||
<path
|
<nav class="text-sm font-medium text-gray-600" aria-label="Main Navigation">
|
||||||
d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z" />
|
<a
|
||||||
</svg>
|
class:bg-gray-100={$router.path === '/'}
|
||||||
<span>{$_('dashboard-title')}</span>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
</a>
|
href="/">
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:GET')}
|
<svg
|
||||||
<a
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
class:bg-gray-100={$router.path.includes('/orgs/')}
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
viewBox="0 0 20 20"
|
||||||
href="/orgs/">
|
fill="currentColor">
|
||||||
<svg
|
<path
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z" />
|
||||||
fill="currentColor"
|
</svg>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<span>{$_('dashboard-title')}</span>
|
||||||
viewBox="0 0 24 24"
|
</a>
|
||||||
width="24"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:GET')}
|
||||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
<a
|
||||||
<path
|
class:bg-gray-100={$router.path.includes('/orgs/')}
|
||||||
d="M17 19h2v-8h-6v8h2v-6h2v6zM3 19V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v5h2v10h1v2H2v-2h1zm4-8v2h2v-2H7zm0 4v2h2v-2H7zm0-8v2h2V7H7z" /></svg>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<span>{$_('orgs')}</span>
|
href="/orgs/">
|
||||||
</a>
|
<svg
|
||||||
{/if}
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:GET')}
|
fill="currentColor"
|
||||||
<a
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class:bg-gray-100={$router.path === '/users/'}
|
viewBox="0 0 24 24"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
width="24"
|
||||||
href="/users/">
|
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
<svg
|
<path
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
d="M17 19h2v-8h-6v8h2v-6h2v6zM3 19V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v5h2v10h1v2H2v-2h1zm4-8v2h2v-2H7zm0 4v2h2v-2H7zm0-8v2h2V7H7z" /></svg>
|
||||||
width="24"
|
<span>{$_('orgs')}</span>
|
||||||
height="24"
|
</a>
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
{/if}
|
||||||
fill="currentColor"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:GET')}
|
||||||
viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z" />
|
<a
|
||||||
<path
|
class:bg-gray-100={$router.path === '/users/'}
|
||||||
d="M12 14v8H4a8 8 0 018-8zm0-1a6 6 0 110-12 6 6 0 010 12zm2.6 5.81a3.51 3.51 0 010-1.62l-1-.57 1-1.74 1 .58a3.5 3.5 0 011.4-.82V13.5h2v1.15a3.5 3.5 0 011.4.8l1-.57 1 1.74-1 .57a3.51 3.51 0 010 1.62l1 .57-1 1.74-1-.58a3.5 3.5 0 01-1.4.82v1.14h-2v-1.15a3.5 3.5 0 01-1.4-.8l-1 .57-1-1.74 1-.57zM18 17a1 1 0 100 2 1 1 0 000-2z" /></svg>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<span>{$_('users')}</span>
|
href="/users/">
|
||||||
</a>
|
<svg
|
||||||
{/if}
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:GET')}
|
width="24"
|
||||||
<a
|
height="24"
|
||||||
class:bg-gray-100={$router.path === '/groups/'}
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
fill="currentColor"
|
||||||
href="/groups/">
|
viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
<svg
|
<path
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
d="M12 14v8H4a8 8 0 018-8zm0-1a6 6 0 110-12 6 6 0 010 12zm2.6 5.81a3.51 3.51 0 010-1.62l-1-.57 1-1.74 1 .58a3.5 3.5 0 011.4-.82V13.5h2v1.15a3.5 3.5 0 011.4.8l1-.57 1 1.74-1 .57a3.51 3.51 0 010 1.62l1 .57-1 1.74-1-.58a3.5 3.5 0 01-1.4.82v1.14h-2v-1.15a3.5 3.5 0 01-1.4-.8l-1 .57-1-1.74 1-.57zM18 17a1 1 0 100 2 1 1 0 000-2z" /></svg>
|
||||||
fill="currentColor"
|
<span>{$_('users')}</span>
|
||||||
width="24"
|
</a>
|
||||||
height="24"
|
{/if}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:GET')}
|
||||||
viewBox="0 0 640 512"><path
|
<a
|
||||||
fill="currentColor"
|
class:bg-gray-100={$router.path === '/groups/'}
|
||||||
d="M610.5 341.3c2.6-14.1 2.6-28.5 0-42.6l25.8-14.9c3-1.7 4.3-5.2 3.3-8.5-6.7-21.6-18.2-41.2-33.2-57.4-2.3-2.5-6-3.1-9-1.4l-25.8 14.9c-10.9-9.3-23.4-16.5-36.9-21.3v-29.8c0-3.4-2.4-6.4-5.7-7.1-22.3-5-45-4.8-66.2 0-3.3.7-5.7 3.7-5.7 7.1v29.8c-13.5 4.8-26 12-36.9 21.3l-25.8-14.9c-2.9-1.7-6.7-1.1-9 1.4-15 16.2-26.5 35.8-33.2 57.4-1 3.3.4 6.8 3.3 8.5l25.8 14.9c-2.6 14.1-2.6 28.5 0 42.6l-25.8 14.9c-3 1.7-4.3 5.2-3.3 8.5 6.7 21.6 18.2 41.1 33.2 57.4 2.3 2.5 6 3.1 9 1.4l25.8-14.9c10.9 9.3 23.4 16.5 36.9 21.3v29.8c0 3.4 2.4 6.4 5.7 7.1 22.3 5 45 4.8 66.2 0 3.3-.7 5.7-3.7 5.7-7.1v-29.8c13.5-4.8 26-12 36.9-21.3l25.8 14.9c2.9 1.7 6.7 1.1 9-1.4 15-16.2 26.5-35.8 33.2-57.4 1-3.3-.4-6.8-3.3-8.5l-25.8-14.9zM496 368.5c-26.8 0-48.5-21.8-48.5-48.5s21.8-48.5 48.5-48.5 48.5 21.8 48.5 48.5-21.7 48.5-48.5 48.5zM96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm224 32c1.9 0 3.7-.5 5.6-.6 8.3-21.7 20.5-42.1 36.3-59.2 7.4-8 17.9-12.6 28.9-12.6 6.9 0 13.7 1.8 19.6 5.3l7.9 4.6c.8-.5 1.6-.9 2.4-1.4 7-14.6 11.2-30.8 11.2-48 0-61.9-50.1-112-112-112S208 82.1 208 144c0 61.9 50.1 112 112 112zm105.2 194.5c-2.3-1.2-4.6-2.6-6.8-3.9-8.2 4.8-15.3 9.8-27.5 9.8-10.9 0-21.4-4.6-28.9-12.6-18.3-19.8-32.3-43.9-40.2-69.6-10.7-34.5 24.9-49.7 25.8-50.3-.1-2.6-.1-5.2 0-7.8l-7.9-4.6c-3.8-2.2-7-5-9.8-8.1-3.3.2-6.5.6-9.8.6-24.6 0-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h255.4c-3.7-6-6.2-12.8-6.2-20.3v-9.2zM173.1 274.6C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z" /></svg>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<span>{$_('user-groups')}</span>
|
href="/groups/">
|
||||||
</a>
|
<svg
|
||||||
{/if}
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')}
|
fill="currentColor"
|
||||||
<a
|
width="24"
|
||||||
class:bg-gray-100={$router.path === '/runners/'}
|
height="24"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
href="/runners/">
|
viewBox="0 0 640 512"><path
|
||||||
<svg
|
fill="currentColor"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
d="M610.5 341.3c2.6-14.1 2.6-28.5 0-42.6l25.8-14.9c3-1.7 4.3-5.2 3.3-8.5-6.7-21.6-18.2-41.2-33.2-57.4-2.3-2.5-6-3.1-9-1.4l-25.8 14.9c-10.9-9.3-23.4-16.5-36.9-21.3v-29.8c0-3.4-2.4-6.4-5.7-7.1-22.3-5-45-4.8-66.2 0-3.3.7-5.7 3.7-5.7 7.1v29.8c-13.5 4.8-26 12-36.9 21.3l-25.8-14.9c-2.9-1.7-6.7-1.1-9 1.4-15 16.2-26.5 35.8-33.2 57.4-1 3.3.4 6.8 3.3 8.5l25.8 14.9c-2.6 14.1-2.6 28.5 0 42.6l-25.8 14.9c-3 1.7-4.3 5.2-3.3 8.5 6.7 21.6 18.2 41.1 33.2 57.4 2.3 2.5 6 3.1 9 1.4l25.8-14.9c10.9 9.3 23.4 16.5 36.9 21.3v29.8c0 3.4 2.4 6.4 5.7 7.1 22.3 5 45 4.8 66.2 0 3.3-.7 5.7-3.7 5.7-7.1v-29.8c13.5-4.8 26-12 36.9-21.3l25.8 14.9c2.9 1.7 6.7 1.1 9-1.4 15-16.2 26.5-35.8 33.2-57.4 1-3.3-.4-6.8-3.3-8.5l-25.8-14.9zM496 368.5c-26.8 0-48.5-21.8-48.5-48.5s21.8-48.5 48.5-48.5 48.5 21.8 48.5 48.5-21.7 48.5-48.5 48.5zM96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm224 32c1.9 0 3.7-.5 5.6-.6 8.3-21.7 20.5-42.1 36.3-59.2 7.4-8 17.9-12.6 28.9-12.6 6.9 0 13.7 1.8 19.6 5.3l7.9 4.6c.8-.5 1.6-.9 2.4-1.4 7-14.6 11.2-30.8 11.2-48 0-61.9-50.1-112-112-112S208 82.1 208 144c0 61.9 50.1 112 112 112zm105.2 194.5c-2.3-1.2-4.6-2.6-6.8-3.9-8.2 4.8-15.3 9.8-27.5 9.8-10.9 0-21.4-4.6-28.9-12.6-18.3-19.8-32.3-43.9-40.2-69.6-10.7-34.5 24.9-49.7 25.8-50.3-.1-2.6-.1-5.2 0-7.8l-7.9-4.6c-3.8-2.2-7-5-9.8-8.1-3.3.2-6.5.6-9.8.6-24.6 0-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h255.4c-3.7-6-6.2-12.8-6.2-20.3v-9.2zM173.1 274.6C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z" /></svg>
|
||||||
viewBox="0 0 24 24"
|
<span>{$_('user-groups')}</span>
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
</a>
|
||||||
fill="currentColor"
|
{/if}
|
||||||
width="24"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')}
|
||||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
<a
|
||||||
<path
|
class:bg-gray-100={$router.path === '/runners/'}
|
||||||
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>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<span>{$_('runners')}</span>
|
href="/runners/">
|
||||||
</a>
|
<svg
|
||||||
{/if}
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')}
|
viewBox="0 0 24 24"
|
||||||
<a
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
class:bg-gray-100={$router.path === '/teams/'}
|
fill="currentColor"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
width="24"
|
||||||
href="/teams/">
|
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
<svg
|
<path
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
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>
|
||||||
fill="currentColor"
|
<span>{$_('runners')}</span>
|
||||||
width="24"
|
</a>
|
||||||
height="24"
|
{/if}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')}
|
||||||
viewBox="0 0 640 512"><path
|
<a
|
||||||
fill="currentColor"
|
class:bg-gray-100={$router.path === '/teams/'}
|
||||||
d="M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z" /></svg>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<span>{$_('teams')}</span>
|
href="/teams/">
|
||||||
</a>
|
<svg
|
||||||
{/if}
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')}
|
fill="currentColor"
|
||||||
<a
|
width="24"
|
||||||
class:bg-gray-100={$router.path.includes('/donors/')}
|
height="24"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
href="/donors/">
|
viewBox="0 0 640 512"><path
|
||||||
<svg
|
fill="currentColor"
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
d="M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z" /></svg>
|
||||||
fill="currentColor"
|
<span>{$_('teams')}</span>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
</a>
|
||||||
viewBox="0 0 24 24"
|
{/if}
|
||||||
width="24"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')}
|
||||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
<a
|
||||||
<path
|
class:bg-gray-100={$router.path.includes('/donors/')}
|
||||||
d="M9.33 11.5h2.17A4.5 4.5 0 0 1 16 16H8.999L9 17h8v-1a5.578 5.578 0 0 0-.886-3H19a5 5 0 0 1 4.516 2.851C21.151 18.972 17.322 21 13 21c-2.761 0-5.1-.59-7-1.625L6 10.071A6.967 6.967 0 0 1 9.33 11.5zM5 19a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v9zM18 5a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm-7-3a3 3 0 1 1 0 6 3 3 0 0 1 0-6z" /></svg>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<span>{$_('donors')}</span>
|
href="/donors/">
|
||||||
</a>
|
<svg
|
||||||
{/if}
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')}
|
fill="currentColor"
|
||||||
<a
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class:bg-gray-100={$router.path.includes('/donations/')}
|
viewBox="0 0 24 24"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
width="24"
|
||||||
href="/donations/">
|
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
<svg
|
<path
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
d="M9.33 11.5h2.17A4.5 4.5 0 0 1 16 16H8.999L9 17h8v-1a5.578 5.578 0 0 0-.886-3H19a5 5 0 0 1 4.516 2.851C21.151 18.972 17.322 21 13 21c-2.761 0-5.1-.59-7-1.625L6 10.071A6.967 6.967 0 0 1 9.33 11.5zM5 19a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v9zM18 5a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm-7-3a3 3 0 1 1 0 6 3 3 0 0 1 0-6z" /></svg>
|
||||||
fill="currentColor"
|
<span>{$_('donors')}</span>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
</a>
|
||||||
viewBox="0 0 24 24"
|
{/if}
|
||||||
width="24"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')}
|
||||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
<a
|
||||||
<path
|
class:bg-gray-100={$router.path.includes('/donations/')}
|
||||||
d="M14 2a8 8 0 013.3 15.3A8 8 0 116.7 6.7 8 8 0 0114 2zm-3 7H9v1a2.5 2.5 0 00-.16 5h2.25a.5.5 0 010 1H7v2h2v1h2v-1a2.5 2.5 0 00.16-5H8.91a.5.5 0 010-1H13v-2h-2V9zm3-5a5.99 5.99 0 00-4.48 2.01 8 8 0 018.47 8.47A6 6 0 0014 4z" /></svg>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<span>{$_('donations')}</span>
|
href="/donations/">
|
||||||
</a>
|
<svg
|
||||||
{/if}
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('TRACK:GET')}
|
fill="currentColor"
|
||||||
<a
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class:bg-gray-100={$router.path === '/tracks/'}
|
viewBox="0 0 24 24"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
width="24"
|
||||||
href="/tracks/">
|
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
<svg
|
<path
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
d="M14 2a8 8 0 013.3 15.3A8 8 0 116.7 6.7 8 8 0 0114 2zm-3 7H9v1a2.5 2.5 0 00-.16 5h2.25a.5.5 0 010 1H7v2h2v1h2v-1a2.5 2.5 0 00.16-5H8.91a.5.5 0 010-1H13v-2h-2V9zm3-5a5.99 5.99 0 00-4.48 2.01 8 8 0 018.47 8.47A6 6 0 0014 4z" /></svg>
|
||||||
fill="currentColor"
|
<span>{$_('donations')}</span>
|
||||||
width="24"
|
</a>
|
||||||
height="24"
|
{/if}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TRACK:GET')}
|
||||||
viewBox="0 0 640 512"><path
|
<a
|
||||||
fill="currentColor"
|
class:bg-gray-100={$router.path === '/tracks/'}
|
||||||
d="M635.7 167.2L556.1 31.7c-8.8-15-28.3-20.1-43.5-11.5l-69 39.1L503.3 161c2.2 3.8.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9L416 75l-55.2 31.3 27.9 47.4c2.2 3.8.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9L333.2 122 278 153.3 337.8 255c2.2 3.7.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9l-59.7-101.7-55.2 31.3 27.9 47.4c2.2 3.8.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9l-27.9-47.5-55.2 31.3 59.7 101.7c2.2 3.7.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9L84.9 262.9l-69 39.1C.7 310.7-4.6 329.8 4.2 344.8l79.6 135.6c8.8 15 28.3 20.1 43.5 11.5L624.1 210c15.2-8.6 20.4-27.8 11.6-42.8z" /></svg>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<span>{$_('tracks')}</span>
|
href="/tracks/">
|
||||||
</a>
|
<svg
|
||||||
{/if}
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:GET')}
|
fill="currentColor"
|
||||||
<a
|
width="24"
|
||||||
class:bg-gray-100={$router.path === '/scans/'}
|
height="24"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
href="/scans/">
|
viewBox="0 0 640 512"><path
|
||||||
<svg
|
fill="currentColor"
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
d="M635.7 167.2L556.1 31.7c-8.8-15-28.3-20.1-43.5-11.5l-69 39.1L503.3 161c2.2 3.8.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9L416 75l-55.2 31.3 27.9 47.4c2.2 3.8.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9L333.2 122 278 153.3 337.8 255c2.2 3.7.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9l-59.7-101.7-55.2 31.3 27.9 47.4c2.2 3.8.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9l-27.9-47.5-55.2 31.3 59.7 101.7c2.2 3.7.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9L84.9 262.9l-69 39.1C.7 310.7-4.6 329.8 4.2 344.8l79.6 135.6c8.8 15 28.3 20.1 43.5 11.5L624.1 210c15.2-8.6 20.4-27.8 11.6-42.8z" /></svg>
|
||||||
fill="currentColor"
|
<span>{$_('tracks')}</span>
|
||||||
width="24"
|
</a>
|
||||||
height="24"
|
{/if}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:GET')}
|
||||||
viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z" />
|
<a
|
||||||
<path
|
class:bg-gray-100={$router.path === '/cards/'}
|
||||||
fill="currentColor"
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
d="M2 4h2v16H2V4zm4 0h1v16H6V4zm2 0h2v16H8V4zm3 0h2v16h-2V4zm3 0h2v16h-2V4zm3 0h1v16h-1V4zm2 0h3v16h-3V4z" /></svg>
|
href="/cards/">
|
||||||
<span>Scans</span>
|
<svg
|
||||||
</a>
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
{/if}
|
fill="currentColor"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:GET')}
|
width="24"
|
||||||
<a
|
height="24"
|
||||||
class:bg-gray-100={$router.path === '/contacts/'}
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
viewBox="0 0 24 24">
|
||||||
href="/contacts/">
|
<path fill="none" d="M0 0h24v24H0z" />
|
||||||
<svg
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
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>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<span>{$_('cards')}</span>
|
||||||
viewBox="0 0 24 24"
|
</a>
|
||||||
width="24"
|
{/if}
|
||||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:GET')}
|
||||||
<path
|
<a
|
||||||
d="M2 22a8 8 0 1 1 16 0H2zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6zm10 4h4v2h-4v-2zm-3-5h7v2h-7v-2zm2-5h5v2h-5V7z" /></svg>
|
class:bg-gray-100={$router.path === '/scans/'}
|
||||||
<span>{$_('contacts')}</span>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
</a>
|
href="/scans/">
|
||||||
{/if}
|
<svg
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('STATION:GET')}
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
<a
|
fill="currentColor"
|
||||||
class:bg-gray-100={$router.path === '/scanstations/'}
|
width="24"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
height="24"
|
||||||
href="/scanstations/">
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<svg
|
viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
width="24"
|
d="M2 4h2v16H2V4zm4 0h1v16H6V4zm2 0h2v16H8V4zm3 0h2v16h-2V4zm3 0h2v16h-2V4zm3 0h1v16h-1V4zm2 0h3v16h-3V4z" /></svg>
|
||||||
height="24"
|
<span>Scans</span>
|
||||||
viewBox="0 0 24 24"
|
</a>
|
||||||
xmlns="http://www.w3.org/2000/svg"><path
|
{/if}
|
||||||
fill="none"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:GET')}
|
||||||
d="M0 0h24v24H0z" />
|
<a
|
||||||
<path
|
class:bg-gray-100={$router.path === '/contacts/'}
|
||||||
fill="currentColor"
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
href="/contacts/">
|
||||||
<span>{$_('scanstations')}</span>
|
<svg
|
||||||
</a>
|
fill="currentColor"
|
||||||
{/if}
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
<a
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class:bg-gray-100={$router.path === '/settings/'}
|
viewBox="0 0 24 24"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
width="24"
|
||||||
href="/settings/">
|
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
<svg
|
<path
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
d="M2 22a8 8 0 1 1 16 0H2zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6zm10 4h4v2h-4v-2zm-3-5h7v2h-7v-2zm2-5h5v2h-5V7z" /></svg>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<span>{$_('contacts')}</span>
|
||||||
viewBox="0 0 20 20"
|
</a>
|
||||||
fill="currentColor">
|
{/if}
|
||||||
<path
|
{#if store.state.jwtinfo.userdetails.permissions.includes('STATION:GET')}
|
||||||
fill-rule="evenodd"
|
<a
|
||||||
d="M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z"
|
class:bg-gray-100={$router.path === '/scanstations/'}
|
||||||
clip-rule="evenodd" />
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
</svg>
|
href="/scanstations/">
|
||||||
<span>{$_('settings')}</span>
|
<svg
|
||||||
</a>
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
<a
|
fill="currentColor"
|
||||||
class:bg-gray-100={$router.path === '/about/'}
|
width="24"
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
height="24"
|
||||||
href="/about/">
|
viewBox="0 0 24 24"
|
||||||
<svg
|
xmlns="http://www.w3.org/2000/svg"><path
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
d="M0 0h24v24H0z" />
|
||||||
fill="none"
|
<path
|
||||||
stroke="currentColor"
|
fill="currentColor"
|
||||||
stroke-width="2"
|
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
||||||
stroke-linecap="round"
|
<span>{$_('scanstations')}</span>
|
||||||
stroke-linejoin="round"
|
</a>
|
||||||
viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" />
|
{/if}
|
||||||
<path d="M12 16v-4M12 8h.01" /></svg>
|
{#if store.state.jwtinfo.userdetails.permissions.includes('STATSCLIENT:GET')}
|
||||||
<span>{$_('about')}</span>
|
<a
|
||||||
</a>
|
class:bg-gray-100={$router.path === '/statsclients/'}
|
||||||
<span
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
tabindex="0"
|
href="/statsclients/">
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
<svg
|
||||||
on:click={() => {
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
AuthService.authControllerLogout();
|
fill="currentColor"
|
||||||
logout();
|
width="24"
|
||||||
}}>
|
height="24"
|
||||||
<svg
|
viewBox="0 0 24 24"
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
xmlns="http://www.w3.org/2000/svg"><path
|
||||||
fill="currentColor"
|
fill="none"
|
||||||
width="24"
|
d="M0 0h24v24H0z" />
|
||||||
height="24"
|
<path
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
fill="currentColor"
|
||||||
viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z" />
|
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
||||||
<path
|
<span>{$_('statsclients')}</span>
|
||||||
d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2a9.985 9.985 0 0 1 8 4h-2.71a8 8 0 1 0 .001 12h2.71A9.985 9.985 0 0 1 12 22zm7-6v-3h-8v-2h8V8l5 4-5 4z" /></svg>
|
</a>
|
||||||
<span>{$_('logout')}</span>
|
{/if}
|
||||||
</span>
|
<a
|
||||||
</nav>
|
class:bg-gray-100={$router.path === '/settings/'}
|
||||||
</nav>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<div class="ml-0 transition md:ml-60">
|
href="/settings/">
|
||||||
<header
|
<svg
|
||||||
on:click={() => {
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
navOpen = true;
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
}}
|
viewBox="0 0 20 20"
|
||||||
class="flex items-center justify-between w-full px-4 bg-white border-b h-14 md:hidden">
|
fill="currentColor">
|
||||||
<button class="block btn btn-light md:hidden">
|
<path
|
||||||
<span class="sr-only">Menu</span><svg
|
fill-rule="evenodd"
|
||||||
class="w-4 h-4"
|
d="M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
clip-rule="evenodd" />
|
||||||
viewBox="0 0 20 20"
|
</svg>
|
||||||
fill="currentcolor"><path
|
<span>{$_('settings')}</span>
|
||||||
fill-rule="evenodd"
|
</a>
|
||||||
d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4A1 1 0 013 5zm0 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
|
<a
|
||||||
clip-rule="evenodd" /></svg></button>
|
class:bg-gray-100={$router.path === '/about/'}
|
||||||
</header>
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
<slot>
|
href="/about/">
|
||||||
<NoComponentLoaded />
|
<svg
|
||||||
</slot>
|
class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600"
|
||||||
</div>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<div
|
fill="none"
|
||||||
on:click={() => {
|
stroke="currentColor"
|
||||||
navOpen = false;
|
stroke-width="2"
|
||||||
}}
|
stroke-linecap="round"
|
||||||
class:hidden={!navOpen}
|
stroke-linejoin="round"
|
||||||
class="fixed inset-0 z-10 w-screen h-screen bg-black bg-opacity-25 md:hidden" />
|
viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" />
|
||||||
</section>
|
<path d="M12 16v-4M12 8h.01" /></svg>
|
||||||
|
<span>{$_('about')}</span>
|
||||||
|
</a>
|
||||||
|
<span
|
||||||
|
tabindex="0"
|
||||||
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
|
on:click={() => {
|
||||||
|
AuthService.authControllerLogout();
|
||||||
|
logout();
|
||||||
|
}}>
|
||||||
|
<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"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
|
<path
|
||||||
|
d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2a9.985 9.985 0 0 1 8 4h-2.71a8 8 0 1 0 .001 12h2.71A9.985 9.985 0 0 1 12 22zm7-6v-3h-8v-2h8V8l5 4-5 4z" /></svg>
|
||||||
|
<span>{$_('logout')}</span>
|
||||||
|
</span>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div class="ml-0 transition md:ml-60">
|
||||||
|
<header
|
||||||
|
class="flex items-center justify-between w-full px-4 bg-white border-b h-14 md:hidden">
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
navOpen = true;
|
||||||
|
}}
|
||||||
|
class="block btn btn-light md:hidden">
|
||||||
|
<span class="sr-only">Menu</span><svg
|
||||||
|
class="w-4 h-4"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentcolor"><path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4A1 1 0 013 5zm0 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
|
||||||
|
clip-rule="evenodd" /></svg></button>
|
||||||
|
</header>
|
||||||
|
<slot>
|
||||||
|
<NoComponentLoaded />
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
{#if navOpen === true}
|
||||||
|
<div
|
||||||
|
on:click={() => {
|
||||||
|
navOpen = false;
|
||||||
|
console.log({ navOpen });
|
||||||
|
}}
|
||||||
|
class:hidden={!navOpen}
|
||||||
|
class="fixed inset-0 z-10 w-screen h-screen bg-black bg-opacity-25 md:hidden" />
|
||||||
|
{/if}
|
||||||
|
</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
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
|
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
|
||||||
import PromiseError from "../base/PromiseError.svelte";
|
import PromiseError from "../base/PromiseError.svelte";
|
||||||
import Select from "svelte-select";
|
import Select from "svelte-select";
|
||||||
|
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
|
||||||
|
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
|
||||||
|
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
|
||||||
|
import { tick } from "svelte";
|
||||||
$: delete_triggered = false;
|
$: delete_triggered = false;
|
||||||
$: address_valid_or_none =
|
$: address_valid_or_none =
|
||||||
(isAddress1Valid && iszipcodevalid && iscityvalid) ||
|
(isAddress1Valid && iszipcodevalid && iscityvalid) ||
|
||||||
@@ -18,6 +22,9 @@
|
|||||||
let original = "";
|
let original = "";
|
||||||
let original_object = {};
|
let original_object = {};
|
||||||
let contacts = [];
|
let contacts = [];
|
||||||
|
let valueCopy = null;
|
||||||
|
let areaDom;
|
||||||
|
let copied = false;
|
||||||
export let params;
|
export let params;
|
||||||
$: editable = {};
|
$: editable = {};
|
||||||
$: contact = {};
|
$: contact = {};
|
||||||
@@ -26,7 +33,11 @@
|
|||||||
$: isAddress1Valid = editable.address?.address1?.trim().length !== 0;
|
$: isAddress1Valid = editable.address?.address1?.trim().length !== 0;
|
||||||
$: iszipcodevalid = editable.address?.postalcode?.trim().length !== 0;
|
$: iszipcodevalid = editable.address?.postalcode?.trim().length !== 0;
|
||||||
$: iscityvalid = editable.address?.city?.trim().length !== 0;
|
$: iscityvalid = editable.address?.city?.trim().length !== 0;
|
||||||
$: sponsoring_contracts_download_open = false;
|
$: sponsoring_contracts_show = true;
|
||||||
|
$: cards_show = true;
|
||||||
|
$: certificates_show = true;
|
||||||
|
$: generate_orgs = [original_object];
|
||||||
|
$: registrationLink = `${config.baseurl}/selfservice/register/${editable.registrationKey}`;
|
||||||
const getContactLabel = (option) =>
|
const getContactLabel = (option) =>
|
||||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||||
const promise = RunnerOrganizationService.runnerOrganizationControllerGetOne(
|
const promise = RunnerOrganizationService.runnerOrganizationControllerGetOne(
|
||||||
@@ -60,14 +71,6 @@
|
|||||||
});
|
});
|
||||||
let modal_open = false;
|
let modal_open = false;
|
||||||
let delete_org = {};
|
let delete_org = {};
|
||||||
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 deleteOrganization() {
|
function deleteOrganization() {
|
||||||
RunnerOrganizationService.runnerOrganizationControllerRemove(
|
RunnerOrganizationService.runnerOrganizationControllerRemove(
|
||||||
original_object.id,
|
original_object.id,
|
||||||
@@ -102,6 +105,7 @@
|
|||||||
postdata
|
postdata
|
||||||
)
|
)
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
|
editable.registrationKey = resp.registrationKey;
|
||||||
original_object = Object.assign({}, editable);
|
original_object = Object.assign({}, editable);
|
||||||
original = JSON.stringify(original_object);
|
original = JSON.stringify(original_object);
|
||||||
Toastify({
|
Toastify({
|
||||||
@@ -114,58 +118,46 @@
|
|||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export let import_modal_open = false;
|
async function copy() {
|
||||||
async function generateSponsoringContract(locale) {
|
if(!editable.registrationKey){
|
||||||
sponsoring_contracts_download_open = false;
|
Toastify({
|
||||||
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(
|
text: $_('you-have-to-save-your-changes-to-generate-a-link'),
|
||||||
original_object.id
|
duration: 500,
|
||||||
);
|
backgroundColor:
|
||||||
const toast = Toastify({
|
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
||||||
text: $_("generating-pdf"),
|
}).showToast();
|
||||||
duration: -1,
|
return;
|
||||||
}).showToast();
|
}
|
||||||
fetch(
|
valueCopy = registrationLink;
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
await tick();
|
||||||
{
|
areaDom.focus();
|
||||||
method: "POST",
|
areaDom.select();
|
||||||
headers: {
|
try {
|
||||||
"Content-Type": "application/json",
|
const successful = document.execCommand("copy");
|
||||||
},
|
if (!successful) {
|
||||||
body: JSON.stringify(runners),
|
throw new Error();
|
||||||
}
|
}
|
||||||
)
|
Toastify({
|
||||||
.then((response) => {
|
text: $_("copied-link-to-clipboard"),
|
||||||
if (response.status != "200") {
|
duration: 500,
|
||||||
toast.hideToast();
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
Toastify({
|
}).showToast();
|
||||||
text: $_("pdf-generation-failed"),
|
copied = true;
|
||||||
duration: 3500,
|
} catch (err) {
|
||||||
backgroundColor:
|
Toastify({
|
||||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
text: $_("error-whyile-copying-to-clipboard"),
|
||||||
}).showToast();
|
duration: 500,
|
||||||
} else {
|
backgroundColor:
|
||||||
return response.blob();
|
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
||||||
}
|
}).showToast();
|
||||||
})
|
}
|
||||||
.then((blob) => {
|
// we can notifi by event or storage about copy status
|
||||||
const url = window.URL.createObjectURL(blob);
|
valueCopy = null;
|
||||||
let a = document.createElement("a");
|
|
||||||
a.href = url;
|
|
||||||
a.download = "Sponsorings_" + original_object.name + ".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) => {});
|
|
||||||
}
|
}
|
||||||
|
export let import_modal_open = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{#if valueCopy != null}<textarea bind:this={areaDom}>{valueCopy}</textarea>{/if}
|
||||||
<ImportRunnerModal
|
<ImportRunnerModal
|
||||||
on:cancelDelete={(event) => {
|
on:cancelDelete={(event) => {
|
||||||
import_modal_open = false;
|
import_modal_open = false;
|
||||||
@@ -182,64 +174,11 @@
|
|||||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||||
{original_object.name}
|
{original_object.name}
|
||||||
<span data-id="org_actions_${editable.id}">
|
<span data-id="org_actions_${editable.id}">
|
||||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
<GenerateSponsoringContracts
|
||||||
<div>
|
bind:sponsoring_contracts_show
|
||||||
<button
|
bind:generate_orgs />
|
||||||
on:click={() => {
|
<GenerateRunnerCards bind:cards_show bind:generate_orgs />
|
||||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
<GenerateRunnerCertificates bind:certificates_show bind:generate_orgs />
|
||||||
}}
|
|
||||||
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-sponsoring-contracts')}
|
|
||||||
<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 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"
|
|
||||||
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 inline-flex"
|
|
||||||
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 inline-flex"
|
|
||||||
role="menuitem">
|
|
||||||
{$_('english')}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
@@ -250,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}
|
||||||
@@ -382,99 +321,151 @@
|
|||||||
on:select={(selectedValue) => (editable.contact = selectedValue.detail.value)}
|
on:select={(selectedValue) => (editable.contact = selectedValue.detail.value)}
|
||||||
on:clear={() => (editable.contact = null)} />
|
on:clear={() => (editable.contact = null)} />
|
||||||
</div>
|
</div>
|
||||||
<!-- -->
|
<div>
|
||||||
<div class="flex items-start mt-2">
|
<div class="flex items-start mt-2">
|
||||||
<div class="flex items-center h-5">
|
<div class="flex items-center h-5">
|
||||||
<input
|
<input
|
||||||
bind:checked={editable.address_checked}
|
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 class="ml-3 text-sm">
|
||||||
|
<label
|
||||||
|
for="toggle_selfservice_feature"
|
||||||
|
class="font-medium text-gray-700">{$_('selfservice-registration')}</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-3 text-sm">
|
<div>
|
||||||
<label
|
{#if editable.registrationEnabled}
|
||||||
for="comments"
|
<div class="text-sm w-full">
|
||||||
class="font-medium text-gray-700">{$_('address')}</label>
|
<div on:click={copy} class="inline-flex w-full">
|
||||||
|
<p
|
||||||
|
name="token"
|
||||||
|
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">
|
||||||
|
{#if editable.registrationKey}
|
||||||
|
{registrationLink}
|
||||||
|
{:else}
|
||||||
|
{$_('you-have-to-save-your-changes-to-generate-a-link')}
|
||||||
|
{/if}
|
||||||
|
</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>
|
||||||
|
{#if editable.registrationKey}
|
||||||
|
<p class="text-gray-500 text-xs">
|
||||||
|
{$_('click-to-copy-the-link-into-your-clipboard')}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<!-- -->
|
||||||
|
<div>
|
||||||
|
<div class="flex items-start mt-2">
|
||||||
|
<div class="flex items-center h-5">
|
||||||
|
<input
|
||||||
|
bind:checked={editable.address_checked}
|
||||||
|
id="toggle_address_checkbox"
|
||||||
|
name="toggle_address_checkbox"
|
||||||
|
type="checkbox"
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
|
</div>
|
||||||
|
<div class="ml-3 text-sm">
|
||||||
|
<label
|
||||||
|
for="toggle_address_checkbox"
|
||||||
|
class="font-medium text-gray-700">{$_('address')}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#if editable.address_checked === true}
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address1"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('address')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="Address"
|
||||||
|
class:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:ring-red-500={!isAddress1Valid}
|
||||||
|
bind:value={editable.address.address1}
|
||||||
|
type="text"
|
||||||
|
name="address1"
|
||||||
|
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 !isAddress1Valid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('address-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address2"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('apartment-suite-etc')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('apartment-suite-etc')}
|
||||||
|
bind:value={editable.address.address2}
|
||||||
|
type="text"
|
||||||
|
name="address2"
|
||||||
|
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 class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="zipcode"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('zip-postal-code')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('zip-postal-code')}
|
||||||
|
class:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:ring-red-500={!iszipcodevalid}
|
||||||
|
bind:value={editable.address.postalcode}
|
||||||
|
type="text"
|
||||||
|
name="zipcode"
|
||||||
|
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 !iszipcodevalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-zipcode-postal-code-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="city"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('city')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('city')}
|
||||||
|
class:border-red-500={!iscityvalid}
|
||||||
|
class:focus:border-red-500={!iscityvalid}
|
||||||
|
class:focus:ring-red-500={!iscityvalid}
|
||||||
|
bind:value={editable.address.city}
|
||||||
|
type="text"
|
||||||
|
name="city"
|
||||||
|
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 !iscityvalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-city-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if editable.address_checked === true}
|
|
||||||
<div class="col-span-6">
|
|
||||||
<label
|
|
||||||
for="address1"
|
|
||||||
class="block text-sm font-medium text-gray-700">{$_('address')}</label>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
placeholder="Address"
|
|
||||||
class:border-red-500={!isAddress1Valid}
|
|
||||||
class:focus:border-red-500={!isAddress1Valid}
|
|
||||||
class:focus:ring-red-500={!isAddress1Valid}
|
|
||||||
bind:value={editable.address.address1}
|
|
||||||
type="text"
|
|
||||||
name="address1"
|
|
||||||
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 !isAddress1Valid}
|
|
||||||
<span
|
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
|
||||||
{$_('address-is-required')}
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="col-span-6">
|
|
||||||
<label
|
|
||||||
for="address2"
|
|
||||||
class="block text-sm font-medium text-gray-700">{$_('apartment-suite-etc')}</label>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
placeholder={$_('apartment-suite-etc')}
|
|
||||||
bind:value={editable.address.address2}
|
|
||||||
type="text"
|
|
||||||
name="address2"
|
|
||||||
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 class="col-span-6">
|
|
||||||
<label
|
|
||||||
for="zipcode"
|
|
||||||
class="block text-sm font-medium text-gray-700">{$_('zip-postal-code')}</label>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
placeholder={$_('zip-postal-code')}
|
|
||||||
class:border-red-500={!iszipcodevalid}
|
|
||||||
class:focus:border-red-500={!iszipcodevalid}
|
|
||||||
class:focus:ring-red-500={!iszipcodevalid}
|
|
||||||
bind:value={editable.address.postalcode}
|
|
||||||
type="text"
|
|
||||||
name="zipcode"
|
|
||||||
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 !iszipcodevalid}
|
|
||||||
<span
|
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
|
||||||
{$_('valid-zipcode-postal-code-is-required')}
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="col-span-6">
|
|
||||||
<label
|
|
||||||
for="city"
|
|
||||||
class="block text-sm font-medium text-gray-700">{$_('city')}</label>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
placeholder={$_('city')}
|
|
||||||
class:border-red-500={!iscityvalid}
|
|
||||||
class:focus:border-red-500={!iscityvalid}
|
|
||||||
class:focus:ring-red-500={!iscityvalid}
|
|
||||||
bind:value={editable.address.city}
|
|
||||||
type="text"
|
|
||||||
name="city"
|
|
||||||
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 !iscityvalid}
|
|
||||||
<span
|
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
|
||||||
{$_('valid-city-is-required')}
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</section>
|
</section>
|
||||||
{:else}
|
{:else}
|
||||||
{#await promise}
|
{#await promise}
|
||||||
|
|||||||
@@ -1,318 +1,219 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
let modal_open = false;
|
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
|
||||||
let delete_org = {};
|
let modal_open = false;
|
||||||
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
let delete_org = {};
|
||||||
import store from "../../store";
|
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
||||||
import OrgsEmptyState from "./OrgsEmptyState.svelte";
|
import store from "../../store";
|
||||||
import Toastify from "toastify-js";
|
import OrgsEmptyState from "./OrgsEmptyState.svelte";
|
||||||
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
|
import Toastify from "toastify-js";
|
||||||
$: searchvalue = "";
|
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
|
||||||
$: active_deletes = [];
|
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
|
||||||
$: sponsoring_contracts_download_open = false;
|
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
|
||||||
export let current_organizations = [];
|
$: searchvalue = "";
|
||||||
|
$: active_deletes = [];
|
||||||
const promise = RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
|
$: sponsoring_contracts_show = current_organizations.some((r) => r.is_selected === true);
|
||||||
(val) => {
|
$: cards_show = current_organizations.some((r) => r.is_selected === true);
|
||||||
current_organizations = val;
|
$: generate_orgs = current_organizations.filter((r) => r.is_selected === true);
|
||||||
}
|
$: certificates_show = current_organizations.some(
|
||||||
);
|
(r) => r.is_selected === true
|
||||||
|
);
|
||||||
document.addEventListener("click", function (e) {
|
export let current_organizations = [];
|
||||||
if (
|
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
const promise = RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
(val) => {
|
||||||
) {
|
current_organizations = val;
|
||||||
sponsoring_contracts_download_open = false;
|
}
|
||||||
}
|
);
|
||||||
});
|
</script>
|
||||||
|
|
||||||
async function generateSponsoringContract(locale) {
|
<ConfirmOrgDeletion
|
||||||
sponsoring_contracts_download_open = false;
|
on:cancelDelete={(event) => {
|
||||||
const orgs = current_organizations.filter((r) => r.is_selected === true);
|
modal_open = false;
|
||||||
const toast = Toastify({
|
active_deletes[event.detail.id] = false;
|
||||||
text: $_("generating-pdfs"),
|
}}
|
||||||
duration: -1,
|
bind:modal_open
|
||||||
}).showToast();
|
bind:delete_org />
|
||||||
let count = 0;
|
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:GET')}
|
||||||
for await (const o of orgs) {
|
{#await promise}
|
||||||
const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners(
|
<div
|
||||||
o.id
|
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||||
);
|
role="alert">
|
||||||
fetch(
|
<p class="font-bold">{$_('organizations-are-being-loaded')}</p>
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
||||||
{
|
</div>
|
||||||
method: "POST",
|
{:then}
|
||||||
headers: {
|
{#if current_organizations.length === 0}
|
||||||
"Content-Type": "application/json",
|
<OrgsEmptyState />
|
||||||
},
|
{:else}
|
||||||
body: JSON.stringify(runners),
|
<input
|
||||||
}
|
type="search"
|
||||||
)
|
bind:value={searchvalue}
|
||||||
.then((response) => {
|
placeholder={$_('datatable.search')}
|
||||||
if (response.status != "200") {
|
aria-label={$_('datatable.search')}
|
||||||
toast.hideToast();
|
class="mb-4" />
|
||||||
Toastify({
|
<div class="h-12">
|
||||||
text: $_("pdf-generation-failed"),
|
<GenerateSponsoringContracts
|
||||||
duration: 3500,
|
bind:sponsoring_contracts_show
|
||||||
backgroundColor:
|
bind:generate_orgs />
|
||||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
<GenerateRunnerCards
|
||||||
}).showToast();
|
bind:cards_show
|
||||||
} else {
|
bind:generate_orgs />
|
||||||
return response.blob();
|
<GenerateRunnerCertificates
|
||||||
}
|
bind:certificates_show
|
||||||
})
|
bind:generate_orgs />
|
||||||
.then((blob) => {
|
</div>
|
||||||
count++;
|
<div
|
||||||
const url = window.URL.createObjectURL(blob);
|
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
||||||
let a = document.createElement("a");
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
a.href = url;
|
<thead class="bg-gray-50">
|
||||||
a.download = "Sponsorings_" + o.name + ".pdf";
|
<tr>
|
||||||
document.body.appendChild(a);
|
<th
|
||||||
a.click();
|
scope="col"
|
||||||
a.remove();
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
if (count === orgs.length) {
|
<span
|
||||||
toast.hideToast();
|
on:click={() => {
|
||||||
Toastify({
|
const newstate = !current_organizations.some((r) => r.is_selected === true);
|
||||||
text: $_("pdfs-successfully-generated"),
|
current_organizations = current_organizations.map((r) => {
|
||||||
duration: 3500,
|
r.is_selected = newstate;
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
return r;
|
||||||
}).showToast();
|
});
|
||||||
}
|
}}
|
||||||
})
|
class="underline cursor-pointer select-none">{#if current_organizations.some((r) => r.is_selected === true)}
|
||||||
.catch((err) => {});
|
{$_('deselect-all')}
|
||||||
}
|
{:else}{$_('select-all')}{/if}
|
||||||
}
|
</span>
|
||||||
</script>
|
</th>
|
||||||
|
<th
|
||||||
<ConfirmOrgDeletion
|
scope="col"
|
||||||
on:cancelDelete={(event) => {
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
modal_open = false;
|
{$_('name')}
|
||||||
active_deletes[event.detail.id] = false;
|
</th>
|
||||||
}}
|
<th
|
||||||
bind:modal_open
|
scope="col"
|
||||||
bind:delete_org />
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:GET')}
|
{$_('address')}
|
||||||
{#await promise}
|
</th>
|
||||||
<div
|
<th
|
||||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
scope="col"
|
||||||
role="alert">
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
<p class="font-bold">{$_('organizations-are-being-loaded')}</p>
|
{$_('contact')}
|
||||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
</th>
|
||||||
</div>
|
<th scope="col" class="relative px-6 py-3">
|
||||||
{:then}
|
<span class="sr-only">{$_('action')}</span>
|
||||||
{#if current_organizations.length === 0}
|
</th>
|
||||||
<OrgsEmptyState />
|
</tr>
|
||||||
{:else}
|
</thead>
|
||||||
<input
|
<tbody class="divide-y divide-gray-200">
|
||||||
type="search"
|
{#each current_organizations as o}
|
||||||
bind:value={searchvalue}
|
{#if Object.values(o)
|
||||||
placeholder={$_('datatable.search')}
|
.toString()
|
||||||
aria-label={$_('datatable.search')}
|
.toLowerCase()
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
.includes(searchvalue)}
|
||||||
<div class="h-12">
|
<tr data-rowid="org_{o.id}">
|
||||||
{#if current_organizations.some((r) => r.is_selected === true)}
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
<input
|
||||||
<div>
|
bind:checked={o.is_selected}
|
||||||
<button
|
type="checkbox"
|
||||||
on:click={() => {
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
</td>
|
||||||
}}
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
type="button"
|
<div class="flex items-center">
|
||||||
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"
|
<div class="ml-4">
|
||||||
id="options-menu"
|
<div class="text-sm font-medium text-gray-900">
|
||||||
aria-haspopup="true"
|
{o.name}
|
||||||
aria-expanded="true">
|
</div>
|
||||||
{$_('generate-sponsoring-contracts')}
|
</div>
|
||||||
<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>
|
</div>
|
||||||
</button>
|
</td>
|
||||||
</div>
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
{#if sponsoring_contracts_download_open}
|
<div class="flex items-center">
|
||||||
<div
|
<div class="ml-4">
|
||||||
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
|
<div class="text-sm font-medium text-gray-900">
|
||||||
id="sponsoring:dropdown:menu">
|
{#if o.address.address1 !== null}
|
||||||
<div
|
{o.address.address1}<br />
|
||||||
class="py-1"
|
{o.address.address2 || ''}<br />
|
||||||
role="menu"
|
{o.address.postalcode}
|
||||||
aria-orientation="vertical"
|
{o.address.city}
|
||||||
aria-labelledby="options-menu">
|
{o.address.country}
|
||||||
<span
|
{/if}
|
||||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
</div>
|
||||||
<button
|
</div>
|
||||||
on:click={() => {
|
</div>
|
||||||
generateSponsoringContract('de');
|
</td>
|
||||||
}}
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
type="submit"
|
<div class="flex items-center">
|
||||||
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 inline-flex"
|
<div class="ml-4">
|
||||||
role="menuitem">
|
<div class="text-sm font-medium text-gray-900">
|
||||||
{$_('german')}
|
{#if o.contact}
|
||||||
</button>
|
<a
|
||||||
<button
|
href="../contacts/{o.contact.id}"
|
||||||
on:click={() => {
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{o.contact.firstname}
|
||||||
generateSponsoringContract('en');
|
{o.contact.middlename || ''}
|
||||||
}}
|
{o.contact.lastname}</a>
|
||||||
type="submit"
|
{:else}{$_('no-contact-specified')}{/if}
|
||||||
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 inline-flex"
|
</div>
|
||||||
role="menuitem">
|
</div>
|
||||||
{$_('english')}
|
</div>
|
||||||
</button>
|
</td>
|
||||||
</div>
|
{#if active_deletes[o.id] === true}
|
||||||
</div>
|
<td
|
||||||
{/if}
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
</div>
|
<button
|
||||||
{/if}
|
on:click={() => {
|
||||||
</div>
|
active_deletes[o.id] = false;
|
||||||
<div
|
}}
|
||||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
tabindex="0"
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
||||||
<thead class="bg-gray-50">
|
<button
|
||||||
<tr>
|
on:click={() => {
|
||||||
<th
|
RunnerOrganizationService.runnerOrganizationControllerRemove(o.id, false)
|
||||||
scope="col"
|
.then((resp) => {
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
current_organizations = current_organizations.filter((obj) => obj.id !== o.id);
|
||||||
<span
|
Toastify({
|
||||||
on:click={() => {
|
text: 'Organization deleted',
|
||||||
const newstate = !current_organizations.some((r) => r.is_selected === true);
|
duration: 500,
|
||||||
current_organizations = current_organizations.map((r) => {
|
backgroundColor:
|
||||||
r.is_selected = newstate;
|
'linear-gradient(to right, #00b09b, #96c93d)',
|
||||||
return r;
|
}).showToast();
|
||||||
});
|
})
|
||||||
}}
|
.catch((err) => {
|
||||||
class="underline cursor-pointer select-none">{#if current_organizations.some((r) => r.is_selected === true)}
|
modal_open = true;
|
||||||
{$_('deselect-all')}
|
delete_org = o;
|
||||||
{:else}{$_('select-all')}{/if}
|
});
|
||||||
</span>
|
}}
|
||||||
</th>
|
tabindex="0"
|
||||||
<th
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||||
scope="col"
|
</td>
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
{:else}
|
||||||
{$_('name')}
|
<td
|
||||||
</th>
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
<th
|
<a
|
||||||
scope="col"
|
href="./{o.id}"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
||||||
{$_('address')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:DELETE')}
|
||||||
</th>
|
<button
|
||||||
<th
|
on:click={() => {
|
||||||
scope="col"
|
active_deletes[o.id] = true;
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
}}
|
||||||
{$_('contact')}
|
tabindex="0"
|
||||||
</th>
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||||
<th scope="col" class="relative px-6 py-3">
|
{/if}
|
||||||
<span class="sr-only">{$_('action')}</span>
|
</td>
|
||||||
</th>
|
{/if}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{/if}
|
||||||
<tbody class="divide-y divide-gray-200">
|
{/each}
|
||||||
{#each current_organizations as o}
|
</tbody>
|
||||||
{#if Object.values(o)
|
</table>
|
||||||
.toString()
|
</div>
|
||||||
.toLowerCase()
|
{/if}
|
||||||
.includes(searchvalue)}
|
{:catch error}
|
||||||
<tr data-rowid="org_{o.id}">
|
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<span class="inline-block align-middle mr-8">
|
||||||
<input
|
<b class="capitalize">{$_('general_promise_error')}</b>
|
||||||
bind:checked={o.is_selected}
|
{error}
|
||||||
type="checkbox"
|
</span>
|
||||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
</div>
|
||||||
</td>
|
{/await}
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
{/if}
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="ml-4">
|
|
||||||
<div class="text-sm font-medium text-gray-900">
|
|
||||||
{o.name}
|
|
||||||
</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">
|
|
||||||
{#if o.address.address1 !== null}
|
|
||||||
{o.address.address1}<br />
|
|
||||||
{o.address.address2 || ''}<br />
|
|
||||||
{o.address.postalcode}
|
|
||||||
{o.address.city}
|
|
||||||
{o.address.country}
|
|
||||||
{/if}
|
|
||||||
</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">
|
|
||||||
{#if o.contact}
|
|
||||||
<a
|
|
||||||
href="../contacts/{o.contact.id}"
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{o.contact.firstname}
|
|
||||||
{o.contact.middlename || ''}
|
|
||||||
{o.contact.lastname}</a>
|
|
||||||
{:else}{$_('no-contact-specified')}{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
{#if active_deletes[o.id] === true}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[o.id] = false;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
RunnerOrganizationService.runnerOrganizationControllerRemove(o.id, false)
|
|
||||||
.then((resp) => {
|
|
||||||
current_organizations = current_organizations.filter((obj) => obj.id !== o.id);
|
|
||||||
Toastify({
|
|
||||||
text: 'Organization deleted',
|
|
||||||
duration: 500,
|
|
||||||
backgroundColor:
|
|
||||||
'linear-gradient(to right, #00b09b, #96c93d)',
|
|
||||||
}).showToast();
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
modal_open = true;
|
|
||||||
delete_org = o;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
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="./{o.id}"
|
|
||||||
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:DELETE')}
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[o.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,418 @@
|
|||||||
|
<script>
|
||||||
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
|
import {
|
||||||
|
RunnerCardService,
|
||||||
|
RunnerOrganizationService,
|
||||||
|
RunnerTeamService,
|
||||||
|
} 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 cards_show = 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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function generateRunnerCards(locale) {
|
||||||
|
cards_dropdown_open = false;
|
||||||
|
|
||||||
|
if (generate_orgs.length > 0) {
|
||||||
|
generateOrgCards(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 {
|
||||||
|
return response.blob();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((blob) => {
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
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();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateRunnersCards(locale) {
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("generating-pdf"),
|
||||||
|
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();
|
||||||
|
})
|
||||||
|
.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 = [];
|
||||||
|
for (let runner of runners) {
|
||||||
|
let card = current_cards.find((c) => c.runner?.id == runner.id);
|
||||||
|
if (!card) {
|
||||||
|
card = await RunnerCardService.runnerCardControllerPost({
|
||||||
|
runner: runner.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
cards.push(card);
|
||||||
|
}
|
||||||
|
await fetch(
|
||||||
|
`${config.baseurl_documentserver}/cards?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(cards),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status != "200") {
|
||||||
|
toast.hideToast();
|
||||||
|
Toastify({
|
||||||
|
text: $_("pdf-generation-failed"),
|
||||||
|
duration: 3500,
|
||||||
|
backgroundColor:
|
||||||
|
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
||||||
|
}).showToast();
|
||||||
|
} else {
|
||||||
|
return response.blob();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((blob) => {
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
a.download = `${$_("runnercards")}_${o.name}_${
|
||||||
|
t.name
|
||||||
|
}-${locale}-${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 cards_show}
|
||||||
|
<div id="cards:dropdown" class="relative inline-block">
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
cards_dropdown_open = !cards_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-runnercards")}
|
||||||
|
<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 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}
|
||||||
@@ -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}
|
||||||
@@ -0,0 +1,324 @@
|
|||||||
|
<script>
|
||||||
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
|
import {
|
||||||
|
RunnerOrganizationService,
|
||||||
|
RunnerTeamService,
|
||||||
|
} 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 sponsoring_contracts_show = false;
|
||||||
|
export let generate_runners = [];
|
||||||
|
export let generate_orgs = [];
|
||||||
|
export let generate_teams = [];
|
||||||
|
$: sponsoring_contracts_download_open = false;
|
||||||
|
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) {
|
||||||
|
sponsoring_contracts_download_open = false;
|
||||||
|
|
||||||
|
if (generate_orgs.length > 0) {
|
||||||
|
generateOrgContracts(locale);
|
||||||
|
} else if (generate_teams.length > 0) {
|
||||||
|
generateTeamContracts(locale);
|
||||||
|
} else {
|
||||||
|
generateRunnerContracts(locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateTeamContracts(locale) {
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("generating-pdfs"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
let count = 0;
|
||||||
|
for (const t of generate_teams) {
|
||||||
|
count++;
|
||||||
|
const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
|
||||||
|
t.id
|
||||||
|
);
|
||||||
|
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")}_${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 generateOrgContracts(locale) {
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("generating-pdf"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
let count_orgs = 0;
|
||||||
|
for (const o of generate_orgs) {
|
||||||
|
count_orgs++;
|
||||||
|
let count = 0;
|
||||||
|
let runners =
|
||||||
|
await RunnerOrganizationService.runnerOrganizationControllerGetRunners(
|
||||||
|
o.id,
|
||||||
|
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) => {
|
||||||
|
if (response.status != "200") {
|
||||||
|
toast.hideToast();
|
||||||
|
Toastify({
|
||||||
|
text: $_("pdf-generation-failed"),
|
||||||
|
duration: 3500,
|
||||||
|
backgroundColor:
|
||||||
|
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
||||||
|
}).showToast();
|
||||||
|
} else {
|
||||||
|
return response.blob();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((blob) => {
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
a.download = `${$_("sponsorings")}_${o.name}_${
|
||||||
|
t.name
|
||||||
|
}-${locale}-${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) => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
{#if sponsoring_contracts_show}
|
||||||
|
<div id="sponsoring:dropdown" class="relative inline-block">
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
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"
|
||||||
|
id="options-menu"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-expanded="true"
|
||||||
|
>
|
||||||
|
{$_("generate-sponsoring-contracts")}
|
||||||
|
<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 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}
|
||||||
@@ -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'}
|
||||||
|
|||||||
@@ -1,398 +1,321 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
import store from "../../store";
|
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
|
||||||
import {
|
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
|
||||||
RunnerService,
|
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
|
||||||
RunnerTeamService,
|
import store from "../../store";
|
||||||
RunnerOrganizationService,
|
import {
|
||||||
} from "@odit/lfk-client-js";
|
RunnerService,
|
||||||
import Toastify from "toastify-js";
|
RunnerTeamService,
|
||||||
import PromiseError from "../base/PromiseError.svelte";
|
RunnerOrganizationService,
|
||||||
import isEmail from "validator/es/lib/isEmail";
|
} from "@odit/lfk-client-js";
|
||||||
import Select from "svelte-select";
|
import Toastify from "toastify-js";
|
||||||
let data_loaded = false;
|
import PromiseError from "../base/PromiseError.svelte";
|
||||||
export let params;
|
import isEmail from "validator/es/lib/isEmail";
|
||||||
const runner_promise = RunnerService.runnerControllerGetOne(params.runnerid);
|
import Select from "svelte-select";
|
||||||
$: delete_triggered = false;
|
let data_loaded = false;
|
||||||
$: sponsoring_contracts_download_open = false;
|
export let params;
|
||||||
$: original_data_pdf = {};
|
const runner_promise = RunnerService.runnerControllerGetOne(params.runnerid);
|
||||||
$: original_data = {};
|
$: delete_triggered = false;
|
||||||
$: editable = {};
|
$: original_data_pdf = {};
|
||||||
$: group = {}
|
$: original_data = {};
|
||||||
$: changes_performed = !(JSON.stringify(original_data) == JSON.stringify(editable));
|
$: editable = {};
|
||||||
$: isEmailValid =
|
$: group = {};
|
||||||
(editable.email || "") === "" ||
|
$: changes_performed = !(
|
||||||
(editable.email && isEmail(editable.email || ""));
|
JSON.stringify(original_data) == JSON.stringify(editable)
|
||||||
$: isFirstnameValid = editable.firstname !== "";
|
);
|
||||||
$: isLastnameValid = editable.lastname !== "";
|
$: isEmailValid =
|
||||||
$: save_enabled =
|
(editable.email || "") === "" ||
|
||||||
changes_performed &&
|
(editable.email && isEmail(editable.email || ""));
|
||||||
isFirstnameValid &&
|
$: isFirstnameValid = editable.firstname !== "";
|
||||||
isLastnameValid &&
|
$: isLastnameValid = editable.lastname !== "";
|
||||||
isEmailValid &&
|
$: save_enabled =
|
||||||
editable.group != null;
|
changes_performed &&
|
||||||
runner_promise.then((data) => {
|
isFirstnameValid &&
|
||||||
data_loaded = true;
|
isLastnameValid &&
|
||||||
original_data_pdf = Object.assign(original_data_pdf, data);
|
isEmailValid &&
|
||||||
data.group = data.group.id;
|
editable.group != null;
|
||||||
original_data = Object.assign(original_data, data);
|
$: sponsoring_contracts_show = true;
|
||||||
editable = Object.assign(editable, original_data);
|
$: cards_show = true;
|
||||||
|
$: certificates_show = true;
|
||||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
$: generate_runners = [original_data_pdf];
|
||||||
const orgs = val.map((r) => {
|
runner_promise.then((data) => {
|
||||||
return { label: r.name, value: r };
|
data_loaded = true;
|
||||||
});
|
original_data_pdf = Object.assign(original_data_pdf, data);
|
||||||
groups = groups.concat(orgs);
|
data.group = data.group.id;
|
||||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
original_data = Object.assign(original_data, data);
|
||||||
const teams = val.map((r) => {
|
editable = Object.assign(editable, original_data);
|
||||||
return { label: `${r.parentGroup.name} > ${r.name}`, value: r };
|
|
||||||
});
|
RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
|
||||||
groups = groups.concat(teams);
|
(val) => {
|
||||||
group = groups.find(g => g.value.id == editable.group)
|
const orgs = val.map((r) => {
|
||||||
});
|
return { label: r.name, value: r };
|
||||||
});
|
});
|
||||||
});
|
groups = groups.concat(orgs);
|
||||||
document.addEventListener("click", function (e) {
|
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||||
if (
|
const teams = val.map((r) => {
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
return { label: `${r.parentGroup.name} > ${r.name}`, value: r };
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
});
|
||||||
) {
|
groups = groups.concat(teams);
|
||||||
sponsoring_contracts_download_open = false;
|
group = groups.find((g) => g.value.id == editable.group);
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
let groups = [];
|
);
|
||||||
function submit() {
|
});
|
||||||
if (data_loaded === true && save_enabled) {
|
let groups = [];
|
||||||
Toastify({
|
function submit() {
|
||||||
text: $_("updating-runner"),
|
if (data_loaded === true && save_enabled) {
|
||||||
duration: 2500,
|
Toastify({
|
||||||
}).showToast();
|
text: $_("updating-runner"),
|
||||||
let postdata = {};
|
duration: 2500,
|
||||||
postdata = Object.assign(postdata, editable);
|
}).showToast();
|
||||||
RunnerService.runnerControllerPut(original_data.id, postdata)
|
let postdata = {};
|
||||||
.then((resp) => {
|
postdata = Object.assign(postdata, editable);
|
||||||
Object.assign(original_data, editable);
|
if (postdata.phone === "") {
|
||||||
original_data = original_data;
|
postdata.phone = null;
|
||||||
Toastify({
|
}
|
||||||
text: $_("runner-updated"),
|
RunnerService.runnerControllerPut(original_data.id, postdata)
|
||||||
duration: 2500,
|
.then((resp) => {
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
Object.assign(original_data, editable);
|
||||||
}).showToast();
|
original_data = original_data;
|
||||||
})
|
Toastify({
|
||||||
.catch((err) => {});
|
text: $_("runner-updated"),
|
||||||
} else {
|
duration: 2500,
|
||||||
}
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}
|
}).showToast();
|
||||||
function deleteRunner() {
|
})
|
||||||
RunnerService.runnerControllerRemove(original_data.id, true)
|
.catch((err) => {});
|
||||||
.then((resp) => {
|
} else {
|
||||||
location.replace("./");
|
}
|
||||||
})
|
}
|
||||||
.catch((err) => {});
|
function deleteRunner() {
|
||||||
}
|
RunnerService.runnerControllerRemove(original_data.id, true)
|
||||||
function generateSponsoringContract(locale) {
|
.then((resp) => {
|
||||||
sponsoring_contracts_download_open = false;
|
location.replace("./");
|
||||||
const toast = Toastify({
|
})
|
||||||
text: $_("generating-pdf"),
|
.catch((err) => {});
|
||||||
duration: -1,
|
}
|
||||||
}).showToast();
|
</script>
|
||||||
fetch(
|
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
{#await runner_promise}
|
||||||
{
|
{$_("loading-runners")}
|
||||||
method: "POST",
|
{:then}
|
||||||
headers: {
|
<section class="container p-5 select-none">
|
||||||
"Content-Type": "application/json",
|
<div class="flex flex-row mb-4">
|
||||||
},
|
<div class="w-full">
|
||||||
body: JSON.stringify([original_data_pdf]),
|
<nav class="w-full flex">
|
||||||
}
|
<ol class="list-none flex flex-row items-center justify-start">
|
||||||
)
|
<li class="flex items-center">
|
||||||
.then((response) => {
|
<svg
|
||||||
if (response.status != "200") {
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
toast.hideToast();
|
viewBox="0 0 24 24"
|
||||||
Toastify({
|
class="flex-shrink-0 w-5 h-5 mr-2"
|
||||||
text: $_("pdf-generation-failed"),
|
fill="currentColor"
|
||||||
duration: 3500,
|
width="24"
|
||||||
backgroundColor:
|
height="24"
|
||||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
><path fill="none" d="M0 0h24v24H0z" />
|
||||||
}).showToast();
|
<path
|
||||||
} else {
|
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"
|
||||||
return response.blob();
|
/></svg
|
||||||
}
|
>
|
||||||
})
|
</li>
|
||||||
.then((blob) => {
|
<li class="flex items-center">
|
||||||
const url = window.URL.createObjectURL(blob);
|
<a class="mr-2" href="./">{$_("runners")}</a><svg
|
||||||
let a = document.createElement("a");
|
stroke="currentColor"
|
||||||
a.href = url;
|
fill="none"
|
||||||
a.download =
|
stroke-width="2"
|
||||||
"Sponsoring_" +
|
viewBox="0 0 24 24"
|
||||||
original_data.firstname +
|
stroke-linecap="round"
|
||||||
(original_data.middlename || "") +
|
stroke-linejoin="round"
|
||||||
original_data.lastname +
|
class="h-3 w-3 mr-2 stroke-current"
|
||||||
".pdf";
|
height="1em"
|
||||||
document.body.appendChild(a);
|
width="1em"
|
||||||
a.click();
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
a.remove();
|
><line x1="5" y1="12" x2="19" y2="12" />
|
||||||
toast.hideToast();
|
<polyline points="12 5 19 12 12 19" /></svg
|
||||||
Toastify({
|
>
|
||||||
text: $_("pdf-successfully-generated"),
|
</li>
|
||||||
duration: 3500,
|
<li class="flex items-center">
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
<span class="mr-2"
|
||||||
}).showToast();
|
>{original_data.firstname}
|
||||||
})
|
{original_data.middlename || ""}
|
||||||
.catch((err) => {
|
{original_data.lastname}</span
|
||||||
console.error(err);
|
>
|
||||||
});
|
</li>
|
||||||
}
|
</ol>
|
||||||
</script>
|
</nav>
|
||||||
|
</div>
|
||||||
{#await runner_promise}
|
</div>
|
||||||
{$_('loading-runners')}
|
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||||
{:then}
|
{original_data.firstname}
|
||||||
<section class="container p-5 select-none">
|
{original_data.middlename || ""}
|
||||||
<div class="flex flex-row mb-4">
|
{original_data.lastname}
|
||||||
<div class="w-full">
|
<span data-id="runner_actions_${editable.id}">
|
||||||
<nav class="w-full flex">
|
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:DELETE")}
|
||||||
<ol class="list-none flex flex-row items-center justify-start">
|
{#if delete_triggered}
|
||||||
<li class="flex items-center">
|
<button
|
||||||
<svg
|
on:click={deleteRunner}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
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"
|
||||||
viewBox="0 0 24 24"
|
>{$_("confirm-deletion")}</button
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2"
|
>
|
||||||
fill="currentColor"
|
<button
|
||||||
width="24"
|
on:click={() => {
|
||||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
delete_triggered = !delete_triggered;
|
||||||
<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>
|
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"
|
||||||
</li>
|
>{$_("cancel")}</button
|
||||||
<li class="flex items-center">
|
>
|
||||||
<a class="mr-2" href="./">{$_('runners')}</a><svg
|
{/if}
|
||||||
stroke="currentColor"
|
<GenerateSponsoringContracts
|
||||||
fill="none"
|
bind:sponsoring_contracts_show
|
||||||
stroke-width="2"
|
bind:generate_runners
|
||||||
viewBox="0 0 24 24"
|
/>
|
||||||
stroke-linecap="round"
|
<GenerateRunnerCards bind:cards_show bind:generate_runners />
|
||||||
stroke-linejoin="round"
|
<GenerateRunnerCertificates
|
||||||
class="h-3 w-3 mr-2 stroke-current"
|
bind:certificates_show
|
||||||
height="1em"
|
bind:generate_runners
|
||||||
width="1em"
|
/>
|
||||||
xmlns="http://www.w3.org/2000/svg"><line
|
{#if !delete_triggered}
|
||||||
x1="5"
|
<button
|
||||||
y1="12"
|
on:click={() => {
|
||||||
x2="19"
|
delete_triggered = true;
|
||||||
y2="12" />
|
}}
|
||||||
<polyline points="12 5 19 12 12 19" /></svg>
|
type="button"
|
||||||
</li>
|
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"
|
||||||
<li class="flex items-center">
|
>{$_("delete-runner")}</button
|
||||||
<span class="mr-2">{original_data.firstname}
|
>
|
||||||
{original_data.middlename || ''}
|
{/if}
|
||||||
{original_data.lastname}</span>
|
{/if}
|
||||||
</li>
|
{#if !delete_triggered}
|
||||||
</ol>
|
<button
|
||||||
</nav>
|
disabled={!save_enabled}
|
||||||
</div>
|
class:opacity-50={!save_enabled}
|
||||||
</div>
|
type="button"
|
||||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
on:click={submit}
|
||||||
{original_data.firstname}
|
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"
|
||||||
{original_data.middlename || ''}
|
>{$_("save-changes")}</button
|
||||||
{original_data.lastname}
|
>
|
||||||
<span data-id="runner_actions_${editable.id}">
|
{/if}
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
|
</span>
|
||||||
{#if delete_triggered}
|
</div>
|
||||||
<button
|
<!-- -->
|
||||||
on:click={deleteRunner}
|
<div class="text-sm w-full">
|
||||||
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>
|
<label for="firstname" class="font-medium text-gray-700"
|
||||||
<button
|
>{$_("first-name")}</label
|
||||||
on:click={() => {
|
>
|
||||||
delete_triggered = !delete_triggered;
|
<input
|
||||||
}}
|
autocomplete="off"
|
||||||
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>
|
placeholder={$_("first-name")}
|
||||||
{/if}
|
type="text"
|
||||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
class:border-red-500={!isFirstnameValid}
|
||||||
<div>
|
class:focus:border-red-500={!isFirstnameValid}
|
||||||
<button
|
class:focus:ring-red-500={!isFirstnameValid}
|
||||||
on:click={() => {
|
bind:value={editable.firstname}
|
||||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
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"
|
||||||
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"
|
{#if !isFirstnameValid}
|
||||||
id="options-menu"
|
<span
|
||||||
aria-haspopup="true"
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
|
||||||
aria-expanded="true">
|
>
|
||||||
{$_('generate-sponsoring-contract')}
|
{$_("first-name-is-required")}
|
||||||
<svg
|
</span>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
{/if}
|
||||||
width="24"
|
</div>
|
||||||
height="24"
|
<div class="text-sm w-full">
|
||||||
viewBox="0 0 24 24"
|
<label for="middlename" class="font-medium text-gray-700"
|
||||||
class="-mr-1 ml-2 h-5 w-5"><path
|
>{$_("middle-name")}</label
|
||||||
fill="none"
|
>
|
||||||
d="M0 0h24v24H0z" />
|
<input
|
||||||
<path
|
autocomplete="off"
|
||||||
fill="currentColor"
|
placeholder={$_("middle-name")}
|
||||||
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>
|
type="text"
|
||||||
</button>
|
bind:value={editable.middlename}
|
||||||
</div>
|
name="middlename"
|
||||||
{#if sponsoring_contracts_download_open}
|
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
|
/>
|
||||||
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
|
</div>
|
||||||
id="sponsoring:dropdown:menu">
|
<div class="text-sm w-full">
|
||||||
<div
|
<label for="lastname" class="font-medium text-gray-700"
|
||||||
class="py-1"
|
>{$_("last-name")}</label
|
||||||
role="menu"
|
>
|
||||||
aria-orientation="vertical"
|
<input
|
||||||
aria-labelledby="options-menu">
|
autocomplete="off"
|
||||||
<span
|
placeholder={$_("last-name")}
|
||||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
type="text"
|
||||||
<button
|
bind:value={editable.lastname}
|
||||||
on:click={() => {
|
class:border-red-500={!isLastnameValid}
|
||||||
generateSponsoringContract('de');
|
class:focus:border-red-500={!isLastnameValid}
|
||||||
}}
|
class:focus:ring-red-500={!isLastnameValid}
|
||||||
type="submit"
|
name="lastname"
|
||||||
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 inline-flex"
|
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"
|
||||||
role="menuitem">
|
/>
|
||||||
{$_('german')}
|
{#if !isLastnameValid}
|
||||||
</button>
|
<span
|
||||||
<button
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
|
||||||
on:click={() => {
|
>
|
||||||
generateSponsoringContract('en');
|
{$_("last-name-is-required")}
|
||||||
}}
|
</span>
|
||||||
type="submit"
|
{/if}
|
||||||
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 inline-flex"
|
</div>
|
||||||
role="menuitem">
|
<div class="text-sm w-full">
|
||||||
{$_('english')}
|
<label for="email" class="font-medium text-gray-700"
|
||||||
</button>
|
>{$_("e-mail-adress")}</label
|
||||||
</div>
|
>
|
||||||
</div>
|
<input
|
||||||
{/if}
|
autocomplete="off"
|
||||||
</div>
|
placeholder={$_("e-mail-adress")}
|
||||||
{#if !delete_triggered}
|
type="email"
|
||||||
<button
|
bind:value={editable.email}
|
||||||
on:click={() => {
|
class:border-red-500={!isEmailValid}
|
||||||
delete_triggered = true;
|
class:focus:border-red-500={!isEmailValid}
|
||||||
}}
|
class:focus:ring-red-500={!isEmailValid}
|
||||||
type="button"
|
name="email"
|
||||||
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="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}
|
/>
|
||||||
{/if}
|
{#if !isEmailValid}
|
||||||
{#if !delete_triggered}
|
<span
|
||||||
<button
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
|
||||||
disabled={!save_enabled}
|
>
|
||||||
class:opacity-50={!save_enabled}
|
{$_("valid-email-is-required")}
|
||||||
type="button"
|
</span>
|
||||||
on:click={submit}
|
{/if}
|
||||||
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>
|
</div>
|
||||||
{/if}
|
<div class="text-sm w-full">
|
||||||
</span>
|
<label for="phone" class="font-medium text-gray-700">{$_("phone")}</label>
|
||||||
</div>
|
<input
|
||||||
<!-- -->
|
autocomplete="off"
|
||||||
<div class="text-sm w-full">
|
placeholder={$_("phone")}
|
||||||
<label
|
type="tel"
|
||||||
for="firstname"
|
bind:value={editable.phone}
|
||||||
class="font-medium text-gray-700">{$_('first-name')}</label>
|
name="phone"
|
||||||
<input
|
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"
|
||||||
autocomplete="off"
|
/>
|
||||||
placeholder={$_('first-name')}
|
</div>
|
||||||
type="text"
|
<div class="text-sm w-full">
|
||||||
class:border-red-500={!isFirstnameValid}
|
<span class="font-medium text-gray-700">{$_("group")}</span>
|
||||||
class:focus:border-red-500={!isFirstnameValid}
|
<Select
|
||||||
class:focus:ring-red-500={!isFirstnameValid}
|
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"
|
||||||
bind:value={editable.firstname}
|
itemFilter={(label, filterText, option) =>
|
||||||
name="firstname"
|
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||||
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" />
|
option.id.value.toString().startsWith(filterText.toLowerCase())}
|
||||||
{#if !isFirstnameValid}
|
items={groups}
|
||||||
<span
|
showChevron={true}
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
placeholder={$_("search-for-an-organization-or-team-by-name-or-id")}
|
||||||
{$_('first-name-is-required')}
|
noOptionsMessage={$_("no-organization-or-team-found")}
|
||||||
</span>
|
bind:selectedValue={group}
|
||||||
{/if}
|
on:select={(selectedValue) => {
|
||||||
</div>
|
editable.group = selectedValue.detail.value.id;
|
||||||
<div class="text-sm w-full">
|
}}
|
||||||
<label
|
on:clear={() => (editable.group = null)}
|
||||||
for="middlename"
|
/>
|
||||||
class="font-medium text-gray-700">{$_('middle-name')}</label>
|
</div>
|
||||||
<input
|
<div class="text-sm w-full">
|
||||||
autocomplete="off"
|
<span class="font-medium text-gray-700">{$_("distance")}</span>
|
||||||
placeholder={$_('middle-name')}
|
<br />
|
||||||
type="text"
|
<span class="text-gray-700">{original_data.distance / 1000} km</span>
|
||||||
bind:value={editable.middlename}
|
</div>
|
||||||
name="middlename"
|
</section>
|
||||||
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" />
|
{:catch error}
|
||||||
</div>
|
<PromiseError {error} />
|
||||||
<div class="text-sm w-full">
|
{/await}
|
||||||
<label
|
|
||||||
for="lastname"
|
|
||||||
class="font-medium text-gray-700">{$_('last-name')}</label>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
placeholder={$_('last-name')}
|
|
||||||
type="text"
|
|
||||||
bind:value={editable.lastname}
|
|
||||||
class:border-red-500={!isLastnameValid}
|
|
||||||
class:focus:border-red-500={!isLastnameValid}
|
|
||||||
class:focus:ring-red-500={!isLastnameValid}
|
|
||||||
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" />
|
|
||||||
{#if !isLastnameValid}
|
|
||||||
<span
|
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
|
||||||
{$_('last-name-is-required')}
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="text-sm w-full">
|
|
||||||
<label
|
|
||||||
for="email"
|
|
||||||
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
placeholder={$_('e-mail-adress')}
|
|
||||||
type="email"
|
|
||||||
bind:value={editable.email}
|
|
||||||
class:border-red-500={!isEmailValid}
|
|
||||||
class:focus:border-red-500={!isEmailValid}
|
|
||||||
class:focus:ring-red-500={!isEmailValid}
|
|
||||||
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" />
|
|
||||||
{#if !isEmailValid}
|
|
||||||
<span
|
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
|
||||||
{$_('valid-email-is-required')}
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="text-sm w-full">
|
|
||||||
<label for="phone" class="font-medium text-gray-700">{$_('phone')}</label>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
placeholder={$_('phone')}
|
|
||||||
type="tel"
|
|
||||||
bind:value={editable.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" />
|
|
||||||
</div>
|
|
||||||
<div class="text-sm w-full">
|
|
||||||
<span class="font-medium text-gray-700">{$_('group')}</span>
|
|
||||||
<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"
|
|
||||||
itemFilter={(label, filterText, option) => label
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
filterText.toLowerCase()
|
|
||||||
) || option.id.value.toString().startsWith(filterText.toLowerCase())}
|
|
||||||
items={groups}
|
|
||||||
showChevron={true}
|
|
||||||
placeholder={$_('search-for-an-organization-or-team-by-name-or-id')}
|
|
||||||
noOptionsMessage={$_('no-organization-or-team-found')}
|
|
||||||
bind:selectedValue={group}
|
|
||||||
on:select={(selectedValue) => {editable.group = selectedValue.detail.value.id}}
|
|
||||||
on:clear={() => (editable.group = null)} />
|
|
||||||
</div>
|
|
||||||
<div class="text-sm w-full">
|
|
||||||
<span class="font-medium text-gray-700">{$_('distance')}</span>
|
|
||||||
<br />
|
|
||||||
<span class="text-gray-700">{original_data.distance} km</span>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{:catch error}
|
|
||||||
<PromiseError {error} />
|
|
||||||
{/await}
|
|
||||||
@@ -1,360 +1,331 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import {
|
let tablePageCount = [25, 50, 100, 250, 500];
|
||||||
RunnerService,
|
import { writable } from "svelte/store";
|
||||||
RunnerTeamService,
|
import {
|
||||||
RunnerOrganizationService,
|
createSvelteTable,
|
||||||
} from "@odit/lfk-client-js";
|
flexRender,
|
||||||
import store from "../../store";
|
getCoreRowModel,
|
||||||
import RunnersEmptyState from "./RunnersEmptyState.svelte";
|
getFilteredRowModel,
|
||||||
import Select from "svelte-select";
|
getPaginationRowModel,
|
||||||
import Toastify from "toastify-js";
|
getSortedRowModel,
|
||||||
$: searchvalue = "";
|
} from "@tanstack/svelte-table";
|
||||||
$: active_deletes = [];
|
import {
|
||||||
export let current_runners = [];
|
RunnerService,
|
||||||
const runners_promise = RunnerService.runnerControllerGetAll().then((val) => {
|
RunnerTeamService,
|
||||||
current_runners = val;
|
RunnerOrganizationService,
|
||||||
});
|
} from "@odit/lfk-client-js";
|
||||||
$: selectedFilter_teams = null;
|
import store from "../../store";
|
||||||
$: selectedFilter = null;
|
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
|
||||||
$: filter__teams = selectedFilter_teams || [];
|
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
|
||||||
$: filter__orgs = selectedFilter || [];
|
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
|
||||||
$: filterGroupIDs = filter__teams.concat(filter__orgs).map((i) => i.value);
|
import { onMount } from "svelte";
|
||||||
$: sponsoring_contracts_download_open = false;
|
import InputElement from "../shared/InputElement.svelte";
|
||||||
$: teams = [];
|
import { groupFilter } from "../shared/tablefilters";
|
||||||
$: orgs = [];
|
|
||||||
$: mappedteams = teams.map(function (g) {
|
$: selectedRunners =
|
||||||
return { value: g.id, label: g.parentGroup.name + " > " + g.name };
|
$table?.getSelectedRowModel().rows.map((row) => row.original) || [];
|
||||||
});
|
$: selected =
|
||||||
$: selectgroups = orgs
|
$table?.getSelectedRowModel().rows.map((row) => row.index) || [];
|
||||||
.map(function (g) {
|
|
||||||
return { value: g.id, label: g.name };
|
const columns = [
|
||||||
})
|
{
|
||||||
.concat(mappedteams);
|
accessorKey: "id",
|
||||||
document.addEventListener("click", function (e) {
|
header: () => "id",
|
||||||
if (
|
filterFn: `equalsString`,
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
},
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
{
|
||||||
) {
|
accessorKey: "firstname",
|
||||||
sponsoring_contracts_download_open = false;
|
header: () => $_("first-name"),
|
||||||
}
|
filterFn: `includesString`,
|
||||||
});
|
},
|
||||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
{
|
||||||
teams = val;
|
accessorKey: "lastname",
|
||||||
});
|
header: () => $_("last-name"),
|
||||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
filterFn: `includesString`,
|
||||||
orgs = val;
|
},
|
||||||
});
|
{
|
||||||
function should_display_based_on_id(id) {
|
accessorKey: "group",
|
||||||
if (searchvalue.toString().slice(-1) === "*") {
|
header: () => $_("group"),
|
||||||
return id.toString().startsWith(searchvalue.replace("*", ""));
|
cell: (info) => {
|
||||||
}
|
const group = info.getValue();
|
||||||
return id.toString() === searchvalue;
|
if (group.responseType === "RUNNERORGANIZATION") {
|
||||||
}
|
return group.name;
|
||||||
function generateSponsoringContract(locale) {
|
}
|
||||||
sponsoring_contracts_download_open = false;
|
return `${group.parentGroup.name} > ${group.name}`;
|
||||||
const toast = Toastify({
|
},
|
||||||
text: $_("generating-pdf"),
|
filterFn: `group`,
|
||||||
duration: -1,
|
},
|
||||||
}).showToast();
|
{
|
||||||
fetch(
|
accessorKey: "distance",
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
header: () => $_("distance"),
|
||||||
{
|
cell: (info) => {
|
||||||
method: "POST",
|
if (info.getValue() < 1000) {
|
||||||
headers: {
|
return `${info.getValue()} m`;
|
||||||
"Content-Type": "application/json",
|
}
|
||||||
},
|
return `${(info.getValue() / 1000).toFixed(1)} km`;
|
||||||
body: JSON.stringify(
|
},
|
||||||
current_runners.filter((r) => r.is_selected === true)
|
enableColumnFilter: false,
|
||||||
),
|
},
|
||||||
}
|
];
|
||||||
)
|
|
||||||
.then((response) => {
|
//
|
||||||
if (response.status != "200") {
|
|
||||||
toast.hideToast();
|
$: active_deletes = [];
|
||||||
Toastify({
|
let dataLoaded = false;
|
||||||
text: $_("pdf-generation-failed"),
|
export let current_runners = [];
|
||||||
duration: 3500,
|
$: sponsoring_contracts_show = selected.length > 0;
|
||||||
backgroundColor:
|
$: cards_show = selected.length > 0;
|
||||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
$: certificates_show = selected.length > 0;
|
||||||
}).showToast();
|
$: teams = [];
|
||||||
} else {
|
$: orgs = [];
|
||||||
return response.blob();
|
$: mappedteams = teams.map(function (g) {
|
||||||
}
|
return { value: g.id, label: g.parentGroup.name + " > " + g.name };
|
||||||
})
|
});
|
||||||
.then((blob) => {
|
$: selectgroups = orgs
|
||||||
const url = window.URL.createObjectURL(blob);
|
.map(function (g) {
|
||||||
let a = document.createElement("a");
|
return { value: g.id, label: g.name };
|
||||||
a.href = url;
|
})
|
||||||
a.download = "Sponsoring.pdf";
|
.concat(mappedteams);
|
||||||
document.body.appendChild(a);
|
const options = writable({
|
||||||
a.click();
|
data: [],
|
||||||
a.remove();
|
columns: columns,
|
||||||
toast.hideToast();
|
filterFns: {
|
||||||
Toastify({
|
group: groupFilter,
|
||||||
text: $_("pdf-successfully-generated"),
|
},
|
||||||
duration: 3500,
|
initialState: {
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
pagination: {
|
||||||
}).showToast();
|
pageSize: 50,
|
||||||
})
|
},
|
||||||
.catch((err) => {
|
},
|
||||||
console.error(err);
|
enableRowSelection: true,
|
||||||
});
|
getCoreRowModel: getCoreRowModel(),
|
||||||
}
|
getFilteredRowModel: getFilteredRowModel(),
|
||||||
</script>
|
getPaginationRowModel: getPaginationRowModel(),
|
||||||
|
getSortedRowModel: getSortedRowModel(),
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')}
|
});
|
||||||
{#await runners_promise}
|
const table = createSvelteTable(options);
|
||||||
<div
|
onMount(() => {
|
||||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
RunnerService.runnerControllerGetAll().then((val) => {
|
||||||
role="alert">
|
current_runners = val;
|
||||||
<p class="font-bold">{$_('runners-are-being-loaded')}</p>
|
dataLoaded = true;
|
||||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
|
||||||
</div>
|
options.update((options) => ({
|
||||||
{:then}
|
...options,
|
||||||
{#if current_runners.length === 0}
|
data: current_runners,
|
||||||
<RunnersEmptyState />
|
}));
|
||||||
{:else}
|
});
|
||||||
<input
|
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||||
type="search"
|
teams = val;
|
||||||
bind:value={searchvalue}
|
});
|
||||||
placeholder={$_('datatable.search')}
|
RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
|
||||||
aria-label={$_('datatable.search')}
|
(val) => {
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
orgs = val;
|
||||||
<div class="block mb-6">
|
}
|
||||||
<label
|
);
|
||||||
for="country"
|
});
|
||||||
class="text-sm font-medium text-gray-700">{$_('filter-by-organization-team')}</label>
|
</script>
|
||||||
<Select
|
|
||||||
on:select={(event) => {
|
{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:GET")}
|
||||||
selectedFilter = event.detail;
|
{#if !dataLoaded}
|
||||||
}}
|
<div
|
||||||
selectedValue={selectedFilter}
|
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||||
placeholder={$_('filter-by-organization-team')}
|
role="alert"
|
||||||
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"
|
>
|
||||||
items={selectgroups}
|
<p class="font-bold">{$_("runners-are-being-loaded")}</p>
|
||||||
isMulti={true} />
|
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-12">
|
{:else}
|
||||||
{#if current_runners.some((r) => r.is_selected === true)}
|
<div class="h-12 mt-2">
|
||||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
<GenerateSponsoringContracts
|
||||||
<div>
|
bind:sponsoring_contracts_show
|
||||||
<button
|
bind:generate_runners={selectedRunners}
|
||||||
on:click={() => {
|
/>
|
||||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
<GenerateRunnerCards
|
||||||
}}
|
bind:cards_show
|
||||||
type="button"
|
bind:generate_runners={selectedRunners}
|
||||||
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"
|
<GenerateRunnerCertificates
|
||||||
aria-haspopup="true"
|
bind:certificates_show
|
||||||
aria-expanded="true">
|
bind:generate_runners={selectedRunners}
|
||||||
{$_('generate-sponsoring-contracts')}
|
/>
|
||||||
<svg
|
</div>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<table class="w-full">
|
||||||
width="24"
|
<thead>
|
||||||
height="24"
|
{#each $table.getHeaderGroups() as headerGroup}
|
||||||
viewBox="0 0 24 24"
|
<tr class="select-none">
|
||||||
class="-mr-1 ml-2 h-5 w-5"><path
|
<th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
|
||||||
fill="none"
|
<InputElement
|
||||||
d="M0 0h24v24H0z" />
|
type="checkbox"
|
||||||
<path
|
checked={$table.getIsAllRowsSelected()}
|
||||||
fill="currentColor"
|
indeterminate={$table.getIsSomeRowsSelected()}
|
||||||
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>
|
on:change={() => $table.toggleAllRowsSelected()}
|
||||||
</button>
|
/>
|
||||||
</div>
|
</th>
|
||||||
{#if sponsoring_contracts_download_open}
|
{#each headerGroup.headers as header}
|
||||||
<div
|
<th class="cursor-pointer">
|
||||||
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
|
{#if !header.isPlaceholder}
|
||||||
id="sponsoring:dropdown:menu">
|
<div on:click={header.column.getToggleSortingHandler()}>
|
||||||
<div
|
<svelte:component
|
||||||
class="py-1"
|
this={flexRender(
|
||||||
role="menu"
|
header.column.columnDef.header,
|
||||||
aria-orientation="vertical"
|
header.getContext()
|
||||||
aria-labelledby="options-menu">
|
)}
|
||||||
<span
|
/>
|
||||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
{#if header.column.getIsSorted().toString() == "asc"}
|
||||||
<button
|
🔼
|
||||||
on:click={() => {
|
{:else if header.column.getIsSorted().toString() == "desc"}
|
||||||
generateSponsoringContract('de');
|
🔽
|
||||||
}}
|
{/if}
|
||||||
type="submit"
|
</div>
|
||||||
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"
|
{/if}
|
||||||
role="menuitem">
|
{#if header.column.getCanFilter()}
|
||||||
{$_('german')}
|
<div class="relative max-w-xs">
|
||||||
</button>
|
<input
|
||||||
<button
|
title="name-search"
|
||||||
on:click={() => {
|
value={header.column.getFilterValue() || ""}
|
||||||
generateSponsoringContract('en');
|
on:keyup={(e) => {
|
||||||
}}
|
header.column.setFilterValue(e.target.value);
|
||||||
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"
|
type="text"
|
||||||
role="menuitem">
|
class="block rounded-md border-gray-200 py-2 pl-8 text-xs focus:border-blue-500 focus:ring-blue-500"
|
||||||
{$_('english')}
|
placeholder=""
|
||||||
</button>
|
/>
|
||||||
</div>
|
<div
|
||||||
</div>
|
class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2"
|
||||||
{/if}
|
>
|
||||||
</div>
|
<svg
|
||||||
{/if}
|
class="h-3.5 w-3.5 text-gray-400"
|
||||||
</div>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<div
|
width={16}
|
||||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
height={16}
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
fill="currentColor"
|
||||||
<thead class="bg-gray-50">
|
viewBox="0 0 16 16"
|
||||||
<tr>
|
>
|
||||||
<th
|
<path
|
||||||
scope="col"
|
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"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
/>
|
||||||
<span
|
</svg>
|
||||||
on:click={() => {
|
</div>
|
||||||
const newstate = !current_runners.some((r) => r.is_selected === true);
|
</div>
|
||||||
current_runners = current_runners.map((r) => {
|
{/if}
|
||||||
r.is_selected = newstate;
|
</th>
|
||||||
return r;
|
{/each}
|
||||||
});
|
</tr>
|
||||||
}}
|
{/each}
|
||||||
class="underline cursor-pointer select-none">{#if current_runners.some((r) => r.is_selected === true)}
|
</thead>
|
||||||
{$_('deselect-all')}
|
<tbody>
|
||||||
{:else}{$_('select-all')}{/if}
|
{#each $table.getRowModel().rows as row}
|
||||||
</span>
|
<tr>
|
||||||
</th>
|
<td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
|
||||||
<th
|
<InputElement
|
||||||
scope="col"
|
type="checkbox"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
checked={row.getIsSelected()}
|
||||||
{$_('name')}
|
on:change={() => row.toggleSelected()}
|
||||||
</th>
|
/>
|
||||||
<th
|
</td>
|
||||||
scope="col"
|
{#each row.getVisibleCells() as cell}
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
<td>
|
||||||
{$_('contact-information')}
|
<svelte:component
|
||||||
</th>
|
this={flexRender(
|
||||||
<th
|
cell.column.columnDef.cell,
|
||||||
scope="col"
|
cell.getContext()
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
)}
|
||||||
{$_('group')}
|
/>
|
||||||
</th>
|
</td>
|
||||||
<th
|
{/each}
|
||||||
scope="col"
|
</tr>
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
{/each}
|
||||||
{$_('distance-in-km')}
|
</tbody>
|
||||||
</th>
|
</table>
|
||||||
<th scope="col" class="relative px-6 py-3">
|
<div class="h-2" />
|
||||||
<span class="sr-only">{$_('action')}</span>
|
<div class="flex items-center gap-2">
|
||||||
</th>
|
<button
|
||||||
</tr>
|
class="border rounded p-1"
|
||||||
</thead>
|
on:click={() => $table.setPageIndex(0)}
|
||||||
<tbody class="divide-y divide-gray-200">
|
disabled={!$table.getCanPreviousPage()}
|
||||||
{#each current_runners as runner}
|
>
|
||||||
{#if runner.firstname
|
{"<<"}
|
||||||
.toLowerCase()
|
</button>
|
||||||
.includes(
|
<button
|
||||||
searchvalue.toLowerCase()
|
class="border rounded p-1"
|
||||||
) || runner.lastname
|
on:click={() => $table.previousPage()}
|
||||||
.toLowerCase()
|
disabled={!$table.getCanPreviousPage()}
|
||||||
.includes(
|
>
|
||||||
searchvalue.toLowerCase()
|
{"<"}
|
||||||
) || should_display_based_on_id(runner.id)}
|
</button>
|
||||||
{#if filterGroupIDs.includes(runner.group.id) || filterGroupIDs.includes(runner.group.parentGroup?.id) || filterGroupIDs.length === 0}
|
<button
|
||||||
<tr
|
class="border rounded p-1"
|
||||||
data-rowid="user_{runner.id}"
|
on:click={() => $table.nextPage()}
|
||||||
data-groupid={runner.group.id}>
|
disabled={!$table.getCanNextPage()}
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
>
|
||||||
<input
|
{">"}
|
||||||
bind:checked={runner.is_selected}
|
</button>
|
||||||
type="checkbox"
|
<button
|
||||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
class="border rounded p-1"
|
||||||
</td>
|
on:click={() => $table.setPageIndex($table.getPageCount() - 1)}
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
disabled={!$table.getCanNextPage()}
|
||||||
<div class="flex items-center">
|
>
|
||||||
<div class="ml-4">
|
{">>"}
|
||||||
<div class="text-sm font-medium text-gray-900">
|
</button>
|
||||||
{runner.firstname}
|
<span class="flex items-center gap-1">
|
||||||
{runner.middlename || ''}
|
<div>Page</div>
|
||||||
{runner.lastname}
|
<strong>
|
||||||
</div>
|
{$table.getState().pagination.pageIndex + 1} of{" "}
|
||||||
</div>
|
{$table.getPageCount()}
|
||||||
</div>
|
</strong>
|
||||||
</td>
|
</span>
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<span class="flex items-center gap-1">
|
||||||
{#if runner.email}
|
| Go to page:
|
||||||
<div class="text-sm text-gray-500">{runner.email}</div>
|
<input
|
||||||
{/if}
|
type="number"
|
||||||
{#if runner.phone}
|
defaultValue={$table.getState().pagination.pageIndex + 1}
|
||||||
<div class="text-sm text-gray-500">{runner.phone}</div>
|
on:change={(e) => {
|
||||||
{/if}
|
const page = e.target.value ? Number(e.target.value) - 1 : 0;
|
||||||
{#if runner.address.address1 !== null}
|
$table.setPageIndex(page);
|
||||||
{runner.address.address1}<br />
|
}}
|
||||||
{runner.address.address2 || ''}<br />
|
class="border p-1 rounded w-16"
|
||||||
{runner.address.postalcode}
|
/>
|
||||||
{runner.address.city}
|
</span>
|
||||||
{runner.address.country}
|
<select
|
||||||
{/if}
|
value={$table.getState().pagination.pageSize}
|
||||||
</td>
|
on:input={(e) => {
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
const ps = Number(e.target.value);
|
||||||
{#if runner.group.responseType === 'RUNNERTEAM'}
|
console.log({ ps });
|
||||||
<a
|
$table.setPageSize(Number(e.target.value));
|
||||||
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}
|
{#each tablePageCount as pageSize}
|
||||||
{#if runner.group.responseType === 'RUNNERORGANIZATION'}
|
<option value={pageSize}>{pageSize}</option>
|
||||||
<a
|
{/each}
|
||||||
href="../orgs/{runner.group.id}"
|
</select>
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{runner.group.name}</a>
|
</div>
|
||||||
{/if}
|
<!-- <pre>{JSON.stringify($table.getState(), null, 2)}</pre> -->
|
||||||
</td>
|
<div>
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
{Object.keys(selected).length} of{" "}
|
||||||
{runner.distance}
|
{$table.getPreFilteredRowModel().rows.length} Total Rows Selected
|
||||||
</td>
|
</div>
|
||||||
{#if active_deletes[runner.id] === true}
|
{/if}
|
||||||
<td
|
{/if}
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<button
|
<style>
|
||||||
on:click={() => {
|
thead {
|
||||||
active_deletes[runner.id] = false;
|
background: #fff;
|
||||||
}}
|
}
|
||||||
tabindex="0"
|
thead {
|
||||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
position: sticky;
|
||||||
<button
|
inset-block-start: 0;
|
||||||
on:click={() => {
|
}
|
||||||
RunnerService.runnerControllerRemove(runner.id, true)
|
tbody td {
|
||||||
.then((resp) => {
|
padding: 4px;
|
||||||
current_runners = current_runners.filter((obj) => obj.id !== runner.id);
|
}
|
||||||
})
|
tbody tr:nth-child(even) {
|
||||||
.catch((err) => {});
|
background: #fafafa;
|
||||||
}}
|
}
|
||||||
tabindex="0"
|
tbody tr {
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
transition: all, 0.2s;
|
||||||
</td>
|
}
|
||||||
{:else}
|
tbody tr:hover {
|
||||||
<td
|
background: #f5f5f5;
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
}
|
||||||
<a
|
</style>
|
||||||
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}
|
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
{/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,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;
|
||||||
@@ -23,14 +23,14 @@
|
|||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_('copied-token-to-clipboard'),
|
text: $_("copied-token-to-clipboard"),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
copied = true;
|
copied = true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_('error-whyile-copying-to-clipboard'),
|
text: $_("error-whyile-copying-to-clipboard"),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
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%)",
|
||||||
@@ -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">
|
||||||
@@ -75,7 +75,9 @@
|
|||||||
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></svg>
|
d="M4 5v11h16V5H4zM2 4a1 1 0 011-1h18a1 1 0 011 1v14H2V4zM1 19h22v2H1v-2z" /></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">{$_('token')}</h3>
|
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||||
|
{$_('token')}
|
||||||
|
</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">
|
||||||
{$_('the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again')}
|
{$_('the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again')}
|
||||||
@@ -106,7 +108,9 @@
|
|||||||
d="M7 4V2h10v2h3l1 1v16a1 1 0 01-1 1H4a1 1 0 01-1-1V5l1-1h3zm0 2H5v14h14V6h-2v2H7V6zm2-2v2h6V4H9z" /></svg>
|
d="M7 4V2h10v2h3l1 1v16a1 1 0 01-1 1H4a1 1 0 01-1-1V5l1-1h3zm0 2H5v14h14V6h-2v2H7V6zm2-2v2h6V4H9z" /></svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-gray-500 text-xs">{$_('click-to-copy-token-to-clipboard')}</p>
|
<p class="text-gray-500 text-xs">
|
||||||
|
{$_('click-to-copy-token-to-clipboard')}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -1,399 +1,304 @@
|
|||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
GroupContactService,
|
GroupContactService,
|
||||||
RunnerOrganizationService,
|
RunnerOrganizationService,
|
||||||
RunnerTeamService,
|
RunnerTeamService,
|
||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import store from "../../store";
|
import store from "../../store";
|
||||||
import Select from "svelte-select";
|
import Select from "svelte-select";
|
||||||
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
|
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
|
||||||
import PromiseError from "../base/PromiseError.svelte";
|
import PromiseError from "../base/PromiseError.svelte";
|
||||||
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
||||||
import Teams from "./Teams.svelte";
|
import Teams from "./Teams.svelte";
|
||||||
let [teamdata, original, delete_team, orgs, contacts, modal_open] = [
|
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
|
||||||
{},
|
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
|
||||||
{},
|
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
|
||||||
{},
|
let [teamdata, original, delete_team, orgs, contacts, modal_open] = [
|
||||||
[],
|
{},
|
||||||
[],
|
{},
|
||||||
false,
|
{},
|
||||||
];
|
[],
|
||||||
export let params;
|
[],
|
||||||
export let import_modal_open = false;
|
false,
|
||||||
$: delete_triggered = false;
|
];
|
||||||
$: save_enabled = !data_changed && teamdata.parentGroup != null;
|
export let params;
|
||||||
$: data_loaded = false;
|
export let import_modal_open = false;
|
||||||
$: data_changed = JSON.stringify(teamdata) === JSON.stringify(original);
|
$: delete_triggered = false;
|
||||||
$: sponsoring_contracts_download_open = false;
|
$: save_enabled = data_changed && teamdata.parentGroup != null;
|
||||||
$: group = {};
|
$: data_loaded = false;
|
||||||
$: contact = {};
|
$: data_changed = !(JSON.stringify(teamdata) === JSON.stringify(original));
|
||||||
//
|
$: sponsoring_contracts_show = true;
|
||||||
const getContactLabel = (option) =>
|
$: cards_show = true;
|
||||||
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
$: certificates_show = true;
|
||||||
const promise = RunnerTeamService.runnerTeamControllerGetOne(
|
$: generate_teams = [original];
|
||||||
params.teamid
|
$: group = {};
|
||||||
).then((value) => {
|
$: contact = {};
|
||||||
data_loaded = true;
|
//
|
||||||
teamdata = Object.assign(teamdata, value);
|
const getContactLabel = (option) =>
|
||||||
original = Object.assign(original, value);
|
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
const promise = RunnerTeamService.runnerTeamControllerGetOne(
|
||||||
orgs = val.map((r) => {
|
params.teamid
|
||||||
return { label: r.name, value: r };
|
).then((value) => {
|
||||||
});
|
data_loaded = true;
|
||||||
group = orgs.find((g) => g.value.id == teamdata.parentGroup.id);
|
teamdata = Object.assign(teamdata, value);
|
||||||
});
|
original = Object.assign(original, value);
|
||||||
GroupContactService.groupContactControllerGetAll().then((val) => {
|
RunnerOrganizationService.runnerOrganizationControllerGetAll().then(
|
||||||
contacts = val.map((r) => {
|
(val) => {
|
||||||
return { label: getContactLabel(r), value: r };
|
orgs = val.map((r) => {
|
||||||
});
|
delete r.contact;
|
||||||
if(teamdata.contact){
|
r.teams = [];
|
||||||
contact = contacts.find((g) => g.value.id == teamdata.contact.id);
|
return { label: r.name, value: r };
|
||||||
}
|
});
|
||||||
else{
|
group = orgs.find((g) => g.value.id == teamdata.parentGroup.id);
|
||||||
contact = null;
|
}
|
||||||
}
|
);
|
||||||
});
|
GroupContactService.groupContactControllerGetAll().then((val) => {
|
||||||
});
|
contacts = val.map((r) => {
|
||||||
document.addEventListener("click", function (e) {
|
return { label: getContactLabel(r), value: r };
|
||||||
if (
|
});
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
if (teamdata.contact) {
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
contact = contacts.find((g) => g.value.id == teamdata.contact.id);
|
||||||
) {
|
} else {
|
||||||
sponsoring_contracts_download_open = false;
|
contact = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
function deleteTeam() {
|
});
|
||||||
RunnerTeamService.runnerTeamControllerRemove(original.id, false)
|
function deleteTeam() {
|
||||||
.then((resp) => {
|
RunnerTeamService.runnerTeamControllerRemove(original.id, false)
|
||||||
Toastify({
|
.then((resp) => {
|
||||||
text: "Organization deleted",
|
Toastify({
|
||||||
duration: 500,
|
text: $_('team-deleted'),
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
duration: 500,
|
||||||
}).showToast();
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
location.replace("./");
|
}).showToast();
|
||||||
})
|
location.replace("./");
|
||||||
.catch((err) => {
|
})
|
||||||
modal_open = true;
|
.catch((err) => {
|
||||||
delete_team = original;
|
modal_open = true;
|
||||||
});
|
delete_team = original;
|
||||||
}
|
});
|
||||||
function submit() {
|
}
|
||||||
if (data_loaded === true && save_enabled) {
|
function submit() {
|
||||||
Toastify({
|
if (data_loaded === true && save_enabled) {
|
||||||
text: "updating team",
|
Toastify({
|
||||||
duration: 2500,
|
text: $_('updating-team'),
|
||||||
}).showToast();
|
duration: 2500,
|
||||||
let postdata = teamdata;
|
}).showToast();
|
||||||
postdata.parentGroup = teamdata.parentGroup.id;
|
let postdata = teamdata;
|
||||||
postdata.contact = teamdata.contact?.id;
|
postdata.parentGroup = teamdata.parentGroup.id;
|
||||||
RunnerTeamService.runnerTeamControllerPut(original.id, postdata)
|
postdata.contact = teamdata.contact?.id;
|
||||||
.then((resp) => {
|
RunnerTeamService.runnerTeamControllerPut(original.id, postdata)
|
||||||
Object.assign(original, teamdata);
|
.then((resp) => {
|
||||||
original = original;
|
Object.assign(original, teamdata);
|
||||||
Toastify({
|
original = original;
|
||||||
text: "updated team",
|
Toastify({
|
||||||
duration: 2500,
|
text: $_('updated-team'),
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
duration: 2500,
|
||||||
}).showToast();
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
})
|
}).showToast();
|
||||||
.catch((err) => {});
|
})
|
||||||
}
|
.catch((err) => {});
|
||||||
}
|
}
|
||||||
async function generateSponsoringContract(locale) {
|
}
|
||||||
sponsoring_contracts_download_open = false;
|
</script>
|
||||||
const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
|
|
||||||
teamdata.id
|
<ImportRunnerModal
|
||||||
);
|
current_runners={[]}
|
||||||
const toast = Toastify({
|
on:cancelDelete={(event) => {
|
||||||
text: $_("generating-pdf"),
|
import_modal_open = false;
|
||||||
duration: -1,
|
}}
|
||||||
}).showToast();
|
passed_team={teamdata}
|
||||||
fetch(
|
passed_orgs={[]}
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
passed_org={{}}
|
||||||
{
|
opened_from="TeamDetail"
|
||||||
method: "POST",
|
bind:import_modal_open />
|
||||||
headers: {
|
<ConfirmTeamDeletion bind:modal_open bind:delete_team />
|
||||||
"Content-Type": "application/json",
|
{#if data_loaded}
|
||||||
},
|
<section class="container p-5">
|
||||||
body: JSON.stringify(runners),
|
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||||
}
|
{original.name}
|
||||||
)
|
<span data-id="org_actions_${teamdata.id}">
|
||||||
.then((response) => {
|
<GenerateSponsoringContracts
|
||||||
if (response.status != "200") {
|
bind:sponsoring_contracts_show
|
||||||
toast.hideToast();
|
bind:generate_teams />
|
||||||
Toastify({
|
<GenerateRunnerCards
|
||||||
text: $_("pdf-generation-failed"),
|
bind:cards_show
|
||||||
duration: 3500,
|
bind:generate_teams />
|
||||||
backgroundColor:
|
<GenerateRunnerCertificates
|
||||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
bind:certificates_show
|
||||||
}).showToast();
|
bind:generate_teams />
|
||||||
} else {
|
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
|
||||||
return response.blob();
|
<button
|
||||||
}
|
on:click={() => {
|
||||||
})
|
import_modal_open = true;
|
||||||
.then((blob) => {
|
}}
|
||||||
const url = window.URL.createObjectURL(blob);
|
type="button"
|
||||||
let a = document.createElement("a");
|
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">
|
||||||
a.href = url;
|
{$_('import-runners')}
|
||||||
a.download = "Sponsorings_" + teamdata.name + ".pdf";
|
</button>
|
||||||
document.body.appendChild(a);
|
{/if}
|
||||||
a.click();
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')}
|
||||||
a.remove();
|
{#if delete_triggered}
|
||||||
toast.hideToast();
|
<button
|
||||||
Toastify({
|
on:click={deleteTeam}
|
||||||
text: $_("pdf-successfully-generated"),
|
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-delete')}</button>
|
||||||
duration: 3500,
|
<button
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
on:click={() => {
|
||||||
}).showToast();
|
delete_triggered = !delete_triggered;
|
||||||
})
|
}}
|
||||||
.catch((err) => {});
|
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}
|
||||||
</script>
|
{#if !delete_triggered}
|
||||||
|
<button
|
||||||
<ImportRunnerModal
|
on:click={() => {
|
||||||
current_runners={[]}
|
delete_triggered = true;
|
||||||
on:cancelDelete={(event) => {
|
}}
|
||||||
import_modal_open = false;
|
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-team')}</button>
|
||||||
passed_team={teamdata}
|
{/if}
|
||||||
passed_orgs={[]}
|
{/if}
|
||||||
passed_org={{}}
|
{#if !delete_triggered}
|
||||||
opened_from="TeamDetail"
|
<button
|
||||||
bind:import_modal_open />
|
on:click={submit}
|
||||||
<ConfirmTeamDeletion bind:modal_open bind:delete_team />
|
disabled={!save_enabled}
|
||||||
{#if data_loaded}
|
class:opacity-50={!save_enabled}
|
||||||
<section class="container p-5">
|
type="button"
|
||||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
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>
|
||||||
{original.name}
|
{/if}
|
||||||
<span data-id="org_actions_${teamdata.id}">
|
</span>
|
||||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
</div>
|
||||||
<div>
|
<div class="flex flex-row mb-4">
|
||||||
<button
|
<div class="w-full">
|
||||||
on:click={() => {
|
<nav class="w-full flex">
|
||||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
<ol class="list-none flex flex-row items-center justify-start">
|
||||||
}}
|
<li class="mr-2 flex items-center">
|
||||||
type="button"
|
<svg
|
||||||
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"
|
stroke="currentColor"
|
||||||
id="options-menu"
|
fill="none"
|
||||||
aria-haspopup="true"
|
stroke-width="2"
|
||||||
aria-expanded="true">
|
viewBox="0 0 24 24"
|
||||||
{$_('generate-sponsoring-contracts')}
|
stroke-linecap="round"
|
||||||
<svg
|
stroke-linejoin="round"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
class="h-3 w-3 stroke-current"
|
||||||
width="24"
|
height="1em"
|
||||||
height="24"
|
width="1em"
|
||||||
viewBox="0 0 24 24"
|
xmlns="http://www.w3.org/2000/svg"><path
|
||||||
class="-mr-1 ml-2 h-5 w-5"><path
|
d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
|
||||||
fill="none"
|
<polyline points="9 22 9 12 15 12 15 22" /></svg>
|
||||||
d="M0 0h24v24H0z" />
|
</li>
|
||||||
<path
|
<li class="flex items-center">
|
||||||
fill="currentColor"
|
<a class="mr-2" href="/">Home</a><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" /></svg>
|
stroke="currentColor"
|
||||||
</button>
|
fill="none"
|
||||||
</div>
|
stroke-width="2"
|
||||||
{#if sponsoring_contracts_download_open}
|
viewBox="0 0 24 24"
|
||||||
<div
|
stroke-linecap="round"
|
||||||
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
|
stroke-linejoin="round"
|
||||||
id="sponsoring:dropdown:menu">
|
class="h-3 w-3 mr-2 stroke-current"
|
||||||
<div
|
height="1em"
|
||||||
class="py-1"
|
width="1em"
|
||||||
role="menu"
|
xmlns="http://www.w3.org/2000/svg"><line
|
||||||
aria-orientation="vertical"
|
x1="5"
|
||||||
aria-labelledby="options-menu">
|
y1="12"
|
||||||
<span
|
x2="19"
|
||||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
y2="12" />
|
||||||
<button
|
<polyline points="12 5 19 12 12 19" /></svg>
|
||||||
on:click={() => {
|
</li>
|
||||||
generateSponsoringContract('de');
|
<li class="mr-2 flex items-center">
|
||||||
}}
|
<svg
|
||||||
type="submit"
|
class="flex-shrink-0 w-5 h-5 mr-2"
|
||||||
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 inline-flex"
|
fill="currentColor"
|
||||||
role="menuitem">
|
width="24"
|
||||||
{$_('german')}
|
height="24"
|
||||||
</button>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<button
|
viewBox="0 0 640 512"><path
|
||||||
on:click={() => {
|
fill="currentColor"
|
||||||
generateSponsoringContract('en');
|
d="M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z" /></svg>
|
||||||
}}
|
</li>
|
||||||
type="submit"
|
<li class="flex items-center">
|
||||||
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 inline-flex"
|
<a class="mr-2" href="./">Teams</a><svg
|
||||||
role="menuitem">
|
stroke="currentColor"
|
||||||
{$_('english')}
|
fill="none"
|
||||||
</button>
|
stroke-width="2"
|
||||||
</div>
|
viewBox="0 0 24 24"
|
||||||
</div>
|
stroke-linecap="round"
|
||||||
{/if}
|
stroke-linejoin="round"
|
||||||
</div>
|
class="h-3 w-3 mr-2 stroke-current"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
|
height="1em"
|
||||||
<button
|
width="1em"
|
||||||
on:click={() => {
|
xmlns="http://www.w3.org/2000/svg"><line
|
||||||
import_modal_open = true;
|
x1="5"
|
||||||
}}
|
y1="12"
|
||||||
type="button"
|
x2="19"
|
||||||
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">
|
y2="12" />
|
||||||
{$_('import-runners')}
|
<polyline points="12 5 19 12 12 19" /></svg>
|
||||||
</button>
|
</li>
|
||||||
{/if}
|
<li class="flex items-center">
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')}
|
<span class="mr-2">Team-Details #{params.teamid}</span>
|
||||||
{#if delete_triggered}
|
</li>
|
||||||
<button
|
</ol>
|
||||||
on:click={deleteTeam}
|
</nav>
|
||||||
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-delete')}</button>
|
</div>
|
||||||
<button
|
</div>
|
||||||
on:click={() => {
|
<div class="text-sm w-full">
|
||||||
delete_triggered = !delete_triggered;
|
<label for="name" class="font-medium text-gray-700">Name</label>
|
||||||
}}
|
<input
|
||||||
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>
|
autocomplete="off"
|
||||||
{/if}
|
placeholder="Name"
|
||||||
{#if !delete_triggered}
|
type="text"
|
||||||
<button
|
bind:value={teamdata.name}
|
||||||
on:click={() => {
|
name="name"
|
||||||
delete_triggered = true;
|
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>
|
||||||
type="button"
|
<div class="text-sm w-full">
|
||||||
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-team')}</button>
|
<label
|
||||||
{/if}
|
for="contact"
|
||||||
{/if}
|
class="font-medium text-gray-700">{$_('contact')}</label>
|
||||||
{#if !delete_triggered}
|
<Select
|
||||||
<button
|
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"
|
||||||
on:click={submit}
|
itemFilter={(label, filterText, option) => label
|
||||||
disabled={!save_enabled}
|
.toLowerCase()
|
||||||
class:opacity-50={!save_enabled}
|
.includes(
|
||||||
type="button"
|
filterText.toLowerCase()
|
||||||
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>
|
) || option.value.id
|
||||||
{/if}
|
.toString()
|
||||||
</span>
|
.startsWith(filterText.toLowerCase())}
|
||||||
</div>
|
items={contacts}
|
||||||
<div class="flex flex-row mb-4">
|
showChevron={true}
|
||||||
<div class="w-full">
|
placeholder={$_('no-contact-selected')}
|
||||||
<nav class="w-full flex">
|
noOptionsMessage={$_('no-contact-found')}
|
||||||
<ol class="list-none flex flex-row items-center justify-start">
|
bind:selectedValue={contact}
|
||||||
<li class="mr-2 flex items-center">
|
on:select={(selectedValue) => (teamdata.contact = selectedValue.detail.value)}
|
||||||
<svg
|
on:clear={() => (teamdata.contact = null)} />
|
||||||
stroke="currentColor"
|
</div>
|
||||||
fill="none"
|
<div class="text-sm w-full">
|
||||||
stroke-width="2"
|
<label
|
||||||
viewBox="0 0 24 24"
|
for="org"
|
||||||
stroke-linecap="round"
|
class="font-medium text-gray-700">{$_('organization')}</label>
|
||||||
stroke-linejoin="round"
|
<Select
|
||||||
class="h-3 w-3 stroke-current"
|
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"
|
||||||
height="1em"
|
itemFilter={(label, filterText, option) => label
|
||||||
width="1em"
|
.toLowerCase()
|
||||||
xmlns="http://www.w3.org/2000/svg"><path
|
.includes(
|
||||||
d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
|
filterText.toLowerCase()
|
||||||
<polyline points="9 22 9 12 15 12 15 22" /></svg>
|
) || option.id.value
|
||||||
</li>
|
.toString()
|
||||||
<li class="flex items-center">
|
.startsWith(filterText.toLowerCase())}
|
||||||
<a class="mr-2" href="/">Home</a><svg
|
items={orgs}
|
||||||
stroke="currentColor"
|
showChevron={true}
|
||||||
fill="none"
|
placeholder={$_('search-for-an-organization-by-name-or-id')}
|
||||||
stroke-width="2"
|
noOptionsMessage={$_('no-organizations-found')}
|
||||||
viewBox="0 0 24 24"
|
bind:selectedValue={group}
|
||||||
stroke-linecap="round"
|
on:select={(selectedValue) => (teamdata.parentGroup = selectedValue.detail.value)}
|
||||||
stroke-linejoin="round"
|
on:clear={() => (teamdata.parentGroup = null)} />
|
||||||
class="h-3 w-3 mr-2 stroke-current"
|
</div>
|
||||||
height="1em"
|
</section>
|
||||||
width="1em"
|
{:else}
|
||||||
xmlns="http://www.w3.org/2000/svg"><line
|
{#await promise}
|
||||||
x1="5"
|
{$_('team-detail-is-being-loaded')}
|
||||||
y1="12"
|
{:catch error}
|
||||||
x2="19"
|
<PromiseError />
|
||||||
y2="12" />
|
{/await}
|
||||||
<polyline points="12 5 19 12 12 19" /></svg>
|
{/if}
|
||||||
</li>
|
|
||||||
<li class="mr-2 flex items-center">
|
|
||||||
<svg
|
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2"
|
|
||||||
fill="currentColor"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 640 512"><path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z" /></svg>
|
|
||||||
</li>
|
|
||||||
<li class="flex items-center">
|
|
||||||
<a class="mr-2" href="./">Teams</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">Team-Details #{params.teamid}</span>
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-sm w-full">
|
|
||||||
<label for="name" class="font-medium text-gray-700">Name</label>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
placeholder="Name"
|
|
||||||
type="text"
|
|
||||||
bind:value={teamdata.name}
|
|
||||||
name="name"
|
|
||||||
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 class="text-sm w-full">
|
|
||||||
<label
|
|
||||||
for="contact"
|
|
||||||
class="font-medium text-gray-700">{$_('contact')}</label>
|
|
||||||
<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"
|
|
||||||
itemFilter={(label, filterText, option) => label
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
filterText.toLowerCase()
|
|
||||||
) || option.value.id
|
|
||||||
.toString()
|
|
||||||
.startsWith(filterText.toLowerCase())}
|
|
||||||
items={contacts}
|
|
||||||
showChevron={true}
|
|
||||||
placeholder={$_('no-contact-selected')}
|
|
||||||
noOptionsMessage={$_('no-contact-found')}
|
|
||||||
bind:selectedValue={contact}
|
|
||||||
on:select={(selectedValue)=> teamdata.contact = selectedValue.detail.value}
|
|
||||||
on:clear={() => (teamdata.contact = null)} />
|
|
||||||
</div>
|
|
||||||
<div class="text-sm w-full">
|
|
||||||
<label
|
|
||||||
for="org"
|
|
||||||
class="font-medium text-gray-700">{$_('organization')}</label>
|
|
||||||
<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"
|
|
||||||
itemFilter={(label, filterText, option) => label
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
filterText.toLowerCase()
|
|
||||||
) || option.id.value.toString().startsWith(filterText.toLowerCase())}
|
|
||||||
items={orgs}
|
|
||||||
showChevron={true}
|
|
||||||
placeholder={$_('search-for-an-organization-by-name-or-id')}
|
|
||||||
noOptionsMessage={$_('no-organizations-found')}
|
|
||||||
bind:selectedValue={group}
|
|
||||||
on:select={(selectedValue)=> teamdata.parentGroup = selectedValue.detail.value}
|
|
||||||
on:clear={() => (teamdata.parentGroup = null)} />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{:else}
|
|
||||||
{#await promise}
|
|
||||||
{$_('team-detail-is-being-loaded')}
|
|
||||||
{:catch error}
|
|
||||||
<PromiseError />
|
|
||||||
{/await}
|
|
||||||
{/if}
|
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<section class="container p-5">
|
<section class="container p-5">
|
||||||
<span class="mb-1 text-3xl font-extrabold leading-tight">
|
<span class="mb-1 text-3xl font-extrabold leading-tight">
|
||||||
{$_('teams')}
|
{$_('teams')}
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:CREATE')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:CREATE')}
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
modal_open = true;
|
modal_open = true;
|
||||||
@@ -27,6 +27,6 @@
|
|||||||
<TeamsOverview bind:current_teams />
|
<TeamsOverview bind:current_teams />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:CREATE')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:CREATE')}
|
||||||
<AddTeamModal bind:current_teams bind:modal_open />
|
<AddTeamModal bind:current_teams bind:modal_open />
|
||||||
{/if}
|
{/if}
|
||||||
@@ -1,330 +1,224 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLocaleFromNavigator, t, _ } from "svelte-i18n";
|
import { getLocaleFromNavigator, t, _ } from "svelte-i18n";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import { RunnerTeamService } from "@odit/lfk-client-js";
|
import { RunnerTeamService } from "@odit/lfk-client-js";
|
||||||
const teams_promise = RunnerTeamService.runnerTeamControllerGetAll();
|
const teams_promise = RunnerTeamService.runnerTeamControllerGetAll();
|
||||||
import store, { users as usersstore } from "../../store.js";
|
import store, { users as usersstore } from "../../store.js";
|
||||||
import TeamsEmptyState from "./TeamsEmptyState.svelte";
|
import TeamsEmptyState from "./TeamsEmptyState.svelte";
|
||||||
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
||||||
import { clickOutside } from "../base/outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
$: searchvalue = "";
|
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
|
||||||
$: active_deletes = [];
|
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
|
||||||
$: sponsoring_contracts_download_open = false;
|
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
|
||||||
export let current_teams = [];
|
$: searchvalue = "";
|
||||||
let modal_open = false;
|
$: active_deletes = [];
|
||||||
let delete_team = {};
|
$: sponsoring_contracts_show = current_teams.some(
|
||||||
usersstore.subscribe((val) => {
|
(r) => r.is_selected === true
|
||||||
current_teams = val;
|
);
|
||||||
});
|
$: cards_show = current_teams.some(
|
||||||
teams_promise.then((data) => {
|
(r) => r.is_selected === true
|
||||||
usersstore.set(data);
|
);
|
||||||
});
|
$: certificates_show = current_teams.some(
|
||||||
document.addEventListener("click", function (e) {
|
(r) => r.is_selected === true
|
||||||
if (
|
);
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
$: generate_teams = current_teams.filter((r) => r.is_selected === true);
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
export let current_teams = [];
|
||||||
) {
|
let modal_open = false;
|
||||||
sponsoring_contracts_download_open = false;
|
let delete_team = {};
|
||||||
}
|
usersstore.subscribe((val) => {
|
||||||
});
|
current_teams = val;
|
||||||
async function generateSponsoringContract(locale) {
|
});
|
||||||
sponsoring_contracts_download_open = false;
|
teams_promise.then((data) => {
|
||||||
const teams = current_teams.filter((r) => r.is_selected === true);
|
usersstore.set(data);
|
||||||
const toast = Toastify({
|
});
|
||||||
text: $_("generating-pdfs"),
|
</script>
|
||||||
duration: -1,
|
|
||||||
}).showToast();
|
<ConfirmTeamDeletion
|
||||||
let count = 0;
|
on:cancelDelete={(event) => {
|
||||||
for await (const t of teams) {
|
modal_open = false;
|
||||||
count++;
|
active_deletes[event.detail.id] = false;
|
||||||
const runners = await RunnerTeamService.runnerTeamControllerGetRunners(
|
}}
|
||||||
t.id
|
bind:modal_open
|
||||||
);
|
bind:delete_team />
|
||||||
fetch(
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')}
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
{#await teams_promise}
|
||||||
{
|
<div
|
||||||
method: "POST",
|
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||||
headers: {
|
role="alert">
|
||||||
"Content-Type": "application/json",
|
<p class="font-bold">{$_('teams-are-being-loaded')}</p>
|
||||||
},
|
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
||||||
body: JSON.stringify(runners),
|
</div>
|
||||||
}
|
{:then}
|
||||||
)
|
{#if current_teams.length === 0}
|
||||||
.then((response) => {
|
<TeamsEmptyState />
|
||||||
if (response.status != "200") {
|
{:else}
|
||||||
toast.hideToast();
|
<input
|
||||||
Toastify({
|
type="search"
|
||||||
text: $_("pdf-generation-failed"),
|
bind:value={searchvalue}
|
||||||
duration: 3500,
|
placeholder={$_('datatable.search')}
|
||||||
backgroundColor:
|
aria-label={$_('datatable.search')}
|
||||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
class="mb-4" />
|
||||||
}).showToast();
|
<div class="h-12">
|
||||||
} else {
|
<GenerateSponsoringContracts
|
||||||
return response.blob();
|
bind:sponsoring_contracts_show
|
||||||
}
|
bind:generate_teams />
|
||||||
})
|
<GenerateRunnerCards
|
||||||
.then((blob) => {
|
bind:cards_show
|
||||||
const url = window.URL.createObjectURL(blob);
|
bind:generate_teams />
|
||||||
let a = document.createElement("a");
|
<GenerateRunnerCertificates
|
||||||
a.href = url;
|
bind:certificates_show
|
||||||
a.download = "Sponsorings_" + t.name + ".pdf";
|
bind:generate_teams />
|
||||||
document.body.appendChild(a);
|
</div>
|
||||||
a.click();
|
<div
|
||||||
a.remove();
|
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
||||||
if (count === teams.length) {
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
toast.hideToast();
|
<thead class="bg-gray-50">
|
||||||
Toastify({
|
<tr>
|
||||||
text: $_("pdfs-successfully-generated"),
|
<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
|
||||||
}
|
on:click={() => {
|
||||||
})
|
const newstate = !current_teams.some((r) => r.is_selected === true);
|
||||||
.catch((err) => {});
|
current_teams = current_teams.map((r) => {
|
||||||
}
|
r.is_selected = newstate;
|
||||||
}
|
return r;
|
||||||
</script>
|
});
|
||||||
|
}}
|
||||||
<ConfirmTeamDeletion
|
class="underline cursor-pointer select-none">{#if current_teams.some((r) => r.is_selected === true)}
|
||||||
on:cancelDelete={(event) => {
|
{$_('deselect-all')}
|
||||||
modal_open = false;
|
{:else}{$_('select-all')}{/if}
|
||||||
active_deletes[event.detail.id] = false;
|
</span>
|
||||||
}}
|
</th>
|
||||||
bind:modal_open
|
<th
|
||||||
bind:delete_team />
|
scope="col"
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')}
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
{#await teams_promise}
|
{$_('name')}
|
||||||
<div
|
</th>
|
||||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
<th
|
||||||
role="alert">
|
scope="col"
|
||||||
<p class="font-bold">{$_('teams-are-being-loaded')}</p>
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
{$_('organization')}
|
||||||
</div>
|
</th>
|
||||||
{:then}
|
<th
|
||||||
{#if current_teams.length === 0}
|
scope="col"
|
||||||
<TeamsEmptyState />
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
{:else}
|
{$_('contact')}
|
||||||
<input
|
</th>
|
||||||
type="search"
|
<th scope="col" class="relative px-6 py-3">
|
||||||
bind:value={searchvalue}
|
<span class="sr-only">{$_('action')}</span>
|
||||||
placeholder={$_('datatable.search')}
|
</th>
|
||||||
aria-label={$_('datatable.search')}
|
</tr>
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
</thead>
|
||||||
<div class="h-12">
|
<tbody class="divide-y divide-gray-200">
|
||||||
{#if current_teams.some((r) => r.is_selected === true)}
|
{#each current_teams as t}
|
||||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
{#if Object.values(t)
|
||||||
<div>
|
.toString()
|
||||||
<button
|
.toLowerCase()
|
||||||
on:click={() => {
|
.includes(searchvalue)}
|
||||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
<tr data-rowid="team_{t.id}">
|
||||||
}}
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
type="button"
|
<input
|
||||||
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"
|
bind:checked={t.is_selected}
|
||||||
id="options-menu"
|
type="checkbox"
|
||||||
aria-haspopup="true"
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
aria-expanded="true">
|
</td>
|
||||||
{$_('generate-sponsoring-contracts')}
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
<svg
|
<div class="flex items-center">
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<div class="ml-4">
|
||||||
width="24"
|
<div class="text-sm font-medium text-gray-900">
|
||||||
height="24"
|
{t.name}
|
||||||
viewBox="0 0 24 24"
|
</div>
|
||||||
class="-mr-1 ml-2 h-5 w-5"><path
|
</div>
|
||||||
fill="none"
|
</div>
|
||||||
d="M0 0h24v24H0z" />
|
</td>
|
||||||
<path
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
fill="currentColor"
|
<div class="flex items-center">
|
||||||
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>
|
<div class="ml-4">
|
||||||
</button>
|
<div class="text-sm font-medium text-gray-900">
|
||||||
</div>
|
{#if t.parentGroup}
|
||||||
{#if sponsoring_contracts_download_open}
|
<a
|
||||||
<div
|
href="../orgs/{t.parentGroup.id}"
|
||||||
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.parentGroup.name}</a>
|
||||||
id="sponsoring:dropdown:menu"
|
{:else}{$_('no-organization-specified')}{/if}
|
||||||
on:click_outside={() => {
|
</div>
|
||||||
sponsoring_contracts_download_open = false;
|
</div>
|
||||||
}}>
|
</div>
|
||||||
<div
|
</td>
|
||||||
class="py-1"
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
role="menu"
|
<div class="flex items-center">
|
||||||
aria-orientation="vertical"
|
<div class="ml-4">
|
||||||
aria-labelledby="options-menu">
|
<div class="text-sm font-medium text-gray-900">
|
||||||
<span
|
{#if t.contact}
|
||||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
<a
|
||||||
<button
|
href="../contacts/{t.contact.id}"
|
||||||
on:click={() => {
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.contact.firstname}
|
||||||
generateSponsoringContract('de');
|
{t.contact.middlename || ''}
|
||||||
}}
|
{t.contact.lastname}</a>
|
||||||
type="submit"
|
{:else}{$_('no-contact-specified')}{/if}
|
||||||
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 inline-flex"
|
</div>
|
||||||
role="menuitem">
|
</div>
|
||||||
{$_('german')}
|
</div>
|
||||||
</button>
|
</td>
|
||||||
<button
|
{#if active_deletes[t.id] === true}
|
||||||
on:click={() => {
|
<td
|
||||||
generateSponsoringContract('en');
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
}}
|
<button
|
||||||
type="submit"
|
on:click={() => {
|
||||||
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 inline-flex"
|
active_deletes[t.id] = false;
|
||||||
role="menuitem">
|
}}
|
||||||
{$_('english')}
|
tabindex="0"
|
||||||
</button>
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
|
||||||
</div>
|
Delete</button>
|
||||||
</div>
|
<button
|
||||||
{/if}
|
on:click={() => {
|
||||||
</div>
|
RunnerTeamService.runnerTeamControllerRemove(t.id, false)
|
||||||
{/if}
|
.then((resp) => {
|
||||||
</div>
|
current_teams = current_teams.filter((obj) => obj.id !== t.id);
|
||||||
<div
|
Toastify({
|
||||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
text: $_('organization-deleted'),
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
duration: 500,
|
||||||
<thead class="bg-gray-50">
|
backgroundColor:
|
||||||
<tr>
|
'linear-gradient(to right, #00b09b, #96c93d)',
|
||||||
<th
|
}).showToast();
|
||||||
scope="col"
|
})
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
.catch((err) => {
|
||||||
<span
|
modal_open = true;
|
||||||
on:click={() => {
|
delete_team = t;
|
||||||
const newstate = !current_teams.some((r) => r.is_selected === true);
|
});
|
||||||
current_teams = current_teams.map((r) => {
|
}}
|
||||||
r.is_selected = newstate;
|
tabindex="0"
|
||||||
return r;
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||||
});
|
</td>
|
||||||
}}
|
{:else}
|
||||||
class="underline cursor-pointer select-none">{#if current_teams.some((r) => r.is_selected === true)}
|
<td
|
||||||
{$_('deselect-all')}
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
{:else}{$_('select-all')}{/if}
|
<a
|
||||||
</span>
|
href="./{t.id}"
|
||||||
</th>
|
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
||||||
<th
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')}
|
||||||
scope="col"
|
<button
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
on:click={() => {
|
||||||
{$_('name')}
|
active_deletes[t.id] = true;
|
||||||
</th>
|
}}
|
||||||
<th
|
tabindex="0"
|
||||||
scope="col"
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
{/if}
|
||||||
{$_('organization')}
|
</td>
|
||||||
</th>
|
{/if}
|
||||||
<th
|
</tr>
|
||||||
scope="col"
|
{/if}
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
{/each}
|
||||||
{$_('contact')}
|
</tbody>
|
||||||
</th>
|
</table>
|
||||||
<th scope="col" class="relative px-6 py-3">
|
</div>
|
||||||
<span class="sr-only">{$_('action')}</span>
|
{/if}
|
||||||
</th>
|
{:catch error}
|
||||||
</tr>
|
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
||||||
</thead>
|
<span class="inline-block align-middle mr-8">
|
||||||
<tbody class="divide-y divide-gray-200">
|
<b class="capitalize">{$_('general_promise_error')}</b>
|
||||||
{#each current_teams as t}
|
{error}
|
||||||
{#if Object.values(t)
|
</span>
|
||||||
.toString()
|
</div>
|
||||||
.toLowerCase()
|
{/await}
|
||||||
.includes(searchvalue)}
|
{/if}
|
||||||
<tr data-rowid="team_{t.id}">
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
<input
|
|
||||||
bind:checked={t.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">
|
|
||||||
{t.name}
|
|
||||||
</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">
|
|
||||||
{#if t.parentGroup}
|
|
||||||
<a
|
|
||||||
href="../orgs/{t.parentGroup.id}"
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.parentGroup.name}</a>
|
|
||||||
{:else}{$_('no-organization-specified')}{/if}
|
|
||||||
</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">
|
|
||||||
{#if t.contact}
|
|
||||||
<a
|
|
||||||
href="../contacts/{t.contact.id}"
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.contact.firstname}
|
|
||||||
{t.contact.middlename || ''}
|
|
||||||
{t.contact.lastname}</a>
|
|
||||||
{:else}{$_('no-contact-specified')}{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
{#if active_deletes[t.id] === true}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[t.id] = false;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
|
|
||||||
Delete</button>
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
RunnerTeamService.runnerTeamControllerRemove(t.id, false)
|
|
||||||
.then((resp) => {
|
|
||||||
current_teams = current_teams.filter((obj) => obj.id !== t.id);
|
|
||||||
Toastify({
|
|
||||||
text: $_('organization-deleted'),
|
|
||||||
duration: 500,
|
|
||||||
backgroundColor:
|
|
||||||
'linear-gradient(to right, #00b09b, #96c93d)',
|
|
||||||
}).showToast();
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
modal_open = true;
|
|
||||||
delete_team = t;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
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="./{t.id}"
|
|
||||||
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')}
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[t.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}
|
|
||||||
@@ -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();
|
||||||
@@ -57,9 +57,9 @@
|
|||||||
.querySelector(`[data-id="triggered_table_actions_${trackid}"]`)
|
.querySelector(`[data-id="triggered_table_actions_${trackid}"]`)
|
||||||
.classList.add("hidden");
|
.classList.add("hidden");
|
||||||
//
|
//
|
||||||
elem.childNodes[0].innerHTML = `<td data-column-id="trackName" class="gridjs-td">${elem.childNodes[0].childNodes[0].value}</td>`;
|
elem.childNodes[0].innerHTML = `<td data-column-id="trackName">${elem.childNodes[0].childNodes[0].value}</td>`;
|
||||||
elem.childNodes[1].innerHTML = `<td data-column-id="trackName" class="gridjs-td">${elem.childNodes[1].childNodes[0].value}</td>`;
|
elem.childNodes[1].innerHTML = `<td data-column-id="trackName">${elem.childNodes[1].childNodes[0].value}</td>`;
|
||||||
elem.childNodes[2].innerHTML = `<td data-column-id="trackName" class="gridjs-td">${elem.childNodes[2].childNodes[0].value}</td>`;
|
elem.childNodes[2].innerHTML = `<td data-column-id="trackName">${elem.childNodes[2].childNodes[0].value}</td>`;
|
||||||
})
|
})
|
||||||
.catch((err) => {});
|
.catch((err) => {});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
-391
@@ -1,392 +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-donation": "Sponsoring erstellen",
|
"add-card": "Karte erstellen",
|
||||||
"add-donor": "Sponsor:in erstellen",
|
"add-donation": "Sponsoring erstellen",
|
||||||
"add-scan": "Scan erstellen",
|
"add-donor": "Sponsor:in erstellen",
|
||||||
"add-the-first-scanstation": "Erstelle deine erste Scannerstation.",
|
"add-or-update-a-payment": "Zahlung hinzufügen oder bearbeiten",
|
||||||
"add-user-group": "Neue Gruppe erstellen",
|
"add-scan": "Scan erstellen",
|
||||||
"add-your-first-contact": "Erstelle den ersten Kontakt",
|
"add-the-first-scanstation": "Erstelle deine erste Scannerstation.",
|
||||||
"add-your-first-donor": "Erstelle die erste Sponsor:in",
|
"add-the-first-statsclient": "Erstelle deinen ersten Statsclient.",
|
||||||
"add-your-first-group": "Erstelle die erste Gruppe",
|
"add-user-group": "Neue Gruppe erstellen",
|
||||||
"add-your-first-organization": "Erstelle die erste Organisation",
|
"add-your-first-card": "Erstelle deine erste Läuferkarte",
|
||||||
"add-your-first-runner": "Erstelle die erste Läufer:in",
|
"add-your-first-contact": "Erstelle den ersten Kontakt",
|
||||||
"add-your-first-team": "Erstelle das erste Team",
|
"add-your-first-donor": "Erstelle die erste Sponsor:in",
|
||||||
"add-your-first-track": "Erstelle den ersten Track (Laufstrecke).",
|
"add-your-first-group": "Erstelle die erste Gruppe",
|
||||||
"add-your-first-user": "Erstelle die erste Benutzer:in",
|
"add-your-first-organization": "Erstelle die erste Organisation",
|
||||||
"add-your-fist-donation": "Erstelle dein erstes Sponsoring",
|
"add-your-first-runner": "Erstelle die erste Läufer:in",
|
||||||
"add-your-fist-scan": "Füge deinen ersten Scan hinzu",
|
"add-your-first-team": "Erstelle das erste Team",
|
||||||
"adding-scan": "Scan wird hinzugefügt",
|
"add-your-first-track": "Erstelle den ersten Track (Laufstrecke).",
|
||||||
"address": "Adresse",
|
"add-your-first-user": "Erstelle die erste Benutzer:in",
|
||||||
"address-is-required": "Du musst eine Adresse angeben",
|
"add-your-fist-donation": "Erstelle dein erstes Sponsoring",
|
||||||
"after-deletion-we-cant-restore-your-old-profile": "Nach der Löschung können auch die Admins dein Profil nicht wiederherstellen!",
|
"add-your-fist-scan": "Füge deinen ersten Scan hinzu",
|
||||||
"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.",
|
"adding-card": "Karte wird erstellt",
|
||||||
"all-associated-donations-will-get-deleted-as-well": "Alle Sponsorings dieser Sponsor:in werden ebenfalls gelöscht",
|
"adding-donation": "Sponsoring wird erstellt...",
|
||||||
"all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!",
|
"adding-scan": "Scan wird hinzugefügt",
|
||||||
"all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!",
|
"address": "Adresse",
|
||||||
"amount-per-kilometer": "Betrag pro Kilometer",
|
"address-is-required": "Du musst eine Adresse angeben",
|
||||||
"apartment-suite-etc": "Apartment, Wohnung, etc.",
|
"after-deletion-we-cant-restore-your-old-profile": "Nach der Löschung können auch die Admins dein Profil nicht wiederherstellen!",
|
||||||
"application_name": "Lauf für Kaya! - Admin",
|
"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.",
|
||||||
"applying-changes": "Änderungen anwenden",
|
"all": "Alle",
|
||||||
"attention": "Achtung!",
|
"all-associated-donations-will-get-deleted-as-well": "Alle Sponsorings dieser Sponsor:in werden ebenfalls gelöscht",
|
||||||
"author": "Autor:in",
|
"all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!",
|
||||||
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer:innen für den Import bestätigen.",
|
"all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!",
|
||||||
"by": "von",
|
"already-paid": "Bereits bezahlt",
|
||||||
"cancel": "Abbrechen",
|
"amount": "Anzahl",
|
||||||
"cancel-delete": "Löschen abbrechen",
|
"amount-per-kilometer": "Betrag pro Kilometer",
|
||||||
"cancel-keep-donor": "Abbrechen, Sponsor:in behalten",
|
"apartment-suite-etc": "Apartment, Wohnung, etc.",
|
||||||
"cancel-keep-my-profile": "Abbrechen, mein Profil behalten",
|
"application_name": "Lauf für Kaya! - Admin",
|
||||||
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
|
"applying-changes": "Änderungen anwenden",
|
||||||
"cancel-keep-team": "Abbrechen, Team behalten",
|
"attention": "Achtung!",
|
||||||
"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.",
|
"author": "Autor:in",
|
||||||
"change-your-password-here": "Hier kannst du dein Passwort ändern",
|
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer:innen für den Import bestätigen.",
|
||||||
"changing-your-password": "Passwort wird geändert",
|
"by": "von",
|
||||||
"city": "Stadt",
|
"cancel": "Abbrechen",
|
||||||
"click-to-copy-token-to-clipboard": "Klicke auf den Token, um ihn in deine Zwischenablage zu kopieren",
|
"cancel-delete": "Löschen abbrechen",
|
||||||
"close": "Schließen",
|
"cancel-keep-donor": "Abbrechen, Sponsor:in behalten",
|
||||||
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
|
"cancel-keep-my-profile": "Abbrechen, mein Profil behalten",
|
||||||
"confirm": "Bestätigen",
|
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
|
||||||
"confirm-delete": "Löschung Bestätigen",
|
"cancel-keep-statsclient": "Abbrechen und Statsclient behalten",
|
||||||
"confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen",
|
"cancel-keep-team": "Abbrechen, Team behalten",
|
||||||
"confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil löschen",
|
"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.",
|
||||||
"confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.",
|
"card-added": "Karte wurde hinzugefügt",
|
||||||
"confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.",
|
"card-deleted": "Karte gelöscht",
|
||||||
"confirm-deletion": "Löschung Bestätigen",
|
"card-updated": "Karte aktualisiert",
|
||||||
"confirm-the-new-password": "Neues Passwort bestätigen",
|
"cards": "Läuferkarten",
|
||||||
"contact": "Kontakt",
|
"certificates": "Urkunden",
|
||||||
"contact-deleted": "Kontakt gelöscht",
|
"change-your-password-here": "Hier kannst du dein Passwort ändern",
|
||||||
"contact-information": "Kontaktinformation",
|
"changing-your-password": "Passwort wird geändert",
|
||||||
"contact-is-being-updated": "Kontakt wird aktualisiert ...",
|
"city": "Stadt",
|
||||||
"contact-is-not-a-member-in-any-group": "Kontakt gehört zu keiner Gruppe",
|
"click-to-copy-the-link-into-your-clipboard": "Klicke auf den Link, um ihn in deine Zwischenablage zu kopieren",
|
||||||
"contacts": "Kontakte",
|
"click-to-copy-token-to-clipboard": "Klicke auf den Token, um ihn in deine Zwischenablage zu kopieren",
|
||||||
"contacts-are-being-loaded": "Kontakte werden geladen ...",
|
"close": "Schließen",
|
||||||
"copied-token-to-clipboard": "Token wurde in die Zwischenablage kopiert",
|
"code": "Code",
|
||||||
"count_organizations": "Organisationen (Anzahl)",
|
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
|
||||||
"count_teams": "Teams (Anzahl)",
|
"confirm": "Bestätigen",
|
||||||
"create": "Erstellen",
|
"confirm-delete": "Löschung Bestätigen",
|
||||||
"create-a-new": "Erstelle eine neue",
|
"confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen",
|
||||||
"create-a-new-contact": "Kontakt erstellen",
|
"confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil löschen",
|
||||||
"create-a-new-distance-donation": "Erstelle ein neues Sponsoring",
|
"confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.",
|
||||||
"create-a-new-donor": "Neue Sponsor:in erstellen",
|
"confirm-delete-statsclient": "Bestätigung, Statsclient löschen",
|
||||||
"create-a-new-fixed-donation": "Erstelle eine neue Festbetragsspende",
|
"confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.",
|
||||||
"create-a-new-organization": "Neue Organisation anlegen",
|
"confirm-deletion": "Löschung Bestätigen",
|
||||||
"create-a-new-runner": "Neue Läufer:in erstellen",
|
"confirm-the-new-password": "Neues Passwort bestätigen",
|
||||||
"create-a-new-scan-fixed-only": "Neuen Scan erstellen (nur mit Festdistanz)",
|
"contact": "Kontakt",
|
||||||
"create-a-new-scanstation": "Neue Station erstellen",
|
"contact-added": "Kontakt wurde hinzugefügt",
|
||||||
"create-a-new-team": "Erstelle ein neues Team",
|
"contact-deleted": "Kontakt gelöscht",
|
||||||
"create-a-new-track": "Neuen Track erstellen",
|
"contact-information": "Kontaktinformation",
|
||||||
"create-a-new-user": "Neue Benutzer:in anlegen",
|
"contact-is-being-added": "Kontakt wird erstellt...",
|
||||||
"create-a-new-user-group": "Erstelle eine neue Gruppe",
|
"contact-is-being-updated": "Kontakt wird aktualisiert ...",
|
||||||
"create-organization": "Organisation erstellen",
|
"contact-is-not-a-member-in-any-group": "Kontakt gehört zu keiner Gruppe",
|
||||||
"create-team": "Team erstellen",
|
"contacts": "Kontakte",
|
||||||
"create-track": "Track erstellen",
|
"contacts-are-being-loaded": "Kontakte werden geladen ...",
|
||||||
"create-user": "Benutzer anlegen",
|
"copied-link-to-clipboard": "Link wurde in die Zwischenablage kopiert",
|
||||||
"credits": "Credits",
|
"copied-token-to-clipboard": "Token wurde in die Zwischenablage kopiert",
|
||||||
"csv_import__class": "Klasse",
|
"count_organizations": "Organisationen (Anzahl)",
|
||||||
"csv_import__firstname": "Vorname",
|
"count_teams": "Teams (Anzahl)",
|
||||||
"csv_import__lastname": "Nachname",
|
"create": "Erstellen",
|
||||||
"csv_import__middlename": "Mittelname",
|
"create-a-new": "Erstelle eine neue",
|
||||||
"csv_import__team": "Team",
|
"create-a-new-card": "Neue Läuferkarte erstellen",
|
||||||
"danger-zone": "Gefahrenzone",
|
"create-a-new-contact": "Kontakt erstellen",
|
||||||
"dashboard-greeting": "Hallo",
|
"create-a-new-distance-donation": "Erstelle ein neues Sponsoring",
|
||||||
"dashboard-title": "Dashboard",
|
"create-a-new-donor": "Neue Sponsor:in erstellen",
|
||||||
"datatable": {
|
"create-a-new-fixed-donation": "Erstelle eine neue Festbetragsspende",
|
||||||
"search": "🔍 Suche ...",
|
"create-a-new-organization": "Neue Organisation anlegen",
|
||||||
"an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten",
|
"create-a-new-runner": "Neue Läufer:in erstellen",
|
||||||
"loading": "Wird geladen...",
|
"create-a-new-scan-fixed-only": "Neuen Scan erstellen (nur mit Festdistanz)",
|
||||||
"next": "Nächste",
|
"create-a-new-scanstation": "Neue Station erstellen",
|
||||||
"of": "von",
|
"create-a-new-statsclient": "Neuen Statsclient erstellen",
|
||||||
"previous": "Vorherige",
|
"create-a-new-team": "Erstelle ein neues Team",
|
||||||
"to": "bis",
|
"create-a-new-track": "Neuen Track erstellen",
|
||||||
"showing": "Zeige",
|
"create-a-new-user": "Neue Benutzer:in anlegen",
|
||||||
"no_matching_records_found": "Keine passenden Einträge gefunden",
|
"create-a-new-user-group": "Erstelle eine neue Gruppe",
|
||||||
"page": "Seite",
|
"create-and-generate-pdf": "Erstellen und PDF herunterladen",
|
||||||
"records": "Einträge",
|
"create-bulk-blanco-cards": "Blankokarten erstellen",
|
||||||
"sort_column_ascending": "Spalte aufsteigend sortieren",
|
"create-bulk-cards": "Blankokarten erstellen",
|
||||||
"sort_column_descending": "Spalte absteigend sortieren"
|
"create-organization": "Organisation erstellen",
|
||||||
},
|
"create-team": "Team erstellen",
|
||||||
"delete": "Löschen",
|
"create-track": "Track erstellen",
|
||||||
"delete-contact": "Kontakt löschen",
|
"create-user": "Benutzer anlegen",
|
||||||
"delete-donation": "Sponsporing löschen",
|
"create-without-pdf": "Ohne PDF erstellen",
|
||||||
"delete-donor": "Sponsor:in löschen",
|
"created-blanco-cards": "Blankokarten wurden erstellt",
|
||||||
"delete-group": "Gruppe löschen",
|
"creating-blanco-cards": "Erstelle Blankokarten",
|
||||||
"delete-organization": "Organisation löschen",
|
"credits": "Credits",
|
||||||
"delete-profile": "Profil löschen",
|
"csv_import__class": "Klasse",
|
||||||
"delete-runner": "Läufer:in löschen",
|
"csv_import__firstname": "Vorname",
|
||||||
"delete-scan": "Scan löschen",
|
"csv_import__lastname": "Nachname",
|
||||||
"delete-station": "Station löschen",
|
"csv_import__middlename": "Mittelname",
|
||||||
"delete-team": "Team Löschen",
|
"csv_import__team": "Team",
|
||||||
"delete-user": "Benutzer:in löschen",
|
"danger-zone": "Gefahrenzone",
|
||||||
"deleted-scan": "Scan wurde gelöscht",
|
"dashboard-greeting": "Hallo",
|
||||||
"dependency_name": "Name",
|
"dashboard-title": "Dashboard",
|
||||||
"description": "Beschreibung",
|
"datatable": {
|
||||||
"description-optional": "Beschreibung (optional)",
|
"search": "🔍 Suche ...",
|
||||||
"deselect-all": "Alle abwählen",
|
"an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten",
|
||||||
"details": "Details",
|
"loading": "Wird geladen...",
|
||||||
"disabled": "deaktiviert",
|
"next": "Nächste",
|
||||||
"distance": "Distanz",
|
"of": "von",
|
||||||
"distance-donation": "Sponsoring",
|
"previous": "Vorherige",
|
||||||
"distance-in-km": "Distanz (in KM)",
|
"to": "bis",
|
||||||
"distance-track": "Distanz (+Track)",
|
"showing": "Zeige",
|
||||||
"do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?",
|
"no_matching_records_found": "Keine passenden Einträge gefunden",
|
||||||
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
|
"page": "Seite",
|
||||||
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?",
|
"records": "Einträge",
|
||||||
"do-you-want-to-delete-this-donor-with-all-related-donations": "Möchtest du diese Sponsor:in mit all ihren Sponsorings löschen?",
|
"sort_column_ascending": "Spalte aufsteigend sortieren",
|
||||||
"documentation": "Dokumentation",
|
"sort_column_descending": "Spalte absteigend sortieren"
|
||||||
"donation-amount": "Sponsoringbetrag",
|
},
|
||||||
"donation-amount-must-be-greater-that-0-00eur": "Der Sponsoringbetrag muss größer als 0.00€ sein.",
|
"delete": "Löschen",
|
||||||
"donations": "Sponsorings",
|
"delete-contact": "Kontakt löschen",
|
||||||
"donor": "Sponsor:in",
|
"delete-donation": "Sponsoring löschen",
|
||||||
"donor-added": "Sponsor:in hinzugefügt",
|
"delete-donor": "Sponsor:in löschen",
|
||||||
"donor-deleted": "Sponsor:in gelöscht",
|
"delete-group": "Gruppe löschen",
|
||||||
"donor-has-no-associated-donations": "Zur Sponsor:in gibt es noch keine Sponsorings",
|
"delete-organization": "Organisation löschen",
|
||||||
"donor-is-being-added": "Sponsor:in wird hinzugefügt...",
|
"delete-profile": "Profil löschen",
|
||||||
"donor-is-being-updated": "Sponsor:in wird aktualisiert",
|
"delete-runner": "Läufer:in löschen",
|
||||||
"donors": "Sponsor:innen",
|
"delete-scan": "Scan löschen",
|
||||||
"donors-are-being-loaded": "Sponsor:innen werden geladen",
|
"delete-station": "Station löschen",
|
||||||
"dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?",
|
"delete-statsclient": "Statsclient löschen",
|
||||||
"dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌",
|
"delete-team": "Team Löschen",
|
||||||
"e-mail-adress": "E-Mail-Adresse",
|
"delete-user": "Benutzer:in löschen",
|
||||||
"edit": "Bearbeiten",
|
"deleted-scan": "Scan wurde gelöscht",
|
||||||
"edit-permissions": "Berechtigungen bearbeiten",
|
"dependency_name": "Name",
|
||||||
"email_address_or_username": "E-Mail-Adresse/ Benutzername",
|
"description": "Beschreibung",
|
||||||
"enabled": "aktiviert",
|
"description-optional": "Beschreibung (optional)",
|
||||||
"enabled_large": "Disabled",
|
"deselect-all": "Alle abwählen",
|
||||||
"english": "Englisch",
|
"details": "Details",
|
||||||
"error-during-import": "Fehler beim Importieren",
|
"disabled": "deaktiviert",
|
||||||
"error-whyile-copying-to-clipboard": "Fehler beim Kopieren in die Zwischenablage",
|
"distance": "Distanz",
|
||||||
"error_on_login": "😢Fehler beim Login",
|
"distance-donation": "Sponsoring",
|
||||||
"erteilte": "Direkt erteilte",
|
"distance-in-km": "Distanz (in KM)",
|
||||||
"everything-concerning-your-profile": "Alles zu deinem Profil",
|
"distance-track": "Distanz (+Track)",
|
||||||
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃♂️🏃♀️🏃♂️",
|
"do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?",
|
||||||
"faq": "FAQ",
|
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
|
||||||
"filter-by-organization-team": "Filtern nach Organisation / Team",
|
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?",
|
||||||
"first-name": "Vorname",
|
"do-you-want-to-delete-this-donor-with-all-related-donations": "Möchtest du diese Sponsor:in mit all ihren Sponsorings löschen?",
|
||||||
"first-name-is-required": "Vorname muss angegeben werden",
|
"documentation": "Dokumentation",
|
||||||
"first-scan-of-the-day": "Erster Scan des Tages",
|
"donation-amount": "Sponsoringbetrag",
|
||||||
"fixed-donation": "Festbetragsspende",
|
"donation-amount-must-be-greater-that-0-00eur": "Der Sponsoringbetrag muss größer als 0.00€ sein.",
|
||||||
"forgot_password": "Passwort vergessen?",
|
"donation-deleted": "Sponsoring gelöscht",
|
||||||
"geerbte": "geerbte",
|
"donation-updated": "Sponsoring wurde aktualisiert",
|
||||||
"general-stats": "Allgemeine Statistiken",
|
"donation_added": "Sponsoring hinzugefügt",
|
||||||
"general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten",
|
"donations": "Sponsorings",
|
||||||
"generate-sponsoring-contract": "Sponsoringvertrag generieren",
|
"donor": "Sponsor:in",
|
||||||
"generate-sponsoring-contracts": "Sponsoringverträge generieren",
|
"donor-added": "Sponsor:in hinzugefügt",
|
||||||
"generating-pdf": "Pdf wird generiert...",
|
"donor-deleted": "Sponsor:in gelöscht",
|
||||||
"generating-pdfs": "PDFs werden generiert...",
|
"donor-has-no-associated-donations": "Zur Sponsor:in gibt es noch keine Sponsorings",
|
||||||
"generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.",
|
"donor-is-being-added": "Sponsor:in wird hinzugefügt...",
|
||||||
"german": "Deutsch",
|
"donor-is-being-updated": "Sponsor:in wird aktualisiert",
|
||||||
"go-to-login": "Zum Login",
|
"donors": "Sponsor:innen",
|
||||||
"goback": "Zur Startseite",
|
"donors-are-being-loaded": "Sponsor:innen werden geladen",
|
||||||
"granted": "Gewährt",
|
"dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?",
|
||||||
"group": "Gruppe",
|
"dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌",
|
||||||
"group-added": "Gruppe hinzugefügt",
|
"e-mail-adress": "E-Mail-Adresse",
|
||||||
"group-is-being-added": "Gruppe wird erstellt",
|
"edit": "Bearbeiten",
|
||||||
"group-name-is-required": "Der Gruppenname muss angegeben werden.",
|
"edit-a-card": "Läuferkarte bearbeiten",
|
||||||
"group-updated": "Gruppe aktualisiert",
|
"edit-permissions": "Berechtigungen bearbeiten",
|
||||||
"groups": "Gruppen",
|
"email_address_or_username": "E-Mail-Adresse/ Benutzername",
|
||||||
"groups-are-being-loaded": "Gruppen werden geladen",
|
"enabled": "aktiviert",
|
||||||
"home": "Start",
|
"enabled_large": "Aktiviert",
|
||||||
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
|
"english": "Englisch",
|
||||||
"import-finished": "Import abgeschlossen",
|
"enter-payment": "Zahlung eingeben",
|
||||||
"import-runners": "Läufer:innen importieren",
|
"error-during-import": "Fehler beim Importieren",
|
||||||
"import__target-organization": "Ziel Organisation",
|
"error-whyile-copying-to-clipboard": "Fehler beim Kopieren in die Zwischenablage",
|
||||||
"imprint": "Impressum ",
|
"error_on_login": "😢Fehler beim Login",
|
||||||
"imprint-loading": "Impressum lädt...",
|
"erteilte": "Direkt erteilte",
|
||||||
"inactive": "Inaktiv",
|
"everything-concerning-your-profile": "Alles zu deinem Profil",
|
||||||
"installed-version": "Installierte Version",
|
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃♂️🏃♀️🏃♂️",
|
||||||
"internal-error": "Interner Fehler",
|
"faq": "FAQ",
|
||||||
"invalid": "Ungültig",
|
"filename_sponsoringquittungsliste": "SponsoringQuittungsListe",
|
||||||
"invalid-mail-reset": "Das ist keine gültige E-Mail",
|
"filter-by-organization-team": "Filtern nach Organisation / Team",
|
||||||
"laeufer-hinzufuegen": "Läufer:in hinzufügen",
|
"first-name": "Vorname",
|
||||||
"laeufer-importieren": "Läufer:innen importieren",
|
"first-name-is-required": "Vorname muss angegeben werden",
|
||||||
"laptime": "Rundenzeit",
|
"first-scan-of-the-day": "Erster Scan des Tages",
|
||||||
"last-name": "Nachname",
|
"fixed-donation": "Festbetragsspende",
|
||||||
"last-name-is-required": "Nachname muss angegeben werden",
|
"forgot_password": "Passwort vergessen?",
|
||||||
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
|
"geerbte": "geerbte",
|
||||||
"license": "Lizenz",
|
"general-stats": "Allgemeine Statistiken",
|
||||||
"licenses-are-being-loaded": "Lizenzen werden geladen...",
|
"general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten",
|
||||||
"loading-contact-details": "Kontaktdaten werden geladen ...",
|
"generate-runner-certificate": "Urkunde generieren",
|
||||||
"loading-donation-details": "Lade Sponsoringdetails",
|
"generate-runner-certificates": "Urkunden generieren",
|
||||||
"loading-donor-details": "Lade Details",
|
"generate-runnercards": "Läuferkarten generieren",
|
||||||
"loading-group-detail": "Lade Gruppendetails...",
|
"generate-sponsoring-contract": "Sponsoringvertrag generieren",
|
||||||
"loading-profile-data": "Lade Profildaten",
|
"generate-sponsoring-contracts": "Sponsoringverträge generieren",
|
||||||
"loading-runners": "Läufer:innen werden geladen...",
|
"generating-pdf": "PDF wird generiert...",
|
||||||
"loading-station-details": "Lade Scanstation-Details ...",
|
"generating-pdfs": "PDFs werden generiert...",
|
||||||
"log_in": "Anmelden",
|
"generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.",
|
||||||
"log_in_to_your_account": "Bitte melde dich an",
|
"german": "Deutsch",
|
||||||
"login_is_checked": "Login wird überprüft",
|
"go-to-login": "Zum Login",
|
||||||
"logout": "Abmelden",
|
"goback": "Zur Startseite",
|
||||||
"mail-validation-in-progress": "E-Mail Verifizierung läuft... ",
|
"granted": "Gewährt",
|
||||||
"manage-admin-users": "Nutzer verwalten",
|
"group": "Gruppe",
|
||||||
"middle-name": "Mittelname",
|
"group-added": "Gruppe hinzugefügt",
|
||||||
"minimum-lap-time-in-s": "Minimale Rundenzeit (in Sekunden)",
|
"group-is-being-added": "Gruppe wird erstellt",
|
||||||
"minimum-lap-time-must-be-a-positive-number-or-0": "Die minimale Rundenzeit muss eine positive Zahl oder 0 sein",
|
"group-name-is-required": "Der Gruppenname muss angegeben werden.",
|
||||||
"name": "Name",
|
"group-updated": "Gruppe aktualisiert",
|
||||||
"name-is-required": "Der Gruppenname muss angegeben werden",
|
"groups": "Gruppen",
|
||||||
"new-password": "Neues Passwort",
|
"groups-are-being-loaded": "Gruppen werden geladen",
|
||||||
"no-contact-found": "Keine Kontakte gefunden",
|
"home": "Start",
|
||||||
"no-contact-selected": "Kein Kontakt ausgewählt",
|
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
|
||||||
"no-contact-specified": "Kein Kontakt angegeben",
|
"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.",
|
||||||
"no-donors-found": "Keine Spender:innen gefunden",
|
"import-finished": "Import abgeschlossen",
|
||||||
"no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢",
|
"import-runners": "Läufer:innen importieren",
|
||||||
"no-organization-or-team-found": "Keine Organisationen oder Teams gefunden",
|
"import__target-organization": "Ziel Organisation",
|
||||||
"no-organization-specified": "Keine Organisation angegeben",
|
"imprint": "Impressum ",
|
||||||
"no-organizations-found": "Keine Organisationen gefunden",
|
"imprint-loading": "Impressum lädt...",
|
||||||
"no-runners-found": "Keine Läufer:innen gefunden",
|
"inactive": "Inaktiv",
|
||||||
"no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.",
|
"installed-version": "Installierte Version",
|
||||||
"organization": "Organisation",
|
"internal-error": "Interner Fehler",
|
||||||
"organization-added": "Organisation hinzugefügt",
|
"invalid": "Ungültig",
|
||||||
"organization-deleted": "Organisation gelöscht",
|
"invalid-mail-reset": "Das ist keine gültige E-Mail",
|
||||||
"organization-detail-is-being-loaded": "Organisationsdetails werden geladen ...",
|
"just-enter-how-many-you-want-and-the-system-will-create-them": "Gebe einfach ein, wie viele Blankokarten das System erstellen soll.",
|
||||||
"organization-is-being-added": "Organisation wird hinzugefügt ...",
|
"key": "Schlüssel",
|
||||||
"organization-name-is-required": "Der Name muss angegeben werden",
|
"laeufer-hinzufuegen": "Läufer:in hinzufügen",
|
||||||
"organizations": "Organisationen",
|
"laeufer-importieren": "Läufer:innen importieren",
|
||||||
"organizations-are-being-loaded": "Organisationen werden geladen ...",
|
"laptime": "Rundenzeit",
|
||||||
"orgs": "Organisationen",
|
"last-name": "Nachname",
|
||||||
"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!",
|
"last-name-is-required": "Nachname muss angegeben werden",
|
||||||
"password": "Passwort",
|
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
|
||||||
"password-changed": "Passwort wurde aktualisiert!",
|
"license": "Lizenz",
|
||||||
"password-is-required": "Passwort muss angegeben werden",
|
"licenses-are-being-loaded": "Lizenzen werden geladen...",
|
||||||
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
|
"loading-cards": "Läuferkarten werden geladen",
|
||||||
"password-reset-in-progress": "Passwort wird zurückgesetzt...",
|
"loading-contact-details": "Kontaktdaten werden geladen ...",
|
||||||
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
|
"loading-donation-details": "Lade Sponsoringdetails",
|
||||||
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
|
"loading-donor-details": "Lade Details",
|
||||||
"passwords-dont-match": "Die Passwörter stimmen nicht überein.",
|
"loading-group-detail": "Lade Gruppendetails...",
|
||||||
"pdf-generation-failed": "PDF Generierung fehlgeschlagen!",
|
"loading-profile-data": "Lade Profildaten",
|
||||||
"pdf-successfully-generated": "PDF wurde erfolgreich generiert!",
|
"loading-runners": "Läufer:innen werden geladen...",
|
||||||
"pdfs-successfully-generated": "Alle PDFs wurden generiert!",
|
"loading-station-details": "Lade Scanstation-Details ...",
|
||||||
"per-kilometer": "pro Kilometer",
|
"log_in": "Anmelden",
|
||||||
"permissions": "Berechtigungen",
|
"log_in_to_your_account": "Bitte melde dich an",
|
||||||
"permissions-updated": "Berechtigungen aktualisiert!",
|
"login_is_checked": "Login wird überprüft",
|
||||||
"phone": "Telefon",
|
"logout": "Abmelden",
|
||||||
"please-copy-the-token-and-store-it-somewhere-save": "Bitte kopiere dir den Token und bewahre ihn gut auf.",
|
"mail-validation-in-progress": "E-Mail Verifizierung läuft... ",
|
||||||
"please-provide-a-password": "Bitte gebe ein Passwort an...",
|
"manage-admin-users": "Nutzer verwalten",
|
||||||
"please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen",
|
"middle-name": "Mittelname",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.",
|
"minimum-lap-time-in-s": "Minimale Rundenzeit (in Sekunden)",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-scan": "Bitte gebe alle notwendigen Informationen an, um einen neuen Scan zu erstellen.",
|
"minimum-lap-time-must-be-a-positive-number-or-0": "Die minimale Rundenzeit muss eine positive Zahl oder 0 sein",
|
||||||
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
|
"must-be-at-least-10-characters-long": "Passwort muss mindestens 10 Zeichen lang sein!",
|
||||||
"please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.",
|
"must-contain-a-lowercase-letter": "Passwort muss einen Großbuchstaben enthalten!",
|
||||||
"please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.",
|
"must-contain-a-number": "Passwort muss eine Zahl enthalten!",
|
||||||
"please-provide-the-required-information-to-add-a-new-organization": "Bitte gebe alle nötigen Informationen an, im die neue Organisation zu erstellen.",
|
"must-contain-a-uppercase-letter": "Passwort muss einen Kleinbuchstaben enthalten!",
|
||||||
"please-provide-the-required-information-to-add-a-new-runner": "Bitte die benötigten Informationen angeben.",
|
"name": "Name",
|
||||||
"please-provide-the-required-information-to-add-a-new-team": "Bitte gebe alle nötigen Informationen an, im das neue Team zu erstellen.",
|
"name-is-required": "Der Gruppenname muss angegeben werden",
|
||||||
"please-provide-the-required-information-to-add-a-new-track": "Bitte die benötigten Informationen angeben.",
|
"new-password": "Neues Passwort",
|
||||||
"please-provide-the-required-information-to-add-a-new-user": "Bitte gebe alle nötigen Informationen an, im die neue Benutzer:in zu erstellen.",
|
"no-contact-found": "Keine Kontakte gefunden",
|
||||||
"please-provide-the-required-information-to-create-a-new-scanstation": "Bitte gebe alle für eine Scannerstation notwendigen Informationen an",
|
"no-contact-selected": "Kein Kontakt ausgewählt",
|
||||||
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
|
"no-contact-specified": "Kein Kontakt angegeben",
|
||||||
"privacy": "Datenschutz",
|
"no-donors-found": "Keine Spender:innen gefunden",
|
||||||
"privacy-loading": "Datenschutzerklärung lädt...",
|
"no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢",
|
||||||
"profile": "Profil",
|
"no-organization-or-team-found": "Keine Organisationen oder Teams gefunden",
|
||||||
"profile-picture": "Profilbild",
|
"no-organization-specified": "Keine Organisation angegeben",
|
||||||
"profile-updated": "Profil wurde aktualisiert!",
|
"no-organizations-found": "Keine Organisationen gefunden",
|
||||||
"read-license": "Lizenz-Text lesen",
|
"no-runners-found": "Keine Läufer:innen gefunden",
|
||||||
"receipt-needed": "Spendenquittung benötigt",
|
"no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.",
|
||||||
"repo_link": "Link",
|
"non-blanko": "Keine/Blankokarte",
|
||||||
"request-a-new-reset-mail": "Neue Reset-Mail anfordern",
|
"open": "OFFEN",
|
||||||
"reset-my-password": "Passwort zurücksetzen",
|
"organization": "Organisation",
|
||||||
"reset-password": "Passwort zurücksetzen",
|
"organization-added": "Organisation hinzugefügt",
|
||||||
"runner": "Läufer:in",
|
"organization-deleted": "Organisation gelöscht",
|
||||||
"runner-added": "Läufer:in hinzugefügt",
|
"organization-detail-is-being-loaded": "Organisationsdetails werden geladen ...",
|
||||||
"runner-import": "Läufer:innen Import",
|
"organization-is-being-added": "Organisation wird hinzugefügt ...",
|
||||||
"runner-is-being-added": "Läufer:in wird hinzugefügt...",
|
"organization-name-is-required": "Der Name muss angegeben werden",
|
||||||
"runner-updated": "Läufer:in aktualisiert!",
|
"organizations": "Organisationen",
|
||||||
"runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen",
|
"organizations-are-being-loaded": "Organisationen werden geladen ...",
|
||||||
"runners": "Läufer",
|
"orgs": "Organisationen",
|
||||||
"runners-are-being-imported": "Läufer:innen werden importiert ...",
|
"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!",
|
||||||
"runners-are-being-loaded": "Läufer:innen werden geladen ...",
|
"paid": "BEZAHLT",
|
||||||
"save": "Speichern",
|
"paid-amount": "Gezahlter Betrag",
|
||||||
"save-changes": "Änderungen speichern",
|
"password": "Passwort",
|
||||||
"scan-added": "Scan hinzugefügt",
|
"password-changed": "Passwort wurde aktualisiert!",
|
||||||
"scan-is-being-updated": "Scan wird aktualisiert",
|
"password-is-required": "Passwort muss angegeben werden",
|
||||||
"scan-with-fixed-distance": "Scan mit Festdistanz",
|
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
|
||||||
"scans": "Scans",
|
"password-reset-in-progress": "Passwort wird zurückgesetzt...",
|
||||||
"scans-are-being-loaded": "Scans werden geladen",
|
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
|
||||||
"scanstation": "Scanner Station",
|
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
|
||||||
"scanstation-added": "Station wurde erstellt",
|
"passwords-dont-match": "Die Passwörter stimmen nicht überein!",
|
||||||
"scanstation-is-being-added": "Scannerstation wird angelegt...",
|
"payment-amount-must-be-greater-than-0-00eur": "Der Zahlungsbetrag muss größer als 0.00€ sein!",
|
||||||
"scanstations": "Scanner Stationen",
|
"pdf-generation-failed": "PDF Generierung fehlgeschlagen!",
|
||||||
"scanstations-are-being-loaded": "Scannerstationen werden geladen...",
|
"pdf-successfully-generated": "PDF wurde erfolgreich generiert!",
|
||||||
"search-for-an-organization-by-name-or-id": "Suche eine Organisation (via Name oder Id)",
|
"pdfs-successfully-generated": "Alle PDFs wurden generiert!",
|
||||||
"search-for-an-organization-or-team-by-name-or-id": "Suche eine Organisation oder ein Team (via Name oder Id)",
|
"per-kilometer": "pro Kilometer",
|
||||||
"search-for-donor-name-or-id": "Suche eine Spender:in (via Name oder Id)",
|
"permissions": "Berechtigungen",
|
||||||
"search-for-permission": "Berechtigungen durchsuchen",
|
"permissions-updated": "Berechtigungen aktualisiert!",
|
||||||
"search-for-runner-by-name-or-id": "Suche eine Läufer:in (via Name oder Id)",
|
"phone": "Telefon",
|
||||||
"select-all": "Alle auswählen",
|
"please-copy-the-token-and-store-it-somewhere-save": "Bitte kopiere dir den Token und bewahre ihn gut auf.",
|
||||||
"select-language": "Sprache auswählen",
|
"please-provide-a-password": "Bitte gebe ein Passwort an...",
|
||||||
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
|
"please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen",
|
||||||
"set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen",
|
"please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.",
|
||||||
"settings": "Einstellungen",
|
"please-provide-the-nessecary-information-to-create-a-new-scan": "Bitte gebe alle notwendigen Informationen an, um einen neuen Scan zu erstellen.",
|
||||||
"settings-for-your-profile": "Die Einstellungen deines Accounts",
|
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
|
||||||
"something-about-the-group": "Infos zur Gruppe",
|
"please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.",
|
||||||
"stats-are-being-loaded": "Die Statistiken werden geladen...",
|
"please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.",
|
||||||
"status": "Status",
|
"please-provide-the-required-information-to-add-a-new-organization": "Bitte gebe alle nötigen Informationen an, im die neue Organisation zu erstellen.",
|
||||||
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
|
"please-provide-the-required-information-to-add-a-new-runner": "Bitte die benötigten Informationen angeben.",
|
||||||
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
|
"please-provide-the-required-information-to-add-a-new-team": "Bitte gebe alle nötigen Informationen an, im das neue Team zu erstellen.",
|
||||||
"team": "Team",
|
"please-provide-the-required-information-to-add-a-new-track": "Bitte die benötigten Informationen angeben.",
|
||||||
"team-detail-is-being-loaded": "Team wird geladen...",
|
"please-provide-the-required-information-to-add-a-new-user": "Bitte gebe alle nötigen Informationen an, im die neue Benutzer:in zu erstellen.",
|
||||||
"team-name": "Teamname",
|
"please-provide-the-required-information-to-create-a-new-scanstation": "Bitte gebe alle für eine Scannerstation notwendigen Informationen an",
|
||||||
"team-name-is-required": "Teamname ist erforderlich",
|
"please-provide-the-required-information-to-create-a-new-statsclient": "Bitte gebe alle für einen Statsclient notwendigen Informationen an",
|
||||||
"teams": "Teams",
|
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
|
||||||
"teams-are-being-loaded": "Teams werden geladen ...",
|
"please-wait-a-moment-your-login-is-still-being-processed": "Bitte warte einen Moment, deine Anmeldung wird verarbeitet",
|
||||||
"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...",
|
"prefix": "Prefix",
|
||||||
"the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.",
|
"privacy": "Datenschutz",
|
||||||
"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!",
|
"privacy-loading": "Datenschutzerklärung lädt...",
|
||||||
"there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.",
|
"profile": "Profil",
|
||||||
"there-are-no-donations-yet": "Es gibt noch keine Sponsorings",
|
"profile-deleted": "Profil gelöscht!",
|
||||||
"there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen",
|
"profile-picture": "Profilbild",
|
||||||
"there-are-no-groups-yet": "Es gibt noch keine Gruppen",
|
"profile-updated": "Profil wurde aktualisiert!",
|
||||||
"there-are-no-organizations-added-yet": "Es wurden noch keine Organisationen hinzugefügt.",
|
"read-license": "Lizenz-Text lesen",
|
||||||
"there-are-no-runners-added-yet": "Es wurden noch keine Läufer:innen hinzugefügt.",
|
"receipt-needed": "Spendenquittung benötigt",
|
||||||
"there-are-no-scans-yet": "Es gibt noch keine Scans",
|
"repo_link": "Link",
|
||||||
"there-are-no-teams-added-yet": "Es wurden noch keine Teams hinzugefügt.",
|
"request-a-new-reset-mail": "Neue Reset-Mail anfordern",
|
||||||
"there-are-no-users-added-yet": "Es wurden noch keine Benutzer hinzugefügt.",
|
"reset-my-password": "Passwort zurücksetzen",
|
||||||
"this-might-take-a-moment": "Das könnte einen kleinen Moment dauern",
|
"reset-password": "Passwort zurücksetzen",
|
||||||
"this-scanstation-is": "Diese Station ist",
|
"runner": "Läufer:in",
|
||||||
"token": "Token",
|
"runner-added": "Läufer:in hinzugefügt",
|
||||||
"total-distance": "gelaufene Strecke",
|
"runner-import": "Läufer:innen Import",
|
||||||
"total-donation-amount": "Gesamtbetrag",
|
"runner-is-being-added": "Läufer:in wird hinzugefügt...",
|
||||||
"total-donations": "Spendensumme",
|
"runner-updated": "Läufer:in aktualisiert!",
|
||||||
"total-scans": "gesamte Scans",
|
"runnercards": "Laeuferkarten",
|
||||||
"track": "Track",
|
"runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen",
|
||||||
"track-added": "Track hinzugefügt",
|
"runners": "Läufer",
|
||||||
"track-data-is-being-loaded": "Trackdaten werden geladen",
|
"runners-are-being-imported": "Läufer:innen werden importiert ...",
|
||||||
"track-is-being-added": "Track wird hinzugefügt...",
|
"runners-are-being-loaded": "Läufer:innen werden geladen ...",
|
||||||
"track-length-in-m": "Tracklänge (in Metern)",
|
"save": "Speichern",
|
||||||
"track-length-must-be-greater-than-0": "Die Länge muss größer als 0 (Meter) sein",
|
"save-changes": "Änderungen speichern",
|
||||||
"track-name": "Trackname",
|
"scan-added": "Scan hinzugefügt",
|
||||||
"track-name-must-not-be-empty": "Der Name muss angegeben werden",
|
"scan-is-being-updated": "Scan wird aktualisiert",
|
||||||
"tracks": "Tracks",
|
"scan-with-fixed-distance": "Scan mit Festdistanz",
|
||||||
"update-password": "Passwort ändern",
|
"scans": "Scans",
|
||||||
"updated-contact": "Kontakt aktualisiert!",
|
"scans-are-being-loaded": "Scans werden geladen",
|
||||||
"updated-donor": "Sponsor:in wurde aktualisiert",
|
"scanstation": "Scanner Station",
|
||||||
"updated-organization": "Organisation wurde aktualisiert",
|
"scanstation-added": "Station wurde erstellt",
|
||||||
"updated-scan": "Scan wurde aktualisiert",
|
"scanstation-is-being-added": "Scannerstation wird angelegt...",
|
||||||
"updateing-group": "Gruppe wird aktualisiert...",
|
"scanstations": "Scanner Stationen",
|
||||||
"updating-organization": "Organisation wird aktualisiert",
|
"scanstations-are-being-loaded": "Scannerstationen werden geladen...",
|
||||||
"updating-permissions": "Berechtigungen werden aktualisiert...",
|
"search-for-an-organization-by-name-or-id": "Suche eine Organisation (via Name oder Id)",
|
||||||
"updating-runner": "Läufer:in wird aktualisiert.",
|
"search-for-an-organization-or-team-by-name-or-id": "Suche eine Organisation oder ein Team (via Name oder Id)",
|
||||||
"updating-user": "Benutzer:in wird aktualisiert...",
|
"search-for-donor-name-or-id": "Suche eine Spender:in (via Name oder Id)",
|
||||||
"updating-your-profile": "Profil wird aktualisiert...",
|
"search-for-permission": "Berechtigungen durchsuchen",
|
||||||
"user-added": "Benutzer hinzugefügt",
|
"search-for-runner-by-name-or-id": "Suche eine Läufer:in (via Name oder Id)",
|
||||||
"user-groups": "Benutzergruppen",
|
"select-all": "Alle auswählen",
|
||||||
"user-is-being-added": "Benutzer wird hinzugefügt ...",
|
"select-language": "Sprache auswählen",
|
||||||
"user-updated": "Benutzer:in wurde aktualisiert",
|
"selfservice-registration": "Selfservice Registrierung",
|
||||||
"username": "Benutzername",
|
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
|
||||||
"users": "Benutzer",
|
"set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen",
|
||||||
"valid": "Gültig",
|
"settings": "Einstellungen",
|
||||||
"valid-city-is-required": "Du musst eine Stadt angeben",
|
"settings-for-your-profile": "Die Einstellungen deines Accounts",
|
||||||
"valid-email-is-required": "Es wird eine valide E-Mail Adresse benötigt",
|
"something-about-the-group": "Infos zur Gruppe",
|
||||||
"valid-international-phone-number-is-required": "Du musst eine Telefonnummer im internationalen Format angeben...",
|
"sponsoring-quittungs-liste_herunterladen": "Sponsoring-Quittungs-Liste herunterladen",
|
||||||
"valid-zipcode-postal-code-is-required": "Du musst eine valide Postleitzahl angeben",
|
"sponsorings": "Sponsoringerklaerungen",
|
||||||
"verfuegbare": "Verfügbar",
|
"stats-are-being-loaded": "Die Statistiken werden geladen...",
|
||||||
"welcome_wavinghand": "Willkommen 👋",
|
"statsclient-deleted": "Statsclient wurde gelöscht",
|
||||||
"yes-i-copied-the-token": "Ja, ich habe den Token kopiert",
|
"statsclient-is-being-added": "Statsclient wird angelegt...",
|
||||||
"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!",
|
"statsclients": "Statsclient (aka Beamershow)",
|
||||||
"you-can-now-use-your-new-password-to-log-in-to-your-account": "Du kannst dich jetzt mit deinem neuen Passwort anmelden! 🎉",
|
"statsclients-are-being-loaded": "Statsclients werden geladen",
|
||||||
"you-dont-have-any-scanstations-yet": "Es gibt noch keine Scannerstationen",
|
"status": "Status",
|
||||||
"you-have-to-provide-an-organization": "Du musst eine Organisation angeben",
|
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
|
||||||
"zip-postal-code": "Postleitzahl"
|
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
|
||||||
}
|
"team": "Team",
|
||||||
|
"team-added": "Team wurde hinzugefügt",
|
||||||
|
"team-deleted": "Team gelöscht",
|
||||||
|
"team-detail-is-being-loaded": "Team wird geladen...",
|
||||||
|
"team-is-being-added": "Team wird erstellt...",
|
||||||
|
"team-name": "Teamname",
|
||||||
|
"team-name-is-required": "Teamname ist erforderlich",
|
||||||
|
"teams": "Teams",
|
||||||
|
"teams-are-being-loaded": "Teams 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...",
|
||||||
|
"the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.",
|
||||||
|
"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!",
|
||||||
|
"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!",
|
||||||
|
"there-are-no-cards-yet": "Es gibt noch keine Läuferkarten.",
|
||||||
|
"there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.",
|
||||||
|
"there-are-no-donations-yet": "Es gibt noch keine Sponsorings",
|
||||||
|
"there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen",
|
||||||
|
"there-are-no-groups-yet": "Es gibt noch keine Gruppen",
|
||||||
|
"there-are-no-organizations-added-yet": "Es wurden noch keine Organisationen hinzugefügt.",
|
||||||
|
"there-are-no-runners-added-yet": "Es wurden noch keine Läufer:innen hinzugefügt.",
|
||||||
|
"there-are-no-scans-yet": "Es gibt noch keine Scans",
|
||||||
|
"there-are-no-teams-added-yet": "Es wurden noch keine Teams hinzugefügt.",
|
||||||
|
"there-are-no-users-added-yet": "Es wurden noch keine Benutzer hinzugefügt.",
|
||||||
|
"this-card-is": "Diese Karte ist",
|
||||||
|
"this-might-take-a-moment": "Das könnte einen kleinen Moment dauern",
|
||||||
|
"this-scanstation-is": "Diese Station ist",
|
||||||
|
"token": "Token",
|
||||||
|
"total-distance": "gelaufene Strecke",
|
||||||
|
"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
-391
@@ -1,392 +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-donation": "Add donation",
|
"add-card": "Add Card",
|
||||||
"add-donor": "add donor",
|
"add-donation": "Add donation",
|
||||||
"add-scan": "Add scan",
|
"add-donor": "Add donor",
|
||||||
"add-the-first-scanstation": "Add your first scanstation.",
|
"add-or-update-a-payment": "Add or update a payment",
|
||||||
"add-user-group": "Add User Group",
|
"add-scan": "Add scan",
|
||||||
"add-your-first-contact": "Add your first contact",
|
"add-the-first-scanstation": "Add your first scanstation.",
|
||||||
"add-your-first-donor": "add your first donor",
|
"add-the-first-statsclient": "Add your first statsclient.",
|
||||||
"add-your-first-group": "Add your first group",
|
"add-user-group": "Add User Group",
|
||||||
"add-your-first-organization": "Add your first organization",
|
"add-your-first-card": "Add your first card",
|
||||||
"add-your-first-runner": "Add your first runner",
|
"add-your-first-contact": "Add your first contact",
|
||||||
"add-your-first-team": "Add your first team",
|
"add-your-first-donor": "add your first donor",
|
||||||
"add-your-first-track": "Add your first track.",
|
"add-your-first-group": "Add your first group",
|
||||||
"add-your-first-user": "Add your first user",
|
"add-your-first-organization": "Add your first organization",
|
||||||
"add-your-fist-donation": "Add your fist donation",
|
"add-your-first-runner": "Add your first runner",
|
||||||
"add-your-fist-scan": "Add your fist scan",
|
"add-your-first-team": "Add your first team",
|
||||||
"adding-scan": "Adding Scan",
|
"add-your-first-track": "Add your first track.",
|
||||||
"address": "Address",
|
"add-your-first-user": "Add your first user",
|
||||||
"address-is-required": "Address is required",
|
"add-your-fist-donation": "Add your fist donation",
|
||||||
"after-deletion-we-cant-restore-your-old-profile": "After deletion we can't restore your old profile!",
|
"add-your-fist-scan": "Add your fist 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.",
|
"adding-card": "Adding Card",
|
||||||
"all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well",
|
"adding-donation": "Adding donation...",
|
||||||
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
|
"adding-scan": "Adding Scan",
|
||||||
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!",
|
"address": "Address",
|
||||||
"amount-per-kilometer": "Amount per kilometer",
|
"address-is-required": "Address is required",
|
||||||
"apartment-suite-etc": "Apartment, suite, etc.",
|
"after-deletion-we-cant-restore-your-old-profile": "After deletion we can't restore your old profile!",
|
||||||
"application_name": "Lauf für Kaya! - Admin",
|
"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.",
|
||||||
"applying-changes": "Applying Changes",
|
"all": "all",
|
||||||
"attention": "Attention!",
|
"all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well",
|
||||||
"author": "Author",
|
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
|
||||||
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.",
|
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!",
|
||||||
"by": "by",
|
"already-paid": "Already paid",
|
||||||
"cancel": "Cancel",
|
"amount": "Amount",
|
||||||
"cancel-delete": "Cancel Delete",
|
"amount-per-kilometer": "Amount per kilometer",
|
||||||
"cancel-keep-donor": "Cancel, keep donor",
|
"apartment-suite-etc": "Apartment, suite, etc.",
|
||||||
"cancel-keep-my-profile": "Cancel, keep my profile",
|
"application_name": "Lauf für Kaya! - Admin",
|
||||||
"cancel-keep-organization": "Cancel, keep organization",
|
"applying-changes": "Applying Changes",
|
||||||
"cancel-keep-team": "Cancel, keep team",
|
"attention": "Attention!",
|
||||||
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
|
"author": "Author",
|
||||||
"change-your-password-here": "Change your password here",
|
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.",
|
||||||
"changing-your-password": "Changing your password",
|
"by": "by",
|
||||||
"city": "City",
|
"cancel": "Cancel",
|
||||||
"click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard",
|
"cancel-delete": "Cancel Delete",
|
||||||
"close": "Close",
|
"cancel-keep-donor": "Cancel, keep donor",
|
||||||
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
|
"cancel-keep-my-profile": "Cancel, keep my profile",
|
||||||
"confirm": "Confirm",
|
"cancel-keep-organization": "Cancel, keep organization",
|
||||||
"confirm-delete": "Confirm Delete",
|
"cancel-keep-statsclient": "Cancel and keep statsclient",
|
||||||
"confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations",
|
"cancel-keep-team": "Cancel, keep team",
|
||||||
"confirm-delete-my-user-profile": "Confirm, delete my user profile",
|
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
|
||||||
"confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.",
|
"card-added": "Card added",
|
||||||
"confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.",
|
"card-deleted": "Card deleted",
|
||||||
"confirm-deletion": "Confirm Deletion",
|
"card-updated": "Card updated",
|
||||||
"confirm-the-new-password": "Confirm the new password",
|
"cards": "Cards",
|
||||||
"contact": "Contact",
|
"certificates": "Certificates",
|
||||||
"contact-deleted": "Contact deleted",
|
"change-your-password-here": "Change your password here",
|
||||||
"contact-information": "Contact Information",
|
"changing-your-password": "Changing your password",
|
||||||
"contact-is-being-updated": "Contact is being updated...",
|
"city": "City",
|
||||||
"contact-is-not-a-member-in-any-group": "Contact is not a member in any group",
|
"click-to-copy-the-link-into-your-clipboard": "Click to copy the link into your clipboard",
|
||||||
"contacts": "Contacts",
|
"click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard",
|
||||||
"contacts-are-being-loaded": "contacts are being loaded...",
|
"close": "Close",
|
||||||
"copied-token-to-clipboard": "Copied token to clipboard",
|
"code": "Code",
|
||||||
"count_organizations": "# Organizations",
|
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
|
||||||
"count_teams": "# Teams",
|
"confirm": "Confirm",
|
||||||
"create": "Create",
|
"confirm-delete": "Confirm Delete",
|
||||||
"create-a-new": "Create a new",
|
"confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations",
|
||||||
"create-a-new-contact": "Create a new contact",
|
"confirm-delete-my-user-profile": "Confirm, delete my user profile",
|
||||||
"create-a-new-distance-donation": "Create a new distance donation",
|
"confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.",
|
||||||
"create-a-new-donor": "Create a new donor",
|
"confirm-delete-statsclient": "Confirm, delete statsclient",
|
||||||
"create-a-new-fixed-donation": "Create a new fixed donation",
|
"confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.",
|
||||||
"create-a-new-organization": "Create a new Organization",
|
"confirm-deletion": "Confirm Deletion",
|
||||||
"create-a-new-runner": "Create a new Runner",
|
"confirm-the-new-password": "Confirm the new password",
|
||||||
"create-a-new-scan-fixed-only": "Create a new scan (fixed only)",
|
"contact": "Contact",
|
||||||
"create-a-new-scanstation": "Create a new station",
|
"contact-added": "Contact added",
|
||||||
"create-a-new-team": "Create a new team",
|
"contact-deleted": "Contact deleted",
|
||||||
"create-a-new-track": "Create a new Track",
|
"contact-information": "Contact Information",
|
||||||
"create-a-new-user": "Create a new User",
|
"contact-is-being-added": "Contact is being added...",
|
||||||
"create-a-new-user-group": "Create a new user group",
|
"contact-is-being-updated": "Contact is being updated...",
|
||||||
"create-organization": "Create Organization",
|
"contact-is-not-a-member-in-any-group": "Contact is not a member in any group",
|
||||||
"create-team": "Create Team",
|
"contacts": "Contacts",
|
||||||
"create-track": "Create Track",
|
"contacts-are-being-loaded": "contacts are being loaded...",
|
||||||
"create-user": "Create User",
|
"copied-link-to-clipboard": "Copied link to clipboard",
|
||||||
"credits": "Credits",
|
"copied-token-to-clipboard": "Copied token to clipboard",
|
||||||
"csv_import__class": "Class",
|
"count_organizations": "# Organizations",
|
||||||
"csv_import__firstname": "Firstname",
|
"count_teams": "# Teams",
|
||||||
"csv_import__lastname": "Lastname",
|
"create": "Create",
|
||||||
"csv_import__middlename": "Middlename",
|
"create-a-new": "Create a new",
|
||||||
"csv_import__team": "Team",
|
"create-a-new-card": "Create a new card",
|
||||||
"danger-zone": "Danger zone",
|
"create-a-new-contact": "Create a new contact",
|
||||||
"dashboard-greeting": "Hello",
|
"create-a-new-distance-donation": "Create a new distance donation",
|
||||||
"dashboard-title": "Dashboard",
|
"create-a-new-donor": "Create a new donor",
|
||||||
"datatable": {
|
"create-a-new-fixed-donation": "Create a new fixed donation",
|
||||||
"search": "🔍 Search...",
|
"create-a-new-organization": "Create a new Organization",
|
||||||
"sort_column_ascending": "Sort column ascending",
|
"create-a-new-runner": "Create a new Runner",
|
||||||
"sort_column_descending": "Sort column descending",
|
"create-a-new-scan-fixed-only": "Create a new scan (fixed only)",
|
||||||
"previous": "Previous",
|
"create-a-new-scanstation": "Create a new station",
|
||||||
"next": "Next",
|
"create-a-new-statsclient": "Create a new statsclient",
|
||||||
"page": "Page",
|
"create-a-new-team": "Create a new team",
|
||||||
"showing": "Showing",
|
"create-a-new-track": "Create a new Track",
|
||||||
"records": "Records",
|
"create-a-new-user": "Create a new User",
|
||||||
"of": "of",
|
"create-a-new-user-group": "Create a new user group",
|
||||||
"to": "to",
|
"create-and-generate-pdf": "Create and generate PDF",
|
||||||
"loading": "Loading...",
|
"create-bulk-blanco-cards": "Create bulk blanco cards",
|
||||||
"no_matching_records_found": "No matching records found",
|
"create-bulk-cards": "Add blanco cards",
|
||||||
"an_error_happened_while_fetching_the_data": "An error happened while fetching the data"
|
"create-organization": "Create Organization",
|
||||||
},
|
"create-team": "Create Team",
|
||||||
"delete": "Delete",
|
"create-track": "Create Track",
|
||||||
"delete-contact": "Delete Contact",
|
"create-user": "Create User",
|
||||||
"delete-donation": "Delete Donation",
|
"create-without-pdf": "Create without PDF",
|
||||||
"delete-donor": "Delete donor",
|
"created-blanco-cards": "Created blanco cards",
|
||||||
"delete-group": "Delete Group",
|
"creating-blanco-cards": "Creating blanco cards",
|
||||||
"delete-organization": "Delete Organization",
|
"credits": "Credits",
|
||||||
"delete-profile": "Delete Profile",
|
"csv_import__class": "Class",
|
||||||
"delete-runner": "Delete Runner",
|
"csv_import__firstname": "Firstname",
|
||||||
"delete-scan": "Delete scan",
|
"csv_import__lastname": "Lastname",
|
||||||
"delete-station": "Delete station",
|
"csv_import__middlename": "Middlename",
|
||||||
"delete-team": "Delete Team",
|
"csv_import__team": "Team",
|
||||||
"delete-user": "Delete User",
|
"danger-zone": "Danger zone",
|
||||||
"deleted-scan": "Deleted scan",
|
"dashboard-greeting": "Hello",
|
||||||
"dependency_name": "Name",
|
"dashboard-title": "Dashboard",
|
||||||
"description": "description",
|
"datatable": {
|
||||||
"description-optional": "Description (optional)",
|
"search": "🔍 Search...",
|
||||||
"deselect-all": "deselect all",
|
"sort_column_ascending": "Sort column ascending",
|
||||||
"details": "Details",
|
"sort_column_descending": "Sort column descending",
|
||||||
"disabled": "disabled",
|
"previous": "Previous",
|
||||||
"distance": "Distance",
|
"next": "Next",
|
||||||
"distance-donation": "distance donation",
|
"page": "Page",
|
||||||
"distance-in-km": "Distance in km",
|
"showing": "Showing",
|
||||||
"distance-track": "Distance (+Track)",
|
"records": "Records",
|
||||||
"do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?",
|
"of": "of",
|
||||||
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
|
"to": "to",
|
||||||
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
|
"loading": "Loading...",
|
||||||
"do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations",
|
"no_matching_records_found": "No matching records found",
|
||||||
"documentation": "Documentation",
|
"an_error_happened_while_fetching_the_data": "An error happened while fetching the data"
|
||||||
"donation-amount": "Donation amount",
|
},
|
||||||
"donation-amount-must-be-greater-that-0-00eur": "Donation amount must be greater that 0.00€",
|
"delete": "Delete",
|
||||||
"donations": "Donations",
|
"delete-contact": "Delete Contact",
|
||||||
"donor": "Donor",
|
"delete-donation": "Delete Donation",
|
||||||
"donor-added": "Donor added",
|
"delete-donor": "Delete donor",
|
||||||
"donor-deleted": "donor deleted",
|
"delete-group": "Delete Group",
|
||||||
"donor-has-no-associated-donations": "Donor has no associated donations.",
|
"delete-organization": "Delete Organization",
|
||||||
"donor-is-being-added": "Donor is being added...",
|
"delete-profile": "Delete Profile",
|
||||||
"donor-is-being-updated": "Donor is being updated",
|
"delete-runner": "Delete Runner",
|
||||||
"donors": "Donors",
|
"delete-scan": "Delete scan",
|
||||||
"donors-are-being-loaded": "donors are being loaded",
|
"delete-station": "Delete station",
|
||||||
"dont-have-your-email-connected": "Don't have your email connected?",
|
"delete-statsclient": "Delete statsclient",
|
||||||
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
|
"delete-team": "Delete Team",
|
||||||
"e-mail-adress": "E-Mail Adress",
|
"delete-user": "Delete User",
|
||||||
"edit": "Edit",
|
"deleted-scan": "Deleted scan",
|
||||||
"edit-permissions": "edit permissions",
|
"dependency_name": "Name",
|
||||||
"email_address_or_username": "Email / username",
|
"description": "description",
|
||||||
"enabled": "enabled",
|
"description-optional": "Description (optional)",
|
||||||
"enabled_large": "Enabled",
|
"deselect-all": "deselect all",
|
||||||
"english": "English",
|
"details": "Details",
|
||||||
"error-during-import": "Error during import",
|
"disabled": "disabled",
|
||||||
"error-whyile-copying-to-clipboard": "Error while copying to clipboard",
|
"distance": "Distance",
|
||||||
"error_on_login": "Error on login",
|
"distance-donation": "distance donation",
|
||||||
"erteilte": "Directly granted",
|
"distance-in-km": "Distance in km",
|
||||||
"everything-concerning-your-profile": "Everything concerning your profile",
|
"distance-track": "Distance (+Track)",
|
||||||
"everything-is-more-fun-together": "everything is more fun together 🏃♂️🏃♀️🏃♂️",
|
"do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?",
|
||||||
"faq": "FAQ",
|
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
|
||||||
"filter-by-organization-team": "Filter by Organization/ Team",
|
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
|
||||||
"first-name": "First name",
|
"do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations",
|
||||||
"first-name-is-required": "First Name is required",
|
"documentation": "Documentation",
|
||||||
"first-scan-of-the-day": "First scan of the day.",
|
"donation-amount": "Donation amount",
|
||||||
"fixed-donation": "fixed donation",
|
"donation-amount-must-be-greater-that-0-00eur": "Donation amount must be greater that 0.00€",
|
||||||
"forgot_password": "Forgot your password?",
|
"donation-deleted": "Donation deleted",
|
||||||
"geerbte": "inherited",
|
"donation-updated": "Donation updated",
|
||||||
"general-stats": "General Stats",
|
"donation_added": "Donation_added",
|
||||||
"general_promise_error": "😢 Error",
|
"donations": "Donations",
|
||||||
"generate-sponsoring-contract": "generate sponsoring contract",
|
"donor": "Donor",
|
||||||
"generate-sponsoring-contracts": "generate sponsoring contracts",
|
"donor-added": "Donor added",
|
||||||
"generating-pdf": "generating PDF...",
|
"donor-deleted": "donor deleted",
|
||||||
"generating-pdfs": "generating PDFs...",
|
"donor-has-no-associated-donations": "Donor has no associated donations.",
|
||||||
"generic-ui-logic-error": "Something went wrong in the UI logic",
|
"donor-is-being-added": "Donor is being added...",
|
||||||
"german": "German",
|
"donor-is-being-updated": "Donor is being updated",
|
||||||
"go-to-login": "Go To Login",
|
"donors": "Donors",
|
||||||
"goback": "Go Home",
|
"donors-are-being-loaded": "donors are being loaded",
|
||||||
"granted": "granted",
|
"dont-have-your-email-connected": "Don't have your email connected?",
|
||||||
"group": "Group",
|
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
|
||||||
"group-added": "Group added",
|
"e-mail-adress": "E-Mail Adress",
|
||||||
"group-is-being-added": "Group is being added...",
|
"edit": "Edit",
|
||||||
"group-name-is-required": "Group name is required",
|
"edit-a-card": "Edit a card",
|
||||||
"group-updated": "group updated",
|
"edit-permissions": "edit permissions",
|
||||||
"groups": "Groups",
|
"email_address_or_username": "Email / username",
|
||||||
"groups-are-being-loaded": "Groups are being loaded",
|
"enabled": "enabled",
|
||||||
"home": "Home",
|
"enabled_large": "Enabled",
|
||||||
"icon-image-credits": "We also want to thank these projects for illustrations and icons:",
|
"english": "English",
|
||||||
"import-finished": "Import finished",
|
"enter-payment": "Enter payment",
|
||||||
"import-runners": "Import runners",
|
"error-during-import": "Error during import",
|
||||||
"import__target-organization": "Target Organization",
|
"error-whyile-copying-to-clipboard": "Error while copying to clipboard",
|
||||||
"imprint": "Imprint",
|
"error_on_login": "Error on login",
|
||||||
"imprint-loading": "Imprint loading...",
|
"erteilte": "Directly granted",
|
||||||
"inactive": "Inactive",
|
"everything-concerning-your-profile": "Everything concerning your profile",
|
||||||
"installed-version": "Installed version",
|
"everything-is-more-fun-together": "everything is more fun together 🏃♂️🏃♀️🏃♂️",
|
||||||
"internal-error": "Internal Error",
|
"faq": "FAQ",
|
||||||
"invalid": "Invalid",
|
"filename_sponsoringquittungsliste": "DonorReceiptList",
|
||||||
"invalid-mail-reset": "the provided email is invalid",
|
"filter-by-organization-team": "Filter by Organization/ Team",
|
||||||
"laeufer-hinzufuegen": "Add runner",
|
"first-name": "First name",
|
||||||
"laeufer-importieren": "Läufer importieren",
|
"first-name-is-required": "First Name is required",
|
||||||
"laptime": "Laptime",
|
"first-scan-of-the-day": "First scan of the day.",
|
||||||
"last-name": "Last name",
|
"fixed-donation": "fixed donation",
|
||||||
"last-name-is-required": "Last Name is required",
|
"forgot_password": "Forgot your password?",
|
||||||
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
|
"geerbte": "inherited",
|
||||||
"license": "License",
|
"general-stats": "General Stats",
|
||||||
"licenses-are-being-loaded": "Licenses are being loaded...",
|
"general_promise_error": "😢 Error",
|
||||||
"loading-contact-details": "Loading contact details...",
|
"generate-runner-certificate": "Generate runner certificate",
|
||||||
"loading-donation-details": "Loading donation details",
|
"generate-runner-certificates": "Generate runner certificates",
|
||||||
"loading-donor-details": "Loading donor details",
|
"generate-runnercards": "Generate Runnercards",
|
||||||
"loading-group-detail": "Loading group detail...",
|
"generate-sponsoring-contract": "generate sponsoring contract",
|
||||||
"loading-profile-data": "Loading profile data",
|
"generate-sponsoring-contracts": "generate sponsoring contracts",
|
||||||
"loading-runners": "loading runners...",
|
"generating-pdf": "generating PDF...",
|
||||||
"loading-station-details": "Loading station details",
|
"generating-pdfs": "generating PDFs...",
|
||||||
"log_in": "Log in",
|
"generic-ui-logic-error": "Something went wrong in the UI logic",
|
||||||
"log_in_to_your_account": "Log in to your account",
|
"german": "German",
|
||||||
"login_is_checked": "Login is being checked...",
|
"go-to-login": "Go To Login",
|
||||||
"logout": "Logout",
|
"goback": "Go Home",
|
||||||
"mail-validation-in-progress": "mail validation in progress...",
|
"granted": "granted",
|
||||||
"manage-admin-users": "manage admin users",
|
"group": "Group",
|
||||||
"middle-name": "Middle name",
|
"group-added": "Group added",
|
||||||
"minimum-lap-time-in-s": "minimum lap time in s",
|
"group-is-being-added": "Group is being added...",
|
||||||
"minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0",
|
"group-name-is-required": "Group name is required",
|
||||||
"name": "Name",
|
"group-updated": "group updated",
|
||||||
"name-is-required": "Name is required",
|
"groups": "Groups",
|
||||||
"new-password": "New password",
|
"groups-are-being-loaded": "Groups are being loaded",
|
||||||
"no-contact-found": "No contacts found",
|
"home": "Home",
|
||||||
"no-contact-selected": "No contact selected",
|
"icon-image-credits": "We also want to thank these projects for illustrations and icons:",
|
||||||
"no-contact-specified": "no contact specified",
|
"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.",
|
||||||
"no-donors-found": "No donors found",
|
"import-finished": "Import finished",
|
||||||
"no-license-text-could-be-found": "No license text could be found 😢",
|
"import-runners": "Import runners",
|
||||||
"no-organization-or-team-found": "No organization or team found",
|
"import__target-organization": "Target Organization",
|
||||||
"no-organization-specified": "no organization specified",
|
"imprint": "Imprint",
|
||||||
"no-organizations-found": "No organizations found",
|
"imprint-loading": "Imprint loading...",
|
||||||
"no-runners-found": "No runners found",
|
"inactive": "Inactive",
|
||||||
"no-tracks-added-yet": "there are no tracks added yet.",
|
"installed-version": "Installed version",
|
||||||
"organization": "Organization",
|
"internal-error": "Internal Error",
|
||||||
"organization-added": "Organization added",
|
"invalid": "Invalid",
|
||||||
"organization-deleted": "Organization deleted",
|
"invalid-mail-reset": "the provided email is invalid",
|
||||||
"organization-detail-is-being-loaded": "organization detail is being loaded...",
|
"just-enter-how-many-you-want-and-the-system-will-create-them": "Just enter how many you want and the system will create them",
|
||||||
"organization-is-being-added": "Organization is being added...",
|
"key": "Key",
|
||||||
"organization-name-is-required": "Organization name is required",
|
"laeufer-hinzufuegen": "Add runner",
|
||||||
"organizations": "Organizations",
|
"laeufer-importieren": "Läufer importieren",
|
||||||
"organizations-are-being-loaded": "organizations are being loaded...",
|
"laptime": "Laptime",
|
||||||
"orgs": "Organizations",
|
"last-name": "Last name",
|
||||||
"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!",
|
"last-name-is-required": "Last Name is required",
|
||||||
"password": "Password",
|
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
|
||||||
"password-changed": "Password changed!",
|
"license": "License",
|
||||||
"password-is-required": "Password is required",
|
"licenses-are-being-loaded": "Licenses are being loaded...",
|
||||||
"password-reset-failed": "Password reset failed!",
|
"loading-cards": "Loading cards",
|
||||||
"password-reset-in-progress": "Password Reset in Progress...",
|
"loading-contact-details": "Loading contact details...",
|
||||||
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
|
"loading-donation-details": "Loading donation details",
|
||||||
"password-reset-successful": "Password Reset successful!",
|
"loading-donor-details": "Loading donor details",
|
||||||
"passwords-dont-match": "Passwords don't match",
|
"loading-group-detail": "Loading group detail...",
|
||||||
"pdf-generation-failed": "PDF generation failed!",
|
"loading-profile-data": "Loading profile data",
|
||||||
"pdf-successfully-generated": "PDF successfully generated!",
|
"loading-runners": "loading runners...",
|
||||||
"pdfs-successfully-generated": "PDFs successfully generated!",
|
"loading-station-details": "Loading station details",
|
||||||
"per-kilometer": "per Kilometer",
|
"log_in": "Log in",
|
||||||
"permissions": "Permissions",
|
"log_in_to_your_account": "Log in to your account",
|
||||||
"permissions-updated": "Permissions updated!",
|
"login_is_checked": "Login is being checked...",
|
||||||
"phone": "Phone",
|
"logout": "Logout",
|
||||||
"please-copy-the-token-and-store-it-somewhere-save": "Please copy the token and store it somewhere safe.",
|
"mail-validation-in-progress": "mail validation in progress...",
|
||||||
"please-provide-a-password": "Please provide a password...",
|
"manage-admin-users": "manage admin users",
|
||||||
"please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor",
|
"middle-name": "Middle name",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation",
|
"minimum-lap-time-in-s": "minimum lap time in s",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-scan": "Please provide the nessecary information to create a new scan.",
|
"minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0",
|
||||||
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
|
"must-be-at-least-10-characters-long": "Must be at least 10 characters long!",
|
||||||
"please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.",
|
"must-contain-a-lowercase-letter": "Must contain a lowercase letter!",
|
||||||
"please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.",
|
"must-contain-a-number": "Must contain a number!",
|
||||||
"please-provide-the-required-information-to-add-a-new-organization": "Please provide the required information to add a new organization.",
|
"must-contain-a-uppercase-letter": "Must contain a uppercase letter!",
|
||||||
"please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.",
|
"name": "Name",
|
||||||
"please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.",
|
"name-is-required": "Name is required",
|
||||||
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
|
"new-password": "New password",
|
||||||
"please-provide-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.",
|
"no-contact-found": "No contacts found",
|
||||||
"please-provide-the-required-information-to-create-a-new-scanstation": "Please provide the required information to create a new scanstation",
|
"no-contact-selected": "No contact selected",
|
||||||
"please-request-a-new-reset-mail": "Please request a new reset mail...",
|
"no-contact-specified": "no contact specified",
|
||||||
"privacy": "Privacy",
|
"no-donors-found": "No donors found",
|
||||||
"privacy-loading": "Privacy loading...",
|
"no-license-text-could-be-found": "No license text could be found 😢",
|
||||||
"profile": "Profile",
|
"no-organization-or-team-found": "No organization or team found",
|
||||||
"profile-picture": "Profile Picture",
|
"no-organization-specified": "no organization specified",
|
||||||
"profile-updated": "Profile updated!",
|
"no-organizations-found": "No organizations found",
|
||||||
"read-license": "Read License",
|
"no-runners-found": "No runners found",
|
||||||
"receipt-needed": "Receipt needed",
|
"no-tracks-added-yet": "there are no tracks added yet.",
|
||||||
"repo_link": "Link",
|
"non-blanko": "Non/Blanko",
|
||||||
"request-a-new-reset-mail": "Request a new reset mail",
|
"open": "OPEN",
|
||||||
"reset-my-password": "Reset my password",
|
"organization": "Organization",
|
||||||
"reset-password": "Reset your password",
|
"organization-added": "Organization added",
|
||||||
"runner": "Runner",
|
"organization-deleted": "Organization deleted",
|
||||||
"runner-added": "Runner added",
|
"organization-detail-is-being-loaded": "organization detail is being loaded...",
|
||||||
"runner-import": "Runner Import",
|
"organization-is-being-added": "Organization is being added...",
|
||||||
"runner-is-being-added": "Runner is being added...",
|
"organization-name-is-required": "Organization name is required",
|
||||||
"runner-updated": "Runner updated!",
|
"organizations": "Organizations",
|
||||||
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
|
"organizations-are-being-loaded": "organizations are being loaded...",
|
||||||
"runners": "Runners",
|
"orgs": "Organizations",
|
||||||
"runners-are-being-imported": "Runners are being imported...",
|
"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!",
|
||||||
"runners-are-being-loaded": "runners are being loaded...",
|
"paid": "PAID",
|
||||||
"save": "Save",
|
"paid-amount": "Paid amount",
|
||||||
"save-changes": "Save Changes",
|
"password": "Password",
|
||||||
"scan-added": "Scan added",
|
"password-changed": "Password changed!",
|
||||||
"scan-is-being-updated": "Scan is being updated",
|
"password-is-required": "Password is required",
|
||||||
"scan-with-fixed-distance": "Scan with fixed distance",
|
"password-reset-failed": "Password reset failed!",
|
||||||
"scans": "Scans",
|
"password-reset-in-progress": "Password Reset in Progress...",
|
||||||
"scans-are-being-loaded": "Scans are being loaded",
|
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
|
||||||
"scanstation": "Scanstation",
|
"password-reset-successful": "Password Reset successful!",
|
||||||
"scanstation-added": "Scanstation added",
|
"passwords-dont-match": "Passwords don't match!",
|
||||||
"scanstation-is-being-added": "Adding scanstation...",
|
"payment-amount-must-be-greater-than-0-00eur": "Payment amount must be greater than 0.00€!",
|
||||||
"scanstations": "Scanstations",
|
"pdf-generation-failed": "PDF generation failed!",
|
||||||
"scanstations-are-being-loaded": "Loading scanstations...",
|
"pdf-successfully-generated": "PDF successfully generated!",
|
||||||
"search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)",
|
"pdfs-successfully-generated": "PDFs successfully generated!",
|
||||||
"search-for-an-organization-or-team-by-name-or-id": "Search for an organization or team (by name or id)",
|
"per-kilometer": "per Kilometer",
|
||||||
"search-for-donor-name-or-id": "Search for donor (by name or id)",
|
"permissions": "Permissions",
|
||||||
"search-for-permission": "Search for permission",
|
"permissions-updated": "Permissions updated!",
|
||||||
"search-for-runner-by-name-or-id": "Search for runner (by name or id)",
|
"phone": "Phone",
|
||||||
"select-all": "select all",
|
"please-copy-the-token-and-store-it-somewhere-save": "Please copy the token and store it somewhere safe.",
|
||||||
"select-language": "Select language",
|
"please-provide-a-password": "Please provide a password...",
|
||||||
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
|
"please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor",
|
||||||
"set-the-user-active-inactive": "set the user active/ inactive",
|
"please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation",
|
||||||
"settings": "Settings",
|
"please-provide-the-nessecary-information-to-create-a-new-scan": "Please provide the nessecary information to create a new scan.",
|
||||||
"settings-for-your-profile": "Settings for your profile",
|
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
|
||||||
"something-about-the-group": "Something about the group...",
|
"please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.",
|
||||||
"stats-are-being-loaded": "stats are being loaded...",
|
"please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.",
|
||||||
"status": "Status",
|
"please-provide-the-required-information-to-add-a-new-organization": "Please provide the required information to add a new organization.",
|
||||||
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
|
"please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.",
|
||||||
"successful-password-reset": "Successful password reset!",
|
"please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.",
|
||||||
"team": "Team",
|
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
|
||||||
"team-detail-is-being-loaded": "team detail is being loaded...",
|
"please-provide-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.",
|
||||||
"team-name": "Team name",
|
"please-provide-the-required-information-to-create-a-new-scanstation": "Please provide the required information to create a new scanstation",
|
||||||
"team-name-is-required": "team name is required",
|
"please-provide-the-required-information-to-create-a-new-statsclient": "Please provide the required information to create a new statsclient",
|
||||||
"teams": "Teams",
|
"please-request-a-new-reset-mail": "Please request a new reset mail...",
|
||||||
"teams-are-being-loaded": "teams are being loaded...",
|
"please-wait-a-moment-your-login-is-still-being-processed": "Please wait a moment, your login is still being processed",
|
||||||
"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...",
|
"prefix": "Prefix",
|
||||||
"the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m",
|
"privacy": "Privacy",
|
||||||
"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!",
|
"privacy-loading": "Privacy loading...",
|
||||||
"there-are-no-contacts-added-yet": "There are no contacts added yet.",
|
"profile": "Profile",
|
||||||
"there-are-no-donations-yet": "There are no donations yet",
|
"profile-deleted": "Profile deleted!",
|
||||||
"there-are-no-donors-yet": "There are no donors yet",
|
"profile-picture": "Profile Picture",
|
||||||
"there-are-no-groups-yet": "There are no groups yet",
|
"profile-updated": "Profile updated!",
|
||||||
"there-are-no-organizations-added-yet": "There are no organizations added yet.",
|
"read-license": "Read License",
|
||||||
"there-are-no-runners-added-yet": "There are no runners added yet.",
|
"receipt-needed": "Receipt needed",
|
||||||
"there-are-no-scans-yet": "There are no scans yet",
|
"repo_link": "Link",
|
||||||
"there-are-no-teams-added-yet": "There are no teams added yet.",
|
"request-a-new-reset-mail": "Request a new reset mail",
|
||||||
"there-are-no-users-added-yet": "There are no users added yet.",
|
"reset-my-password": "Reset my password",
|
||||||
"this-might-take-a-moment": "This might take a moment 👀",
|
"reset-password": "Reset your password",
|
||||||
"this-scanstation-is": "This scanstation is",
|
"runner": "Runner",
|
||||||
"token": "Token",
|
"runner-added": "Runner added",
|
||||||
"total-distance": "total distance",
|
"runner-import": "Runner Import",
|
||||||
"total-donation-amount": "total donation amount",
|
"runner-is-being-added": "Runner is being added...",
|
||||||
"total-donations": "total donations",
|
"runner-updated": "Runner updated!",
|
||||||
"total-scans": "total scans",
|
"runnercards": "Runnercards",
|
||||||
"track": "Track",
|
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
|
||||||
"track-added": "Track added",
|
"runners": "Runners",
|
||||||
"track-data-is-being-loaded": "Track data is being loaded",
|
"runners-are-being-imported": "Runners are being imported...",
|
||||||
"track-is-being-added": "Track is being added...",
|
"runners-are-being-loaded": "runners are being loaded...",
|
||||||
"track-length-in-m": "Track Length in m",
|
"save": "Save",
|
||||||
"track-length-must-be-greater-than-0": "Track length must be greater than 0",
|
"save-changes": "Save Changes",
|
||||||
"track-name": "Track name",
|
"scan-added": "Scan added",
|
||||||
"track-name-must-not-be-empty": "Track name must not be empty",
|
"scan-is-being-updated": "Scan is being updated",
|
||||||
"tracks": "Tracks",
|
"scan-with-fixed-distance": "Scan with fixed distance",
|
||||||
"update-password": "Update password",
|
"scans": "Scans",
|
||||||
"updated-contact": "Updated contact!",
|
"scans-are-being-loaded": "Scans are being loaded",
|
||||||
"updated-donor": "updated donor",
|
"scanstation": "Scanstation",
|
||||||
"updated-organization": "updated organization",
|
"scanstation-added": "Scanstation added",
|
||||||
"updated-scan": "updated scan",
|
"scanstation-is-being-added": "Adding scanstation...",
|
||||||
"updateing-group": "updateing group...",
|
"scanstations": "Scanstations",
|
||||||
"updating-organization": "updating organization",
|
"scanstations-are-being-loaded": "Loading scanstations...",
|
||||||
"updating-permissions": "updating permissions...",
|
"search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)",
|
||||||
"updating-runner": "Updating runner...",
|
"search-for-an-organization-or-team-by-name-or-id": "Search for an organization or team (by name or id)",
|
||||||
"updating-user": "updating user...",
|
"search-for-donor-name-or-id": "Search for donor (by name or id)",
|
||||||
"updating-your-profile": "Updating your profile...",
|
"search-for-permission": "Search for permission",
|
||||||
"user-added": "User added",
|
"search-for-runner-by-name-or-id": "Search for runner (by name or id)",
|
||||||
"user-groups": "User Groups",
|
"select-all": "select all",
|
||||||
"user-is-being-added": "User is being added...",
|
"select-language": "Select language",
|
||||||
"user-updated": "User updated",
|
"selfservice-registration": "Selfservice registration",
|
||||||
"username": "Username",
|
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
|
||||||
"users": "Users",
|
"set-the-user-active-inactive": "set the user active/ inactive",
|
||||||
"valid": "Valid",
|
"settings": "Settings",
|
||||||
"valid-city-is-required": "Valid city is required",
|
"settings-for-your-profile": "Settings for your profile",
|
||||||
"valid-email-is-required": "valid email is required",
|
"something-about-the-group": "Something about the group...",
|
||||||
"valid-international-phone-number-is-required": "valid international phone number is required...",
|
"sponsoring-quittungs-liste_herunterladen": "Download donor receipt list",
|
||||||
"valid-zipcode-postal-code-is-required": "Valid zipcode/ postal code is required",
|
"sponsorings": "Sponsorings",
|
||||||
"verfuegbare": "availdable",
|
"stats-are-being-loaded": "stats are being loaded...",
|
||||||
"welcome_wavinghand": "Welcome 👋",
|
"statsclient-deleted": "Deleted statsclient",
|
||||||
"yes-i-copied-the-token": "Yes, I copied the token",
|
"statsclient-is-being-added": "Statsclient is being added...",
|
||||||
"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!",
|
"statsclients": "Statsclients (aka Beamershow)",
|
||||||
"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! 🎉",
|
"statsclients-are-being-loaded": "Loading statsclients",
|
||||||
"you-dont-have-any-scanstations-yet": "You don't have any scanstations yet",
|
"status": "Status",
|
||||||
"you-have-to-provide-an-organization": "You have to provide an organization",
|
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
|
||||||
"zip-postal-code": "ZIP/ postal code"
|
"successful-password-reset": "Successful password reset!",
|
||||||
}
|
"team": "Team",
|
||||||
|
"team-added": "Team added",
|
||||||
|
"team-deleted": "Team deleted",
|
||||||
|
"team-detail-is-being-loaded": "team detail is being loaded...",
|
||||||
|
"team-is-being-added": "Team is being added...",
|
||||||
|
"team-name": "Team name",
|
||||||
|
"team-name-is-required": "team name is required",
|
||||||
|
"teams": "Teams",
|
||||||
|
"teams-are-being-loaded": "teams 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...",
|
||||||
|
"the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m",
|
||||||
|
"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!",
|
||||||
|
"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!",
|
||||||
|
"there-are-no-cards-yet": "There are no cards yet.",
|
||||||
|
"there-are-no-contacts-added-yet": "There are no contacts added yet.",
|
||||||
|
"there-are-no-donations-yet": "There are no donations yet",
|
||||||
|
"there-are-no-donors-yet": "There are no donors yet",
|
||||||
|
"there-are-no-groups-yet": "There are no groups yet",
|
||||||
|
"there-are-no-organizations-added-yet": "There are no organizations added yet.",
|
||||||
|
"there-are-no-runners-added-yet": "There are no runners added yet.",
|
||||||
|
"there-are-no-scans-yet": "There are no scans yet",
|
||||||
|
"there-are-no-teams-added-yet": "There are no teams added yet.",
|
||||||
|
"there-are-no-users-added-yet": "There are no users added yet.",
|
||||||
|
"this-card-is": "This card is",
|
||||||
|
"this-might-take-a-moment": "This might take a moment 👀",
|
||||||
|
"this-scanstation-is": "This scanstation is",
|
||||||
|
"token": "Token",
|
||||||
|
"total-distance": "total distance",
|
||||||
|
"total-donation-amount": "total donation amount",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
Loaded 100 of 108 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user