Compare commits
255
Commits
0.8.7
...
96c55db63d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
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
-3
@@ -1,3 +1 @@
|
|||||||
public/env.sample.js
|
public/env.sample.js
|
||||||
public/workbox-*.js
|
|
||||||
public/workbox-*.js.map
|
|
||||||
+1
-1
@@ -27,7 +27,7 @@ name: build:dev
|
|||||||
steps:
|
steps:
|
||||||
- name: run full license export
|
- name: run full license export
|
||||||
depends_on: ["clone"]
|
depends_on: ["clone"]
|
||||||
image: node:alpine
|
image: registry.odit.services/hub/library/node:alpine
|
||||||
commands:
|
commands:
|
||||||
- yarn
|
- yarn
|
||||||
- yarn licenses:export
|
- yarn licenses:export
|
||||||
|
|||||||
+5
-5
@@ -1,11 +1,11 @@
|
|||||||
node_modules
|
node_modules
|
||||||
build
|
|
||||||
package-lock.json
|
package-lock.json
|
||||||
yarn.lock
|
yarn.lock
|
||||||
*.map
|
*.map
|
||||||
public/env.js
|
public/env.js
|
||||||
public/sw.js
|
|
||||||
public/index.html
|
|
||||||
public/workbox-*.js
|
|
||||||
svelte.config.js
|
|
||||||
public/index.html
|
public/index.html
|
||||||
|
/dist
|
||||||
|
.yarn
|
||||||
|
.pnp.js
|
||||||
|
.yarnrc.yml
|
||||||
|
pnpm-lock.yaml
|
||||||
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,
|
||||||
}
|
}
|
||||||
+328
@@ -2,8 +2,336 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||||
|
|
||||||
|
#### [0.15.6](https://git.odit.services/lfk/frontend/compare/0.15.5...0.15.6)
|
||||||
|
|
||||||
|
- 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)
|
#### [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)
|
- 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)
|
||||||
|
|||||||
+6
-12
@@ -1,18 +1,12 @@
|
|||||||
FROM node:15.5.1-alpine3.12
|
FROM registry.odit.services/hub/library/node:15.14.0-alpine3.13
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN npm i -g pnpm
|
|
||||||
COPY package.json ./
|
COPY package.json ./
|
||||||
RUN pnpm i
|
RUN yarn
|
||||||
COPY package.json *.config.js workbox-config.js template-copy.js index.template.html s-config.template.js ./
|
COPY package.json *.config.js postcss.config.cjs index.html ./
|
||||||
COPY src ./src
|
COPY src ./src
|
||||||
COPY public ./public
|
COPY public ./public
|
||||||
RUN pnpm run build
|
RUN yarn build
|
||||||
# final image
|
# final image
|
||||||
FROM alpine
|
FROM registry.odit.services/hub/fholzer/nginx-brotli:v1.19.1
|
||||||
COPY --from=0 /app/build /app
|
COPY --from=0 /app/dist /usr/share/nginx/html
|
||||||
RUN rm -rf /app/build/_dist_/components
|
|
||||||
RUN rm -rf /app/build/_dist_/locales
|
|
||||||
RUN rm -rf /app/build-manifest.json
|
|
||||||
FROM fholzer/nginx-brotli:v1.19.1
|
|
||||||
COPY --from=1 /app /usr/share/nginx/html
|
|
||||||
COPY ./nginx.conf /etc/nginx/nginx.conf
|
COPY ./nginx.conf /etc/nginx/nginx.conf
|
||||||
@@ -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.7-RELEASE_INFO</span>
|
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.15.6-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;
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-33
@@ -1,45 +1,40 @@
|
|||||||
{
|
{
|
||||||
"name": "@odit/lfk-frontend",
|
"name": "@odit/lfk-frontend",
|
||||||
"version": "0.8.7",
|
"version": "0.15.6",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"i18n-order": "node order.js",
|
"i18n-order": "node order.js",
|
||||||
"dev:all": "yarn prebuild && snowpack dev",
|
"dev": "vite",
|
||||||
"dev": "cross-env NODE_ENV_ODIT=development_fast node template-copy.js && yarn build:sw && snowpack dev",
|
"build": "vite build",
|
||||||
"build": "yarn prebuild && snowpack build",
|
|
||||||
"prebuild": "cross-env NODE_ENV_ODIT=production node template-copy.js && yarn build:sw",
|
|
||||||
"build:sw": "workbox generateSW workbox-config.js",
|
|
||||||
"release": "release-it",
|
"release": "release-it",
|
||||||
"licenses:export": "license-exporter --json -o public"
|
"licenses:export": "license-exporter --json -o public"
|
||||||
},
|
},
|
||||||
"license": "CC-BY-NC-SA-4.0",
|
"license": "CC-BY-NC-SA-4.0",
|
||||||
"dependencies": {
|
|
||||||
"@odit/lfk-client-js": "0.6.4",
|
|
||||||
"csvtojson": "^2.0.10",
|
|
||||||
"gridjs": "3.3.0",
|
|
||||||
"localforage": "1.9.0",
|
|
||||||
"marked": "^2.0.1",
|
|
||||||
"svelte-focus-trap": "1.0.1",
|
|
||||||
"svelte-i18n": "3.3.7",
|
|
||||||
"svelte-select": "^3.17.0",
|
|
||||||
"tailwindcss": "2.0.3",
|
|
||||||
"tinro": "0.6.1",
|
|
||||||
"toastify-js": "1.9.3",
|
|
||||||
"validator": "13.5.2",
|
|
||||||
"xlsx": "^0.16.9"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@odit/license-exporter": "^0.0.11",
|
"@odit/lfk-client-js": "0.13.1",
|
||||||
"@snowpack/plugin-svelte": "3.5.2",
|
"@odit/license-exporter": "0.0.11",
|
||||||
"auto-changelog": "^2.2.1",
|
"@sveltejs/vite-plugin-svelte": "1.0.0-next.6",
|
||||||
|
"@types/html-minifier": "4.0.0",
|
||||||
|
"auto-changelog": "2.2.1",
|
||||||
"autoprefixer": "10.2.5",
|
"autoprefixer": "10.2.5",
|
||||||
"cross-env": "^7.0.3",
|
"check-password-strength": "2.0.2",
|
||||||
"postcss": "8.2.8",
|
"csvtojson": "2.0.10",
|
||||||
"postcss-load-config": "3.0.1",
|
"gridjs": "3.4.0",
|
||||||
"release-it": "^14.4.1",
|
"html-minifier": "4.0.0",
|
||||||
"snowpack": "3.0.13",
|
"localforage": "1.9.0",
|
||||||
"svelte": "3.35.0",
|
"marked": "2.0.3",
|
||||||
"svelte-preprocess": "4.6.9",
|
"postcss": "8.2.10",
|
||||||
"workbox-cli": "6.1.2"
|
"release-it": "14.6.1",
|
||||||
|
"svelte": "3.37.0",
|
||||||
|
"svelte-focus-trap": "1.2.0",
|
||||||
|
"svelte-i18n": "3.3.9",
|
||||||
|
"svelte-preprocess": "4.7.0",
|
||||||
|
"svelte-select": "3.17.0",
|
||||||
|
"tailwindcss": "2.1.1",
|
||||||
|
"tinro": "0.6.1",
|
||||||
|
"toastify-js": "1.10.0",
|
||||||
|
"validator": "13.5.2",
|
||||||
|
"vite": "2.1.5",
|
||||||
|
"xlsx": "0.16.9"
|
||||||
},
|
},
|
||||||
"release-it": {
|
"release-it": {
|
||||||
"git": {
|
"git": {
|
||||||
@@ -55,7 +50,7 @@
|
|||||||
"publish": false
|
"publish": false
|
||||||
},
|
},
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node versionbuilder.js && git add index.template.html && node order.js && git add src/locales"
|
"after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node versionbuilder.js && git add index.html && node order.js && git add src/locales"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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":"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.11.0","licensetext":"Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Creative\r\nCommons Corporation (\"Creative Commons\") is not a law firm and does not provide\r\nlegal services or legal advice. Distribution of Creative Commons public licenses\r\ndoes not create a lawyer-client or other relationship. Creative Commons makes\r\nits licenses and related information available on an \"as-is\" basis. Creative\r\nCommons gives no warranties regarding its licenses, any material licensed\r\nunder their terms and conditions, or any related information. Creative Commons\r\ndisclaims all liability for damages resulting from their use to the fullest\r\nextent possible.\r\n\r\nUsing Creative Commons Public Licenses\r\n\r\nCreative Commons public licenses provide a standard set of terms and conditions\r\nthat creators and other rights holders may use to share original works of\r\nauthorship and other material subject to copyright and certain other rights\r\nspecified in the public license below. The following considerations are for\r\ninformational purposes only, are not exhaustive, and do not form part of our\r\nlicenses.\r\n\r\nConsiderations for licensors: Our public licenses are intended for use by\r\nthose authorized to give the public permission to use material in ways otherwise\r\nrestricted by copyright and certain other rights. Our licenses are irrevocable.\r\nLicensors should read and understand the terms and conditions of the license\r\nthey choose before applying it. Licensors should also secure all rights necessary\r\nbefore applying our licenses so that the public can reuse the material as\r\nexpected. Licensors should clearly mark any material not subject to the license.\r\nThis includes other CC-licensed material, or material used under an exception\r\nor limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors\r\n\r\nConsiderations for the public: By using one of our public licenses, a licensor\r\ngrants the public permission to use the licensed material under specified\r\nterms and conditions. If the licensor's permission is not necessary for any\r\nreason–for example, because of any applicable exception or limitation to copyright–then\r\nthat use is not regulated by the license. Our licenses grant only permissions\r\nunder copyright and certain other rights that a licensor has authority to\r\ngrant. Use of the licensed material may still be restricted for other reasons,\r\nincluding because others have copyright or other rights in the material. A\r\nlicensor may make special requests, such as asking that all changes be marked\r\nor described. Although not required by our licenses, you are encouraged to\r\nrespect those requests where reasonable. More considerations for the public\r\n: wiki.creativecommons.org/Considerations_for_licensees\r\n\r\nCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public\r\nLicense\r\n\r\nBy exercising the Licensed Rights (defined below), You accept and agree to\r\nbe bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike\r\n4.0 International Public License (\"Public License\"). To the extent this Public\r\nLicense may be interpreted as a contract, You are granted the Licensed Rights\r\nin consideration of Your acceptance of these terms and conditions, and the\r\nLicensor grants You such rights in consideration of benefits the Licensor\r\nreceives from making the Licensed Material available under these terms and\r\nconditions.\r\n\r\nSection 1 – Definitions.\r\n\r\na. Adapted Material means material subject to Copyright and Similar Rights\r\nthat is derived from or based upon the Licensed Material and in which the\r\nLicensed Material is translated, altered, arranged, transformed, or otherwise\r\nmodified in a manner requiring permission under the Copyright and Similar\r\nRights held by the Licensor. For purposes of this Public License, where the\r\nLicensed Material is a musical work, performance, or sound recording, Adapted\r\nMaterial is always produced where the Licensed Material is synched in timed\r\nrelation with a moving image.\r\n\r\nb. Adapter's License means the license You apply to Your Copyright and Similar\r\nRights in Your contributions to Adapted Material in accordance with the terms\r\nand conditions of this Public License.\r\n\r\nc. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses,\r\napproved by Creative Commons as essentially the equivalent of this Public\r\nLicense.\r\n\r\nd. Copyright and Similar Rights means copyright and/or similar rights closely\r\nrelated to coLine 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
-5
@@ -1,5 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import "./TailwindStyles.svelte";
|
|
||||||
import "toastify-js/src/toastify.css";
|
import "toastify-js/src/toastify.css";
|
||||||
import "gridjs/dist/theme/mermaid.css";
|
import "gridjs/dist/theme/mermaid.css";
|
||||||
import { Route, router } from "tinro";
|
import { Route, router } from "tinro";
|
||||||
@@ -53,7 +52,6 @@
|
|||||||
import { OpenAPI } from "@odit/lfk-client-js";
|
import { OpenAPI } from "@odit/lfk-client-js";
|
||||||
import UserDetail from "./components/users/UserDetail.svelte";
|
import UserDetail from "./components/users/UserDetail.svelte";
|
||||||
OpenAPI.BASE = config.baseurl;
|
OpenAPI.BASE = config.baseurl;
|
||||||
import { register as registerSW } from "./swmodule";
|
|
||||||
import TeamDetail from "./components/teams/TeamDetail.svelte";
|
import TeamDetail from "./components/teams/TeamDetail.svelte";
|
||||||
import UserPermissions from "./components/users/UserPermissions.svelte";
|
import UserPermissions from "./components/users/UserPermissions.svelte";
|
||||||
import GroupPermissions from "./components/groups/GroupPermissions.svelte";
|
import GroupPermissions from "./components/groups/GroupPermissions.svelte";
|
||||||
@@ -69,13 +67,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 +184,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 +208,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 { focusTrap } from "svelte-focus-trap";
|
||||||
|
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:focusTrap
|
||||||
|
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,170 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
|
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) =>
|
||||||
|
option.firstname + " " + (option.middlename || "") + " " + option.lastname;
|
||||||
|
const filterRunners = (label, filterText, option) =>
|
||||||
|
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||||
|
option.value.toString().startsWith(filterText.toLowerCase());
|
||||||
|
function focus(el) {
|
||||||
|
el.focus();
|
||||||
|
}
|
||||||
|
$: runner = 0;
|
||||||
|
$: runners = [];
|
||||||
|
$: enabled = true;
|
||||||
|
$: processed_last_submit = true;
|
||||||
|
RunnerService.runnerControllerGetAll().then((val) => {
|
||||||
|
runners = val.map((r) => {
|
||||||
|
return { label: getRunnerLabel(r), value: r };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$: 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:focusTrap
|
||||||
|
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}
|
||||||
|
showChevron={true}
|
||||||
|
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,186 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
|
import { RunnerCardService, RunnerService } from "@odit/lfk-client-js";
|
||||||
|
import Select from "svelte-select";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
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) =>
|
||||||
|
label.toLowerCase().includes(filterText.toLowerCase()) ||
|
||||||
|
option.value.toString().startsWith(filterText.toLowerCase());
|
||||||
|
function focus(el) {
|
||||||
|
el.focus();
|
||||||
|
}
|
||||||
|
$: runners = [];
|
||||||
|
$: enabled = true;
|
||||||
|
$: processed_last_submit = true;
|
||||||
|
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;
|
||||||
|
})
|
||||||
|
.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:focusTrap
|
||||||
|
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,281 @@
|
|||||||
|
<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";
|
||||||
|
export let edit_modal_open = false;
|
||||||
|
export let runner = {};
|
||||||
|
export let editable = {};
|
||||||
|
export let original_data = {};
|
||||||
|
export let current_cards = [];
|
||||||
|
$: filtered_cards = current_cards.filter(function (c) {
|
||||||
|
if (
|
||||||
|
c.code.toLowerCase().includes(searchvalue_lowercase) ||
|
||||||
|
c.runner?.firstname.toLowerCase().includes(searchvalue_lowercase) ||
|
||||||
|
c.runner?.middlename.toLowerCase().includes(searchvalue_lowercase) ||
|
||||||
|
c.runner?.lastname.toLowerCase().includes(searchvalue_lowercase) ||
|
||||||
|
should_display_based_on_id(c.id)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$: searchvalue = "";
|
||||||
|
$: searchvalue_lowercase = searchvalue.toLowerCase();
|
||||||
|
$: active_deletes = [];
|
||||||
|
$: cards_show = current_cards.some((r) => r.is_selected === true);
|
||||||
|
$: generate_cards = current_cards.filter((r) => r.is_selected === true);
|
||||||
|
const cards_promise = RunnerCardService.runnerCardControllerGetAll().then(
|
||||||
|
(val) => {
|
||||||
|
current_cards = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
function should_display_based_on_id(id) {
|
||||||
|
if (searchvalue.toString().slice(-1) === "*") {
|
||||||
|
return id.toString().startsWith(searchvalue.replace("*", ""));
|
||||||
|
}
|
||||||
|
return id.toString() === searchvalue;
|
||||||
|
}
|
||||||
|
const getRunnerLabel = (option) =>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
// -----------------
|
||||||
|
let scrollTop = 0;
|
||||||
|
$: rendered = filtered_cards;
|
||||||
|
let innerHeight = 0;
|
||||||
|
let ele;
|
||||||
|
$: updateSlice(scrollTop);
|
||||||
|
$: innerHeight = `${filtered_cards.length * 25}px`;
|
||||||
|
$: if (ele) updateSlice();
|
||||||
|
function updateSlice() {
|
||||||
|
const height = ele ? parseInt(ele.clientHeight) : 100;
|
||||||
|
const init = scrollTop / 25;
|
||||||
|
const end = Math.ceil((scrollTop + height) / 25);
|
||||||
|
rendered = filtered_cards.slice(init, end + 15);
|
||||||
|
}
|
||||||
|
function updateScroll($event) {
|
||||||
|
scrollTop = $event.target.scrollTop;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
table tbody {
|
||||||
|
display: block;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead, table tbody tr {
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:UPDATE')}
|
||||||
|
<CardDetailModal
|
||||||
|
bind:current_cards
|
||||||
|
bind:edit_modal_open
|
||||||
|
bind:runner
|
||||||
|
bind:editable
|
||||||
|
bind:original_data />
|
||||||
|
{/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}
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
bind:value={searchvalue}
|
||||||
|
placeholder={$_('datatable.search')}
|
||||||
|
aria-label={$_('datatable.search')}
|
||||||
|
class="gridjs-input gridjs-search-input mb-4" />
|
||||||
|
<div class="h-12">
|
||||||
|
<GenerateRunnerCards
|
||||||
|
bind:cards_show
|
||||||
|
bind:generate_cards />
|
||||||
|
</div>
|
||||||
|
<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">
|
||||||
|
<span
|
||||||
|
on:click={() => {
|
||||||
|
const newstate = !current_cards.some((r) => r.is_selected === true);
|
||||||
|
current_cards = current_cards.map((r) => {
|
||||||
|
r.is_selected = newstate;
|
||||||
|
return r;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
class="underline cursor-pointer select-none">{#if current_cards.some((r) => r.is_selected === true)}
|
||||||
|
{$_('deselect-all')}
|
||||||
|
{:else}{$_('select-all')}{/if}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
{$_('code')}
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
{$_('runner')}
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
scope="col"
|
||||||
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
{$_('status')}
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="relative px-6 py-3">
|
||||||
|
<span class="sr-only">{$_('action')}</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 virtual-wrapper"
|
||||||
|
on:scroll={updateScroll}
|
||||||
|
style="height: 70vh; width:100%"
|
||||||
|
bind:this={ele}
|
||||||
|
>
|
||||||
|
{#each filtered_cards as card, index}
|
||||||
|
{#if card.code
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(
|
||||||
|
searchvalue.toLowerCase()
|
||||||
|
) || card.runner?.firstname
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(
|
||||||
|
searchvalue.toLowerCase()
|
||||||
|
) || card.runner?.middlename
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(
|
||||||
|
searchvalue.toLowerCase()
|
||||||
|
) || card.runner?.lastname
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(
|
||||||
|
searchvalue.toLowerCase()
|
||||||
|
) || should_display_based_on_id(card.id)}
|
||||||
|
<tr data-rowid="card_{card.id}">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<input
|
||||||
|
bind:checked={card.is_selected}
|
||||||
|
type="checkbox"
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="flex items-center">{card.code}</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="flex items-center">
|
||||||
|
{#if card.runner}
|
||||||
|
<a
|
||||||
|
href="../runners/{card.runner.id}"
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{card.runner.firstname}
|
||||||
|
{card.runner.middlename || ''}
|
||||||
|
{card.runner.lastname}</a>
|
||||||
|
{:else}{$_('non-blanko')}{/if}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="flex items-center">
|
||||||
|
{#if card.enabled}
|
||||||
|
<span
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('enabled')}</span>
|
||||||
|
{:else}
|
||||||
|
<span
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('disabled')}</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{#if active_deletes[card.id] === true}
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[card.id] = false;
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
RunnerCardService.runnerCardControllerRemove(card.id, false).then(
|
||||||
|
(resp) => {
|
||||||
|
current_cards = current_cards.filter(
|
||||||
|
(obj) => obj.id !== card.id
|
||||||
|
);
|
||||||
|
Toastify({
|
||||||
|
text: $_('card-deleted'),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor:
|
||||||
|
'linear-gradient(to right, #00b09b, #96c93d)',
|
||||||
|
}).showToast();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||||
|
</td>
|
||||||
|
{:else}
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
open_edit_modal(card);
|
||||||
|
}}
|
||||||
|
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</button>
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[card.id] = true;
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
{/if}
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{/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 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 |
@@ -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();
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
<div class="text-xs uppercase font-light text-grey-500">
|
<div class="text-xs uppercase font-light text-grey-500">
|
||||||
{$_('total-donations')}
|
{$_('total-donations')}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xl font-bold">{stats.total_donation} €</div>
|
<div class="text-xl font-bold">{(stats.total_donation/100).toFixed(2)} €</div>
|
||||||
</div><svg
|
</div><svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
height="24"
|
height="24"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
import Select from "svelte-select";
|
import Select from "svelte-select";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
|
import { is_promise } from "svelte/internal";
|
||||||
export let modal_open;
|
export let modal_open;
|
||||||
export let current_donations;
|
export let current_donations;
|
||||||
const getDonorLabel = (option) =>
|
const getDonorLabel = (option) =>
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
$: donors = [];
|
$: donors = [];
|
||||||
$: runners = [];
|
$: runners = [];
|
||||||
$: is_fixed = false;
|
$: is_fixed = false;
|
||||||
|
$: is_paid = false;
|
||||||
DonorService.donorControllerGetAll().then((val) => {
|
DonorService.donorControllerGetAll().then((val) => {
|
||||||
donors = val.map((r) => {
|
donors = val.map((r) => {
|
||||||
return { label: getDonorLabel(r), value: r };
|
return { label: getDonorLabel(r), value: r };
|
||||||
@@ -57,14 +59,18 @@
|
|||||||
let amount_cent = Math.floor(amount_input * 100);
|
let amount_cent = Math.floor(amount_input * 100);
|
||||||
processed_last_submit = false;
|
processed_last_submit = false;
|
||||||
const toast = Toastify({
|
const toast = Toastify({
|
||||||
text: "adding donation",
|
text: $_('adding-donation'),
|
||||||
duration: -1,
|
duration: -1,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
if (is_fixed) {
|
if (is_fixed) {
|
||||||
let postdata = {
|
let postdata = {
|
||||||
donor,
|
donor,
|
||||||
amount: amount_cent,
|
amount: amount_cent,
|
||||||
|
paidAmount: 0
|
||||||
};
|
};
|
||||||
|
if(is_paid){
|
||||||
|
postdata.paidAmount = amount_cent;
|
||||||
|
}
|
||||||
DonationService.donationControllerPostFixed(postdata)
|
DonationService.donationControllerPostFixed(postdata)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
donor = donors[0].id || 0;
|
donor = donors[0].id || 0;
|
||||||
@@ -73,7 +79,7 @@
|
|||||||
modal_open = false;
|
modal_open = false;
|
||||||
//
|
//
|
||||||
Toastify({
|
Toastify({
|
||||||
text: "donation_added",
|
text: $_('donation_added'),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
@@ -102,7 +108,7 @@
|
|||||||
modal_open = false;
|
modal_open = false;
|
||||||
//
|
//
|
||||||
Toastify({
|
Toastify({
|
||||||
text: "donation_added",
|
text: $_('donation_added'),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
@@ -123,7 +129,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
input:before {
|
.toggle:before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 1.25rem;
|
width: 1.25rem;
|
||||||
@@ -137,12 +143,12 @@
|
|||||||
transition: 0.2s ease-in-out;
|
transition: 0.2s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:checked {
|
.toggle:checked {
|
||||||
/* @apply: bg-indigo-400; */
|
/* @apply: bg-indigo-400; */
|
||||||
background-color: #7f9cf5;
|
background-color: #7f9cf5;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:checked:before {
|
.toggle:checked:before {
|
||||||
left: 1.25rem;
|
left: 1.25rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -195,7 +201,7 @@
|
|||||||
class="ml-2 text-base"
|
class="ml-2 text-base"
|
||||||
class:text-gray-300={is_fixed}>{$_('distance-donation')}</span>
|
class:text-gray-300={is_fixed}>{$_('distance-donation')}</span>
|
||||||
<input
|
<input
|
||||||
class="relative w-10 h-5 transition-all duration-200 ease-in-out bg-gray-400 rounded-full shadow-inner outline-none appearance-none align-middle"
|
class="toggle relative w-10 h-5 transition-all duration-200 ease-in-out bg-gray-400 rounded-full shadow-inner outline-none appearance-none align-middle"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
bind:checked={is_fixed} />
|
bind:checked={is_fixed} />
|
||||||
<span
|
<span
|
||||||
@@ -267,6 +273,29 @@
|
|||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
{#if is_fixed}
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="paid"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('already-paid')}</label>
|
||||||
|
<p class="text-gray-500">
|
||||||
|
<input
|
||||||
|
id="paid"
|
||||||
|
bind:checked={is_paid}
|
||||||
|
name="paid"
|
||||||
|
type="checkbox"
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" >
|
||||||
|
<span class="align-text-bottom">
|
||||||
|
|
||||||
|
{#if is_paid}
|
||||||
|
{$_('paid')}
|
||||||
|
{:else}
|
||||||
|
{$_('open')}
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,202 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
|
import { DonationService } from "@odit/lfk-client-js";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
export let payment_modal_open = false;
|
||||||
|
export let current_donations = [];
|
||||||
|
export let editable = {};
|
||||||
|
export let original_data = {};
|
||||||
|
export let paid_amount_input = 0;
|
||||||
|
$:processed_last_submit=true;
|
||||||
|
function focus(el) {
|
||||||
|
el.focus();
|
||||||
|
}
|
||||||
|
$: createbtnenabled = is_paid_amount_valid && !(paid_amount_input*100 == original_data.paidAmount)
|
||||||
|
$: is_paid_amount_valid = paid_amount_input > 0;
|
||||||
|
(() => {
|
||||||
|
document.onkeydown = (e) => {
|
||||||
|
e = e || window.event;
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
payment_modal_open = false;
|
||||||
|
}
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
if (createbtnenabled === true) {
|
||||||
|
createbtnenabled = false;
|
||||||
|
submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
function submit() {
|
||||||
|
if (processed_last_submit === true) {
|
||||||
|
processed_last_submit = false;
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_('updating-donation'),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
editable.donor = editable.donor.id;
|
||||||
|
editable.paidAmount = paid_amount_input*100;
|
||||||
|
if(editable.responseType == "DISTANCEDONATION" || editable.runner){
|
||||||
|
editable.runner = editable.runner.id;
|
||||||
|
DonationService.donationControllerPutDistance(original_data.id, editable)
|
||||||
|
.then((result) => {
|
||||||
|
let id = original_data.id;
|
||||||
|
editable = {};
|
||||||
|
original_data = {};
|
||||||
|
payment_modal_open = false;
|
||||||
|
//
|
||||||
|
Toastify({
|
||||||
|
text: $_('donation-updated'),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
current_donations[current_donations.findIndex((c) => c.id === id)] = result;
|
||||||
|
current_donations = current_donations;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
processed_last_submit = true;
|
||||||
|
//
|
||||||
|
toast.hideToast();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
DonationService.donationControllerPutFixed(original_data.id, editable)
|
||||||
|
.then((result) => {
|
||||||
|
let id = original_data.id;
|
||||||
|
editable = {};
|
||||||
|
original_data = {};
|
||||||
|
payment_modal_open = false;
|
||||||
|
//
|
||||||
|
Toastify({
|
||||||
|
text: $_('donation-updated'),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
current_donations[current_donations.findIndex((c) => c.id === id)] = result;
|
||||||
|
current_donations = current_donations;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
processed_last_submit = true;
|
||||||
|
//
|
||||||
|
toast.hideToast();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if payment_modal_open}
|
||||||
|
<div
|
||||||
|
class="fixed z-10 inset-0 overflow-y-auto"
|
||||||
|
use:focusTrap
|
||||||
|
use:clickOutside
|
||||||
|
on:click_outside={() => {
|
||||||
|
payment_modal_open = false;
|
||||||
|
}}>
|
||||||
|
<div
|
||||||
|
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
||||||
|
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
|
||||||
|
<div
|
||||||
|
class="absolute inset-0 bg-gray-500 opacity-75"
|
||||||
|
data-id="modal_backdrop" />
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||||
|
aria-hidden="true">​</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
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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";
|
||||||
@@ -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">
|
||||||
|
|||||||
@@ -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>
|
||||||
-
|
-
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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="comments"
|
||||||
name="comments"
|
name="comments"
|
||||||
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="comments"
|
||||||
|
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="comments"
|
||||||
|
name="comments"
|
||||||
|
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="comments"
|
||||||
|
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="gridjs-input gridjs-search-input 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,403 @@
|
|||||||
|
<script>
|
||||||
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
|
import {
|
||||||
|
RunnerCardService,
|
||||||
|
RunnerOrganizationService,
|
||||||
|
RunnerTeamService,
|
||||||
|
} from "@odit/lfk-client-js";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
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}.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}.pdf`;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
a.download = `Runnercards-${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 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}.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}.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}.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"
|
||||||
|
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,332 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import {
|
||||||
|
DonationService,
|
||||||
|
RunnerTeamService,
|
||||||
|
RunnerOrganizationService
|
||||||
|
} from "@odit/lfk-client-js";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
export let certificates_show = false;
|
||||||
|
export let generate_runners = [];
|
||||||
|
export let generate_orgs = [];
|
||||||
|
export let generate_teams = [];
|
||||||
|
$: certificates_dropdown_open = false;
|
||||||
|
document.addEventListener("click", function (e) {
|
||||||
|
if (
|
||||||
|
e.target.parentNode?.parentNode?.id != "certificates:dropdown" &&
|
||||||
|
e.target.parentNode?.parentNode?.id != "certificates:dropdown:menu"
|
||||||
|
) {
|
||||||
|
certificates_dropdown_open = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function generateCertificates(locale) {
|
||||||
|
certificates_dropdown_open = false;
|
||||||
|
|
||||||
|
if (generate_orgs.length > 0) {
|
||||||
|
generateOrgCertificates(locale);
|
||||||
|
} else if (generate_teams.length > 0) {
|
||||||
|
generateTeamCertificates(locale);
|
||||||
|
} else {
|
||||||
|
generateRunnerCertificates(locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateRunnerCertificates(locale) {
|
||||||
|
const toast = Toastify({
|
||||||
|
text: $_("generating-pdf"),
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
const current_donations = (await DonationService.donationControllerGetAll()) || [];
|
||||||
|
let certificateRunners = [];
|
||||||
|
for (let runner of generate_runners) {
|
||||||
|
runner.distanceDonations = current_donations.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}.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}.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}_direct-${locale}.pdf`;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
if (count === o.teams.length && count_orgs === generate_orgs.length) {
|
||||||
|
toast.hideToast();
|
||||||
|
console.log("here")
|
||||||
|
Toastify({
|
||||||
|
text: $_("pdfs-successfully-generated"),
|
||||||
|
duration: 3500,
|
||||||
|
backgroundColor:
|
||||||
|
"linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
for (const t of o.teams) {
|
||||||
|
count++;
|
||||||
|
let runners = await RunnerTeamService.runnerTeamControllerGetRunners(
|
||||||
|
t.id
|
||||||
|
);
|
||||||
|
let certificateRunners = [];
|
||||||
|
for (let runner of runners) {
|
||||||
|
runner.distanceDonations = current_donations.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}.pdf`;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
if (count === o.teams.length && count_orgs === generate_orgs.length) {
|
||||||
|
toast.hideToast();
|
||||||
|
Toastify({
|
||||||
|
text: $_("pdfs-successfully-generated"),
|
||||||
|
duration: 3500,
|
||||||
|
backgroundColor:
|
||||||
|
"linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if certificates_show}
|
||||||
|
<div id="certificates:dropdown" class="relative inline-block">
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
certificates_dropdown_open = !certificates_dropdown_open;
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-600 text-base font-medium text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex"
|
||||||
|
id="options-menu"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-expanded="true">
|
||||||
|
{$_('generate-runner-certificates')}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
class="-mr-1 ml-2 h-5 w-5"><path
|
||||||
|
fill="none"
|
||||||
|
d="M0 0h24v24H0z" />
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M3 19h18v2H3v-2zm10-5.83l6.07-6.07 1.42 1.41L12 17 3.52 8.52l1.4-1.42L11 13.17V2h2v11.17z" /></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{#if certificates_dropdown_open}
|
||||||
|
<div
|
||||||
|
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
|
||||||
|
id="certificates:dropdown:menu">
|
||||||
|
<div
|
||||||
|
class="py-1"
|
||||||
|
role="menu"
|
||||||
|
aria-orientation="vertical"
|
||||||
|
aria-labelledby="options-menu">
|
||||||
|
<span
|
||||||
|
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
generateCertificates('de');
|
||||||
|
}}
|
||||||
|
type="submit"
|
||||||
|
class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900"
|
||||||
|
role="menuitem">
|
||||||
|
{$_('german')}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
generateCertificates('en');
|
||||||
|
}}
|
||||||
|
type="submit"
|
||||||
|
class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900"
|
||||||
|
role="menuitem">
|
||||||
|
{$_('english')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1,306 @@
|
|||||||
|
<script>
|
||||||
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
|
import {
|
||||||
|
RunnerOrganizationService,
|
||||||
|
RunnerTeamService,
|
||||||
|
} from "@odit/lfk-client-js";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
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}.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}.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}.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}.pdf`;
|
||||||
|
}
|
||||||
|
a.download = `${$_('sponsorings')}-${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) => {
|
||||||
|
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"
|
||||||
|
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}
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
document.onkeydown = (e) => {
|
document.onkeydown = (e) => {
|
||||||
e = e || window.event;
|
e = e || window.event;
|
||||||
if (e.key === "Escape") {
|
if (e.key === "Escape") {
|
||||||
import_modal_open = false;
|
cancelModal();
|
||||||
}
|
}
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
//
|
//
|
||||||
@@ -202,7 +202,7 @@
|
|||||||
toast.hideToast();
|
toast.hideToast();
|
||||||
recent_processed = true;
|
recent_processed = true;
|
||||||
Toastify({
|
Toastify({
|
||||||
text: "Import finished",
|
text: $_('import-finished'),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
@@ -281,6 +281,16 @@
|
|||||||
bind:files
|
bind:files
|
||||||
type="file" />
|
type="file" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="overflow-hidden relative mt-4 mb-4">
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
cancelModal();
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
class="w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 md:ml-40 mr-0 sm:ml-0 sm:w-auto sm:text-sm">
|
||||||
|
{$_('cancel')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if json_output.length > 0}
|
{#if json_output.length > 0}
|
||||||
{#if opened_from === 'OrgOverview'}
|
{#if opened_from === 'OrgOverview'}
|
||||||
|
|||||||
@@ -1,398 +1,302 @@
|
|||||||
<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);
|
RunnerService.runnerControllerPut(original_data.id, postdata)
|
||||||
original_data = original_data;
|
.then((resp) => {
|
||||||
Toastify({
|
Object.assign(original_data, editable);
|
||||||
text: $_("runner-updated"),
|
original_data = original_data;
|
||||||
duration: 2500,
|
Toastify({
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
text: $_("runner-updated"),
|
||||||
}).showToast();
|
duration: 2500,
|
||||||
})
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
.catch((err) => {});
|
}).showToast();
|
||||||
} else {
|
})
|
||||||
}
|
.catch((err) => {});
|
||||||
}
|
} else {
|
||||||
function deleteRunner() {
|
}
|
||||||
RunnerService.runnerControllerRemove(original_data.id, true)
|
}
|
||||||
.then((resp) => {
|
function deleteRunner() {
|
||||||
location.replace("./");
|
RunnerService.runnerControllerRemove(original_data.id, true)
|
||||||
})
|
.then((resp) => {
|
||||||
.catch((err) => {});
|
location.replace("./");
|
||||||
}
|
})
|
||||||
function generateSponsoringContract(locale) {
|
.catch((err) => {});
|
||||||
sponsoring_contracts_download_open = false;
|
}
|
||||||
const toast = Toastify({
|
</script>
|
||||||
text: $_("generating-pdf"),
|
|
||||||
duration: -1,
|
{#await runner_promise}
|
||||||
}).showToast();
|
{$_('loading-runners')}
|
||||||
fetch(
|
{:then}
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
<section class="container p-5 select-none">
|
||||||
{
|
<div class="flex flex-row mb-4">
|
||||||
method: "POST",
|
<div class="w-full">
|
||||||
headers: {
|
<nav class="w-full flex">
|
||||||
"Content-Type": "application/json",
|
<ol class="list-none flex flex-row items-center justify-start">
|
||||||
},
|
<li class="flex items-center">
|
||||||
body: JSON.stringify([original_data_pdf]),
|
<svg
|
||||||
}
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
)
|
viewBox="0 0 24 24"
|
||||||
.then((response) => {
|
class="flex-shrink-0 w-5 h-5 mr-2"
|
||||||
if (response.status != "200") {
|
fill="currentColor"
|
||||||
toast.hideToast();
|
width="24"
|
||||||
Toastify({
|
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
text: $_("pdf-generation-failed"),
|
<path
|
||||||
duration: 3500,
|
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>
|
||||||
backgroundColor:
|
</li>
|
||||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
<li class="flex items-center">
|
||||||
}).showToast();
|
<a class="mr-2" href="./">{$_('runners')}</a><svg
|
||||||
} else {
|
stroke="currentColor"
|
||||||
return response.blob();
|
fill="none"
|
||||||
}
|
stroke-width="2"
|
||||||
})
|
viewBox="0 0 24 24"
|
||||||
.then((blob) => {
|
stroke-linecap="round"
|
||||||
const url = window.URL.createObjectURL(blob);
|
stroke-linejoin="round"
|
||||||
let a = document.createElement("a");
|
class="h-3 w-3 mr-2 stroke-current"
|
||||||
a.href = url;
|
height="1em"
|
||||||
a.download =
|
width="1em"
|
||||||
"Sponsoring_" +
|
xmlns="http://www.w3.org/2000/svg"><line
|
||||||
original_data.firstname +
|
x1="5"
|
||||||
(original_data.middlename || "") +
|
y1="12"
|
||||||
original_data.lastname +
|
x2="19"
|
||||||
".pdf";
|
y2="12" />
|
||||||
document.body.appendChild(a);
|
<polyline points="12 5 19 12 12 19" /></svg>
|
||||||
a.click();
|
</li>
|
||||||
a.remove();
|
<li class="flex items-center">
|
||||||
toast.hideToast();
|
<span class="mr-2">{original_data.firstname}
|
||||||
Toastify({
|
{original_data.middlename || ''}
|
||||||
text: $_("pdf-successfully-generated"),
|
{original_data.lastname}</span>
|
||||||
duration: 3500,
|
</li>
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
</ol>
|
||||||
}).showToast();
|
</nav>
|
||||||
})
|
</div>
|
||||||
.catch((err) => {
|
</div>
|
||||||
console.error(err);
|
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||||
});
|
{original_data.firstname}
|
||||||
}
|
{original_data.middlename || ''}
|
||||||
</script>
|
{original_data.lastname}
|
||||||
|
<span data-id="runner_actions_${editable.id}">
|
||||||
{#await runner_promise}
|
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
|
||||||
{$_('loading-runners')}
|
{#if delete_triggered}
|
||||||
{:then}
|
<button
|
||||||
<section class="container p-5 select-none">
|
on:click={deleteRunner}
|
||||||
<div class="flex flex-row mb-4">
|
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>
|
||||||
<div class="w-full">
|
<button
|
||||||
<nav class="w-full flex">
|
on:click={() => {
|
||||||
<ol class="list-none flex flex-row items-center justify-start">
|
delete_triggered = !delete_triggered;
|
||||||
<li class="flex items-center">
|
}}
|
||||||
<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">{$_('cancel')}</button>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
{/if}
|
||||||
viewBox="0 0 24 24"
|
<GenerateSponsoringContracts
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2"
|
bind:sponsoring_contracts_show
|
||||||
fill="currentColor"
|
bind:generate_runners />
|
||||||
width="24"
|
<GenerateRunnerCards
|
||||||
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
bind:cards_show
|
||||||
<path
|
bind:generate_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>
|
<GenerateRunnerCertificates
|
||||||
</li>
|
bind:certificates_show
|
||||||
<li class="flex items-center">
|
bind:generate_runners />
|
||||||
<a class="mr-2" href="./">{$_('runners')}</a><svg
|
{#if !delete_triggered}
|
||||||
stroke="currentColor"
|
<button
|
||||||
fill="none"
|
on:click={() => {
|
||||||
stroke-width="2"
|
delete_triggered = true;
|
||||||
viewBox="0 0 24 24"
|
}}
|
||||||
stroke-linecap="round"
|
type="button"
|
||||||
stroke-linejoin="round"
|
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="h-3 w-3 mr-2 stroke-current"
|
{/if}
|
||||||
height="1em"
|
{/if}
|
||||||
width="1em"
|
{#if !delete_triggered}
|
||||||
xmlns="http://www.w3.org/2000/svg"><line
|
<button
|
||||||
x1="5"
|
disabled={!save_enabled}
|
||||||
y1="12"
|
class:opacity-50={!save_enabled}
|
||||||
x2="19"
|
type="button"
|
||||||
y2="12" />
|
on:click={submit}
|
||||||
<polyline points="12 5 19 12 12 19" /></svg>
|
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>
|
||||||
</li>
|
{/if}
|
||||||
<li class="flex items-center">
|
</span>
|
||||||
<span class="mr-2">{original_data.firstname}
|
</div>
|
||||||
{original_data.middlename || ''}
|
<!-- -->
|
||||||
{original_data.lastname}</span>
|
<div class="text-sm w-full">
|
||||||
</li>
|
<label
|
||||||
</ol>
|
for="firstname"
|
||||||
</nav>
|
class="font-medium text-gray-700">{$_('first-name')}</label>
|
||||||
</div>
|
<input
|
||||||
</div>
|
autocomplete="off"
|
||||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
placeholder={$_('first-name')}
|
||||||
{original_data.firstname}
|
type="text"
|
||||||
{original_data.middlename || ''}
|
class:border-red-500={!isFirstnameValid}
|
||||||
{original_data.lastname}
|
class:focus:border-red-500={!isFirstnameValid}
|
||||||
<span data-id="runner_actions_${editable.id}">
|
class:focus:ring-red-500={!isFirstnameValid}
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
|
bind:value={editable.firstname}
|
||||||
{#if delete_triggered}
|
name="firstname"
|
||||||
<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" />
|
||||||
on:click={deleteRunner}
|
{#if !isFirstnameValid}
|
||||||
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>
|
<span
|
||||||
<button
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
on:click={() => {
|
{$_('first-name-is-required')}
|
||||||
delete_triggered = !delete_triggered;
|
</span>
|
||||||
}}
|
{/if}
|
||||||
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>
|
</div>
|
||||||
{/if}
|
<div class="text-sm w-full">
|
||||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
<label
|
||||||
<div>
|
for="middlename"
|
||||||
<button
|
class="font-medium text-gray-700">{$_('middle-name')}</label>
|
||||||
on:click={() => {
|
<input
|
||||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
autocomplete="off"
|
||||||
}}
|
placeholder={$_('middle-name')}
|
||||||
type="button"
|
type="text"
|
||||||
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:value={editable.middlename}
|
||||||
id="options-menu"
|
name="middlename"
|
||||||
aria-haspopup="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" />
|
||||||
aria-expanded="true">
|
</div>
|
||||||
{$_('generate-sponsoring-contract')}
|
<div class="text-sm w-full">
|
||||||
<svg
|
<label
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
for="lastname"
|
||||||
width="24"
|
class="font-medium text-gray-700">{$_('last-name')}</label>
|
||||||
height="24"
|
<input
|
||||||
viewBox="0 0 24 24"
|
autocomplete="off"
|
||||||
class="-mr-1 ml-2 h-5 w-5"><path
|
placeholder={$_('last-name')}
|
||||||
fill="none"
|
type="text"
|
||||||
d="M0 0h24v24H0z" />
|
bind:value={editable.lastname}
|
||||||
<path
|
class:border-red-500={!isLastnameValid}
|
||||||
fill="currentColor"
|
class:focus:border-red-500={!isLastnameValid}
|
||||||
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>
|
class:focus:ring-red-500={!isLastnameValid}
|
||||||
</button>
|
name="lastname"
|
||||||
</div>
|
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 sponsoring_contracts_download_open}
|
{#if !isLastnameValid}
|
||||||
<div
|
<span
|
||||||
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="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
id="sponsoring:dropdown:menu">
|
{$_('last-name-is-required')}
|
||||||
<div
|
</span>
|
||||||
class="py-1"
|
{/if}
|
||||||
role="menu"
|
</div>
|
||||||
aria-orientation="vertical"
|
<div class="text-sm w-full">
|
||||||
aria-labelledby="options-menu">
|
<label
|
||||||
<span
|
for="email"
|
||||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
|
||||||
<button
|
<input
|
||||||
on:click={() => {
|
autocomplete="off"
|
||||||
generateSponsoringContract('de');
|
placeholder={$_('e-mail-adress')}
|
||||||
}}
|
type="email"
|
||||||
type="submit"
|
bind:value={editable.email}
|
||||||
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:border-red-500={!isEmailValid}
|
||||||
role="menuitem">
|
class:focus:border-red-500={!isEmailValid}
|
||||||
{$_('german')}
|
class:focus:ring-red-500={!isEmailValid}
|
||||||
</button>
|
name="email"
|
||||||
<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" />
|
||||||
on:click={() => {
|
{#if !isEmailValid}
|
||||||
generateSponsoringContract('en');
|
<span
|
||||||
}}
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
type="submit"
|
{$_('valid-email-is-required')}
|
||||||
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"
|
</span>
|
||||||
role="menuitem">
|
{/if}
|
||||||
{$_('english')}
|
</div>
|
||||||
</button>
|
<div class="text-sm w-full">
|
||||||
</div>
|
<label for="phone" class="font-medium text-gray-700">{$_('phone')}</label>
|
||||||
</div>
|
<input
|
||||||
{/if}
|
autocomplete="off"
|
||||||
</div>
|
placeholder={$_('phone')}
|
||||||
{#if !delete_triggered}
|
type="tel"
|
||||||
<button
|
bind:value={editable.phone}
|
||||||
on:click={() => {
|
name="phone"
|
||||||
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-runner')}</button>
|
<span class="font-medium text-gray-700">{$_('group')}</span>
|
||||||
{/if}
|
<Select
|
||||||
{/if}
|
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"
|
||||||
{#if !delete_triggered}
|
itemFilter={(label, filterText, option) => label
|
||||||
<button
|
.toLowerCase()
|
||||||
disabled={!save_enabled}
|
.includes(
|
||||||
class:opacity-50={!save_enabled}
|
filterText.toLowerCase()
|
||||||
type="button"
|
) || option.id.value
|
||||||
on:click={submit}
|
.toString()
|
||||||
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>
|
.startsWith(filterText.toLowerCase())}
|
||||||
{/if}
|
items={groups}
|
||||||
</span>
|
showChevron={true}
|
||||||
</div>
|
placeholder={$_('search-for-an-organization-or-team-by-name-or-id')}
|
||||||
<!-- -->
|
noOptionsMessage={$_('no-organization-or-team-found')}
|
||||||
<div class="text-sm w-full">
|
bind:selectedValue={group}
|
||||||
<label
|
on:select={(selectedValue) => {
|
||||||
for="firstname"
|
editable.group = selectedValue.detail.value.id;
|
||||||
class="font-medium text-gray-700">{$_('first-name')}</label>
|
}}
|
||||||
<input
|
on:clear={() => (editable.group = null)} />
|
||||||
autocomplete="off"
|
</div>
|
||||||
placeholder={$_('first-name')}
|
<div class="text-sm w-full">
|
||||||
type="text"
|
<span class="font-medium text-gray-700">{$_('distance')}</span>
|
||||||
class:border-red-500={!isFirstnameValid}
|
<br />
|
||||||
class:focus:border-red-500={!isFirstnameValid}
|
<span class="text-gray-700">{original_data.distance /1000 } km</span>
|
||||||
class:focus:ring-red-500={!isFirstnameValid}
|
</div>
|
||||||
bind:value={editable.firstname}
|
</section>
|
||||||
name="firstname"
|
{:catch error}
|
||||||
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" />
|
<PromiseError {error} />
|
||||||
{#if !isFirstnameValid}
|
{/await}
|
||||||
<span
|
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
|
||||||
{$_('first-name-is-required')}
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="text-sm w-full">
|
|
||||||
<label
|
|
||||||
for="middlename"
|
|
||||||
class="font-medium text-gray-700">{$_('middle-name')}</label>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
placeholder={$_('middle-name')}
|
|
||||||
type="text"
|
|
||||||
bind:value={editable.middlename}
|
|
||||||
name="middlename"
|
|
||||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
|
||||||
</div>
|
|
||||||
<div class="text-sm w-full">
|
|
||||||
<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,263 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
import { getLocaleFromNavigator, _ } from "svelte-i18n";
|
||||||
import {
|
import {
|
||||||
RunnerService,
|
RunnerService,
|
||||||
RunnerTeamService,
|
RunnerTeamService,
|
||||||
RunnerOrganizationService,
|
RunnerOrganizationService,
|
||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
import store from "../../store";
|
import store from "../../store";
|
||||||
import RunnersEmptyState from "./RunnersEmptyState.svelte";
|
import RunnersEmptyState from "./RunnersEmptyState.svelte";
|
||||||
import Select from "svelte-select";
|
import Select from "svelte-select";
|
||||||
import Toastify from "toastify-js";
|
import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte";
|
||||||
$: searchvalue = "";
|
import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
|
||||||
$: active_deletes = [];
|
import GenerateRunnerCertificates from "../pdf_generation/GenerateRunnerCertificates.svelte";
|
||||||
export let current_runners = [];
|
$: searchvalue = "";
|
||||||
const runners_promise = RunnerService.runnerControllerGetAll().then((val) => {
|
$: active_deletes = [];
|
||||||
current_runners = val;
|
export let current_runners = [];
|
||||||
});
|
const runners_promise = RunnerService.runnerControllerGetAll().then((val) => {
|
||||||
$: selectedFilter_teams = null;
|
current_runners = val;
|
||||||
$: selectedFilter = null;
|
});
|
||||||
$: filter__teams = selectedFilter_teams || [];
|
$: selectedFilter_teams = null;
|
||||||
$: filter__orgs = selectedFilter || [];
|
$: selectedFilter = null;
|
||||||
$: filterGroupIDs = filter__teams.concat(filter__orgs).map((i) => i.value);
|
$: filter__teams = selectedFilter_teams || [];
|
||||||
$: sponsoring_contracts_download_open = false;
|
$: filter__orgs = selectedFilter || [];
|
||||||
$: teams = [];
|
$: filterGroupIDs = filter__teams.concat(filter__orgs).map((i) => i.value);
|
||||||
$: orgs = [];
|
$: sponsoring_contracts_show = current_runners.some(
|
||||||
$: mappedteams = teams.map(function (g) {
|
(r) => r.is_selected === true
|
||||||
return { value: g.id, label: g.parentGroup.name + " > " + g.name };
|
);
|
||||||
});
|
$: cards_show = current_runners.some(
|
||||||
$: selectgroups = orgs
|
(r) => r.is_selected === true
|
||||||
.map(function (g) {
|
);
|
||||||
return { value: g.id, label: g.name };
|
$: certificates_show = current_runners.some(
|
||||||
})
|
(r) => r.is_selected === true
|
||||||
.concat(mappedteams);
|
);
|
||||||
document.addEventListener("click", function (e) {
|
$: generate_runners = current_runners.filter((r) => r.is_selected === true);
|
||||||
if (
|
$: teams = [];
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown" &&
|
$: orgs = [];
|
||||||
e.target.parentNode?.parentNode?.id != "sponsoring:dropdown:menu"
|
$: mappedteams = teams.map(function (g) {
|
||||||
) {
|
return { value: g.id, label: g.parentGroup.name + " > " + g.name };
|
||||||
sponsoring_contracts_download_open = false;
|
});
|
||||||
}
|
$: selectgroups = orgs
|
||||||
});
|
.map(function (g) {
|
||||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
return { value: g.id, label: g.name };
|
||||||
teams = val;
|
})
|
||||||
});
|
.concat(mappedteams);
|
||||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
|
||||||
orgs = val;
|
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||||
});
|
teams = val;
|
||||||
function should_display_based_on_id(id) {
|
});
|
||||||
if (searchvalue.toString().slice(-1) === "*") {
|
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||||
return id.toString().startsWith(searchvalue.replace("*", ""));
|
orgs = val;
|
||||||
}
|
});
|
||||||
return id.toString() === searchvalue;
|
function should_display_based_on_id(id) {
|
||||||
}
|
if (searchvalue.toString().slice(-1) === "*") {
|
||||||
function generateSponsoringContract(locale) {
|
return id.toString().startsWith(searchvalue.replace("*", ""));
|
||||||
sponsoring_contracts_download_open = false;
|
}
|
||||||
const toast = Toastify({
|
return id.toString() === searchvalue;
|
||||||
text: $_("generating-pdf"),
|
}
|
||||||
duration: -1,
|
</script>
|
||||||
}).showToast();
|
|
||||||
fetch(
|
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')}
|
||||||
`${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`,
|
{#await runners_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">{$_('runners-are-being-loaded')}</p>
|
||||||
},
|
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
||||||
body: JSON.stringify(
|
</div>
|
||||||
current_runners.filter((r) => r.is_selected === true)
|
{:then}
|
||||||
),
|
{#if current_runners.length === 0}
|
||||||
}
|
<RunnersEmptyState />
|
||||||
)
|
{:else}
|
||||||
.then((response) => {
|
<input
|
||||||
if (response.status != "200") {
|
type="search"
|
||||||
toast.hideToast();
|
bind:value={searchvalue}
|
||||||
Toastify({
|
placeholder={$_('datatable.search')}
|
||||||
text: $_("pdf-generation-failed"),
|
aria-label={$_('datatable.search')}
|
||||||
duration: 3500,
|
class="gridjs-input gridjs-search-input mb-4" />
|
||||||
backgroundColor:
|
<div class="block mb-6">
|
||||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
<label
|
||||||
}).showToast();
|
for="country"
|
||||||
} else {
|
class="text-sm font-medium text-gray-700">{$_('filter-by-organization-team')}</label>
|
||||||
return response.blob();
|
<Select
|
||||||
}
|
on:select={(event) => {
|
||||||
})
|
selectedFilter = event.detail;
|
||||||
.then((blob) => {
|
}}
|
||||||
const url = window.URL.createObjectURL(blob);
|
selectedValue={selectedFilter}
|
||||||
let a = document.createElement("a");
|
placeholder={$_('filter-by-organization-team')}
|
||||||
a.href = url;
|
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"
|
||||||
a.download = "Sponsoring.pdf";
|
items={selectgroups}
|
||||||
document.body.appendChild(a);
|
isMulti={true} />
|
||||||
a.click();
|
</div>
|
||||||
a.remove();
|
<div class="h-12">
|
||||||
toast.hideToast();
|
<GenerateSponsoringContracts
|
||||||
Toastify({
|
bind:sponsoring_contracts_show
|
||||||
text: $_("pdf-successfully-generated"),
|
bind:generate_runners />
|
||||||
duration: 3500,
|
<GenerateRunnerCards
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
bind:cards_show
|
||||||
}).showToast();
|
bind:generate_runners />
|
||||||
})
|
<GenerateRunnerCertificates
|
||||||
.catch((err) => {
|
bind:certificates_show
|
||||||
console.error(err);
|
bind:generate_runners />
|
||||||
});
|
</div>
|
||||||
}
|
<div
|
||||||
</script>
|
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
||||||
|
<table class="divide-y divide-gray-200 w-full">
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')}
|
<thead class="bg-gray-50">
|
||||||
{#await runners_promise}
|
<tr>
|
||||||
<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">{$_('runners-are-being-loaded')}</p>
|
<span
|
||||||
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
on:click={() => {
|
||||||
</div>
|
const newstate = !current_runners.some((r) => r.is_selected === true);
|
||||||
{:then}
|
current_runners = current_runners.map((r) => {
|
||||||
{#if current_runners.length === 0}
|
r.is_selected = newstate;
|
||||||
<RunnersEmptyState />
|
return r;
|
||||||
{:else}
|
});
|
||||||
<input
|
}}
|
||||||
type="search"
|
class="underline cursor-pointer select-none">{#if current_runners.some((r) => r.is_selected === true)}
|
||||||
bind:value={searchvalue}
|
{$_('deselect-all')}
|
||||||
placeholder={$_('datatable.search')}
|
{:else}{$_('select-all')}{/if}
|
||||||
aria-label={$_('datatable.search')}
|
</span>
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
</th>
|
||||||
<div class="block mb-6">
|
<th
|
||||||
<label
|
scope="col"
|
||||||
for="country"
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
class="text-sm font-medium text-gray-700">{$_('filter-by-organization-team')}</label>
|
{$_('name')}
|
||||||
<Select
|
</th>
|
||||||
on:select={(event) => {
|
<th
|
||||||
selectedFilter = event.detail;
|
scope="col"
|
||||||
}}
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
selectedValue={selectedFilter}
|
{$_('contact-information')}
|
||||||
placeholder={$_('filter-by-organization-team')}
|
</th>
|
||||||
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"
|
<th
|
||||||
items={selectgroups}
|
scope="col"
|
||||||
isMulti={true} />
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
</div>
|
{$_('group')}
|
||||||
<div class="h-12">
|
</th>
|
||||||
{#if current_runners.some((r) => r.is_selected === true)}
|
<th
|
||||||
<div id="sponsoring:dropdown" class="relative inline-block">
|
scope="col"
|
||||||
<div>
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
<button
|
{$_('distance-in-km')}
|
||||||
on:click={() => {
|
</th>
|
||||||
sponsoring_contracts_download_open = !sponsoring_contracts_download_open;
|
<th scope="col" class="relative px-6 py-3">
|
||||||
}}
|
<span class="sr-only">{$_('action')}</span>
|
||||||
type="button"
|
</th>
|
||||||
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"
|
</tr>
|
||||||
id="options-menu"
|
</thead>
|
||||||
aria-haspopup="true"
|
<tbody class="divide-y divide-gray-200">
|
||||||
aria-expanded="true">
|
{#each current_runners as runner}
|
||||||
{$_('generate-sponsoring-contracts')}
|
{#if runner.firstname
|
||||||
<svg
|
.toLowerCase()
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
.includes(
|
||||||
width="24"
|
searchvalue.toLowerCase()
|
||||||
height="24"
|
) || runner.lastname
|
||||||
viewBox="0 0 24 24"
|
.toLowerCase()
|
||||||
class="-mr-1 ml-2 h-5 w-5"><path
|
.includes(
|
||||||
fill="none"
|
searchvalue.toLowerCase()
|
||||||
d="M0 0h24v24H0z" />
|
) || should_display_based_on_id(runner.id)}
|
||||||
<path
|
{#if filterGroupIDs.includes(runner.group.id) || filterGroupIDs.includes(runner.group.parentGroup?.id) || filterGroupIDs.length === 0}
|
||||||
fill="currentColor"
|
<tr
|
||||||
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>
|
data-rowid="user_{runner.id}"
|
||||||
</button>
|
data-groupid={runner.group.id}>
|
||||||
</div>
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
{#if sponsoring_contracts_download_open}
|
<input
|
||||||
<div
|
bind:checked={runner.is_selected}
|
||||||
class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"
|
type="checkbox"
|
||||||
id="sponsoring:dropdown:menu">
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
<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
|
{runner.firstname}
|
||||||
class="block w-full text-left px-4 py-2 text-sm text-gray-700">{$_('select-language')}</span>
|
{runner.middlename || ''}
|
||||||
<button
|
{runner.lastname}
|
||||||
on:click={() => {
|
</div>
|
||||||
generateSponsoringContract('de');
|
</div>
|
||||||
}}
|
</div>
|
||||||
type="submit"
|
</td>
|
||||||
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"
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
role="menuitem">
|
{#if runner.email}
|
||||||
{$_('german')}
|
<div class="text-sm text-gray-500">{runner.email}</div>
|
||||||
</button>
|
{/if}
|
||||||
<button
|
{#if runner.phone}
|
||||||
on:click={() => {
|
<div class="text-sm text-gray-500">{runner.phone}</div>
|
||||||
generateSponsoringContract('en');
|
{/if}
|
||||||
}}
|
{#if runner.address.address1 !== null}
|
||||||
type="submit"
|
{runner.address.address1}<br />
|
||||||
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"
|
{runner.address.address2 || ''}<br />
|
||||||
role="menuitem">
|
{runner.address.postalcode}
|
||||||
{$_('english')}
|
{runner.address.city}
|
||||||
</button>
|
{runner.address.country}
|
||||||
</div>
|
{/if}
|
||||||
</div>
|
</td>
|
||||||
{/if}
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
</div>
|
{#if runner.group.responseType === 'RUNNERTEAM'}
|
||||||
{/if}
|
<a
|
||||||
</div>
|
href="../teams/{runner.group.id}"
|
||||||
<div
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{runner.group.parentGroup.name} > {runner.group.name}</a>
|
||||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
{/if}
|
||||||
<table class="divide-y divide-gray-200 w-full">
|
{#if runner.group.responseType === 'RUNNERORGANIZATION'}
|
||||||
<thead class="bg-gray-50">
|
<a
|
||||||
<tr>
|
href="../orgs/{runner.group.id}"
|
||||||
<th
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{runner.group.name}</a>
|
||||||
scope="col"
|
{/if}
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
</td>
|
||||||
<span
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
on:click={() => {
|
{runner.distance /1000 } km
|
||||||
const newstate = !current_runners.some((r) => r.is_selected === true);
|
</td>
|
||||||
current_runners = current_runners.map((r) => {
|
{#if active_deletes[runner.id] === true}
|
||||||
r.is_selected = newstate;
|
<td
|
||||||
return r;
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
});
|
<button
|
||||||
}}
|
on:click={() => {
|
||||||
class="underline cursor-pointer select-none">{#if current_runners.some((r) => r.is_selected === true)}
|
active_deletes[runner.id] = false;
|
||||||
{$_('deselect-all')}
|
}}
|
||||||
{:else}{$_('select-all')}{/if}
|
tabindex="0"
|
||||||
</span>
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
||||||
</th>
|
<button
|
||||||
<th
|
on:click={() => {
|
||||||
scope="col"
|
RunnerService.runnerControllerRemove(runner.id, true)
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
.then((resp) => {
|
||||||
{$_('name')}
|
current_runners = current_runners.filter((obj) => obj.id !== runner.id);
|
||||||
</th>
|
})
|
||||||
<th
|
.catch((err) => {});
|
||||||
scope="col"
|
}}
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
tabindex="0"
|
||||||
{$_('contact-information')}
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||||
</th>
|
</td>
|
||||||
<th
|
{:else}
|
||||||
scope="col"
|
<td
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
{$_('group')}
|
<a
|
||||||
</th>
|
href="./{runner.id}"
|
||||||
<th
|
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
||||||
scope="col"
|
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
<button
|
||||||
{$_('distance-in-km')}
|
on:click={() => {
|
||||||
</th>
|
active_deletes[runner.id] = true;
|
||||||
<th scope="col" class="relative px-6 py-3">
|
}}
|
||||||
<span class="sr-only">{$_('action')}</span>
|
tabindex="0"
|
||||||
</th>
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||||
</tr>
|
{/if}
|
||||||
</thead>
|
</td>
|
||||||
<tbody class="divide-y divide-gray-200">
|
{/if}
|
||||||
{#each current_runners as runner}
|
</tr>
|
||||||
{#if runner.firstname
|
{/if}
|
||||||
.toLowerCase()
|
{/if}
|
||||||
.includes(
|
{/each}
|
||||||
searchvalue.toLowerCase()
|
</tbody>
|
||||||
) || runner.lastname
|
</table>
|
||||||
.toLowerCase()
|
</div>
|
||||||
.includes(
|
{/if}
|
||||||
searchvalue.toLowerCase()
|
{:catch error}
|
||||||
) || should_display_based_on_id(runner.id)}
|
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
|
||||||
{#if filterGroupIDs.includes(runner.group.id) || filterGroupIDs.includes(runner.group.parentGroup?.id) || filterGroupIDs.length === 0}
|
<span class="inline-block align-middle mr-8">
|
||||||
<tr
|
<b class="capitalize">{$_('general_promise_error')}</b>
|
||||||
data-rowid="user_{runner.id}"
|
{error}
|
||||||
data-groupid={runner.group.id}>
|
</span>
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
</div>
|
||||||
<input
|
{/await}
|
||||||
bind:checked={runner.is_selected}
|
{/if}
|
||||||
type="checkbox"
|
|
||||||
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="ml-4">
|
|
||||||
<div class="text-sm font-medium text-gray-900">
|
|
||||||
{runner.firstname}
|
|
||||||
{runner.middlename || ''}
|
|
||||||
{runner.lastname}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
{#if runner.email}
|
|
||||||
<div class="text-sm text-gray-500">{runner.email}</div>
|
|
||||||
{/if}
|
|
||||||
{#if runner.phone}
|
|
||||||
<div class="text-sm text-gray-500">{runner.phone}</div>
|
|
||||||
{/if}
|
|
||||||
{#if runner.address.address1 !== null}
|
|
||||||
{runner.address.address1}<br />
|
|
||||||
{runner.address.address2 || ''}<br />
|
|
||||||
{runner.address.postalcode}
|
|
||||||
{runner.address.city}
|
|
||||||
{runner.address.country}
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
{#if runner.group.responseType === 'RUNNERTEAM'}
|
|
||||||
<a
|
|
||||||
href="../teams/{runner.group.id}"
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{runner.group.name}</a>
|
|
||||||
{/if}
|
|
||||||
{#if runner.group.responseType === 'RUNNERORGANIZATION'}
|
|
||||||
<a
|
|
||||||
href="../orgs/{runner.group.id}"
|
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{runner.group.name}</a>
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
{runner.distance}
|
|
||||||
</td>
|
|
||||||
{#if active_deletes[runner.id] === true}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[runner.id] = false;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
RunnerService.runnerControllerRemove(runner.id, true)
|
|
||||||
.then((resp) => {
|
|
||||||
current_runners = current_runners.filter((obj) => obj.id !== runner.id);
|
|
||||||
})
|
|
||||||
.catch((err) => {});
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
|
||||||
</td>
|
|
||||||
{:else}
|
|
||||||
<td
|
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
||||||
<a
|
|
||||||
href="./{runner.id}"
|
|
||||||
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
active_deletes[runner.id] = true;
|
|
||||||
}}
|
|
||||||
tabindex="0"
|
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
|
||||||
{/if}
|
|
||||||
</td>
|
|
||||||
{/if}
|
|
||||||
</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}
|
|
||||||
@@ -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%)",
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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,151 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
|
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:focusTrap
|
||||||
|
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 { focusTrap } from "svelte-focus-trap";
|
||||||
|
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:focusTrap
|
||||||
|
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 { focusTrap } from "svelte-focus-trap";
|
||||||
|
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" use:focusTrap>
|
||||||
|
<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="gridjs-input gridjs-search-input 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 |
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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}
|
|
||||||
@@ -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="gridjs-input gridjs-search-input 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}
|
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
import { UserService } from "@odit/lfk-client-js";
|
import { UserService } from "@odit/lfk-client-js";
|
||||||
import isEmail from "validator/es/lib/isEmail";
|
import isEmail from "validator/es/lib/isEmail";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
|
import PasswordStrength, {
|
||||||
|
password_strong_enough,
|
||||||
|
} from "../auth/PasswordStrength.svelte";
|
||||||
export let modal_open;
|
export let modal_open;
|
||||||
export let current_users;
|
export let current_users;
|
||||||
let firstname_input;
|
let firstname_input;
|
||||||
@@ -28,7 +31,10 @@
|
|||||||
$: isLastnameValid = lastname_input_value.trim().length !== 0;
|
$: isLastnameValid = lastname_input_value.trim().length !== 0;
|
||||||
$: isFirstnameValid = firstname_input_value.trim().length !== 0;
|
$: isFirstnameValid = firstname_input_value.trim().length !== 0;
|
||||||
$: createbtnenabled =
|
$: createbtnenabled =
|
||||||
isFirstnameValid && isLastnameValid && isPasswordValid && isEmailValid;
|
isFirstnameValid &&
|
||||||
|
isLastnameValid &&
|
||||||
|
password_strong_enough(password_input_value) &&
|
||||||
|
isEmailValid;
|
||||||
(function () {
|
(function () {
|
||||||
document.onkeydown = function (e) {
|
document.onkeydown = function (e) {
|
||||||
e = e || window.event;
|
e = e || window.event;
|
||||||
@@ -203,12 +209,8 @@
|
|||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
|
||||||
{#if !isPasswordValid}
|
<PasswordStrength
|
||||||
<span
|
bind:password_change={password_input_value} />
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
|
||||||
{$_('password-is-required')}
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-6">
|
<div class="col-span-6">
|
||||||
<label
|
<label
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
+474
-391
@@ -1,392 +1,475 @@
|
|||||||
{
|
{
|
||||||
"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-scan": "Scan erstellen",
|
||||||
"add-user-group": "Neue Gruppe erstellen",
|
"add-the-first-scanstation": "Erstelle deine erste Scannerstation.",
|
||||||
"add-your-first-contact": "Erstelle den ersten Kontakt",
|
"add-user-group": "Neue Gruppe erstellen",
|
||||||
"add-your-first-donor": "Erstelle die erste Sponsor:in",
|
"add-your-first-card": "Erstelle deine erste Läuferkarte",
|
||||||
"add-your-first-group": "Erstelle die erste Gruppe",
|
"add-your-first-contact": "Erstelle den ersten Kontakt",
|
||||||
"add-your-first-organization": "Erstelle die erste Organisation",
|
"add-your-first-donor": "Erstelle die erste Sponsor:in",
|
||||||
"add-your-first-runner": "Erstelle die erste Läufer:in",
|
"add-your-first-group": "Erstelle die erste Gruppe",
|
||||||
"add-your-first-team": "Erstelle das erste Team",
|
"add-your-first-organization": "Erstelle die erste Organisation",
|
||||||
"add-your-first-track": "Erstelle den ersten Track (Laufstrecke).",
|
"add-your-first-runner": "Erstelle die erste Läufer:in",
|
||||||
"add-your-first-user": "Erstelle die erste Benutzer:in",
|
"add-your-first-team": "Erstelle das erste Team",
|
||||||
"add-your-fist-donation": "Erstelle dein erstes Sponsoring",
|
"add-your-first-track": "Erstelle den ersten Track (Laufstrecke).",
|
||||||
"add-your-fist-scan": "Füge deinen ersten Scan hinzu",
|
"add-your-first-user": "Erstelle die erste Benutzer:in",
|
||||||
"adding-scan": "Scan wird hinzugefügt",
|
"add-your-fist-donation": "Erstelle dein erstes Sponsoring",
|
||||||
"address": "Adresse",
|
"add-your-fist-scan": "Füge deinen ersten Scan hinzu",
|
||||||
"address-is-required": "Du musst eine Adresse angeben",
|
"adding-card": "Karte wird erstellt",
|
||||||
"after-deletion-we-cant-restore-your-old-profile": "Nach der Löschung können auch die Admins dein Profil nicht wiederherstellen!",
|
"adding-donation": "Sponsoring wird erstellt...",
|
||||||
"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-scan": "Scan wird hinzugefügt",
|
||||||
"all-associated-donations-will-get-deleted-as-well": "Alle Sponsorings dieser Sponsor:in werden ebenfalls gelöscht",
|
"address": "Adresse",
|
||||||
"all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!",
|
"address-is-required": "Du musst eine Adresse angeben",
|
||||||
"all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!",
|
"after-deletion-we-cant-restore-your-old-profile": "Nach der Löschung können auch die Admins dein Profil nicht wiederherstellen!",
|
||||||
"amount-per-kilometer": "Betrag pro Kilometer",
|
"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.",
|
||||||
"apartment-suite-etc": "Apartment, Wohnung, etc.",
|
"all-associated-donations-will-get-deleted-as-well": "Alle Sponsorings dieser Sponsor:in werden ebenfalls gelöscht",
|
||||||
"application_name": "Lauf für Kaya! - Admin",
|
"all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!",
|
||||||
"applying-changes": "Änderungen anwenden",
|
"all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!",
|
||||||
"attention": "Achtung!",
|
"already-paid": "Bereits bezahlt",
|
||||||
"author": "Autor:in",
|
"amount": "Anzahl",
|
||||||
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer:innen für den Import bestätigen.",
|
"amount-per-kilometer": "Betrag pro Kilometer",
|
||||||
"by": "von",
|
"apartment-suite-etc": "Apartment, Wohnung, etc.",
|
||||||
"cancel": "Abbrechen",
|
"application_name": "Lauf für Kaya! - Admin",
|
||||||
"cancel-delete": "Löschen abbrechen",
|
"applying-changes": "Änderungen anwenden",
|
||||||
"cancel-keep-donor": "Abbrechen, Sponsor:in behalten",
|
"attention": "Achtung!",
|
||||||
"cancel-keep-my-profile": "Abbrechen, mein Profil behalten",
|
"author": "Autor:in",
|
||||||
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
|
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer:innen für den Import bestätigen.",
|
||||||
"cancel-keep-team": "Abbrechen, Team behalten",
|
"by": "von",
|
||||||
"cannot-reset-your-password-directly": "Schade. \nWir können das Passwort leider nicht direkt zurücksetzen.\nBitte sende uns eine Mail in der du deine Identität bestätigst.",
|
"cancel": "Abbrechen",
|
||||||
"change-your-password-here": "Hier kannst du dein Passwort ändern",
|
"cancel-delete": "Löschen abbrechen",
|
||||||
"changing-your-password": "Passwort wird geändert",
|
"cancel-keep-donor": "Abbrechen, Sponsor:in behalten",
|
||||||
"city": "Stadt",
|
"cancel-keep-my-profile": "Abbrechen, mein Profil behalten",
|
||||||
"click-to-copy-token-to-clipboard": "Klicke auf den Token, um ihn in deine Zwischenablage zu kopieren",
|
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
|
||||||
"close": "Schließen",
|
"cancel-keep-team": "Abbrechen, Team behalten",
|
||||||
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
|
"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": "Bestätigen",
|
"card-added": "Karte wurde hinzugefügt",
|
||||||
"confirm-delete": "Löschung Bestätigen",
|
"card-deleted": "Karte gelöscht",
|
||||||
"confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen",
|
"card-updated": "Karte aktualisiert",
|
||||||
"confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil löschen",
|
"cards": "Läuferkarten",
|
||||||
"confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.",
|
"certificates": "Urkunden",
|
||||||
"confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.",
|
"change-your-password-here": "Hier kannst du dein Passwort ändern",
|
||||||
"confirm-deletion": "Löschung Bestätigen",
|
"changing-your-password": "Passwort wird geändert",
|
||||||
"confirm-the-new-password": "Neues Passwort bestätigen",
|
"city": "Stadt",
|
||||||
"contact": "Kontakt",
|
"click-to-copy-the-link-into-your-clipboard": "Klicke auf den Link, um ihn in deine Zwischenablage zu kopieren",
|
||||||
"contact-deleted": "Kontakt gelöscht",
|
"click-to-copy-token-to-clipboard": "Klicke auf den Token, um ihn in deine Zwischenablage zu kopieren",
|
||||||
"contact-information": "Kontaktinformation",
|
"close": "Schließen",
|
||||||
"contact-is-being-updated": "Kontakt wird aktualisiert ...",
|
"code": "Code",
|
||||||
"contact-is-not-a-member-in-any-group": "Kontakt gehört zu keiner Gruppe",
|
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
|
||||||
"contacts": "Kontakte",
|
"confirm": "Bestätigen",
|
||||||
"contacts-are-being-loaded": "Kontakte werden geladen ...",
|
"confirm-delete": "Löschung Bestätigen",
|
||||||
"copied-token-to-clipboard": "Token wurde in die Zwischenablage kopiert",
|
"confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen",
|
||||||
"count_organizations": "Organisationen (Anzahl)",
|
"confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil löschen",
|
||||||
"count_teams": "Teams (Anzahl)",
|
"confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.",
|
||||||
"create": "Erstellen",
|
"confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.",
|
||||||
"create-a-new": "Erstelle eine neue",
|
"confirm-deletion": "Löschung Bestätigen",
|
||||||
"create-a-new-contact": "Kontakt erstellen",
|
"confirm-the-new-password": "Neues Passwort bestätigen",
|
||||||
"create-a-new-distance-donation": "Erstelle ein neues Sponsoring",
|
"contact": "Kontakt",
|
||||||
"create-a-new-donor": "Neue Sponsor:in erstellen",
|
"contact-added": "Kontakt wurde hinzugefügt",
|
||||||
"create-a-new-fixed-donation": "Erstelle eine neue Festbetragsspende",
|
"contact-deleted": "Kontakt gelöscht",
|
||||||
"create-a-new-organization": "Neue Organisation anlegen",
|
"contact-information": "Kontaktinformation",
|
||||||
"create-a-new-runner": "Neue Läufer:in erstellen",
|
"contact-is-being-added": "Kontakt wird erstellt...",
|
||||||
"create-a-new-scan-fixed-only": "Neuen Scan erstellen (nur mit Festdistanz)",
|
"contact-is-being-updated": "Kontakt wird aktualisiert ...",
|
||||||
"create-a-new-scanstation": "Neue Station erstellen",
|
"contact-is-not-a-member-in-any-group": "Kontakt gehört zu keiner Gruppe",
|
||||||
"create-a-new-team": "Erstelle ein neues Team",
|
"contacts": "Kontakte",
|
||||||
"create-a-new-track": "Neuen Track erstellen",
|
"contacts-are-being-loaded": "Kontakte werden geladen ...",
|
||||||
"create-a-new-user": "Neue Benutzer:in anlegen",
|
"copied-link-to-clipboard": "Link wurde in die Zwischenablage kopiert",
|
||||||
"create-a-new-user-group": "Erstelle eine neue Gruppe",
|
"copied-token-to-clipboard": "Token wurde in die Zwischenablage kopiert",
|
||||||
"create-organization": "Organisation erstellen",
|
"count_organizations": "Organisationen (Anzahl)",
|
||||||
"create-team": "Team erstellen",
|
"count_teams": "Teams (Anzahl)",
|
||||||
"create-track": "Track erstellen",
|
"create": "Erstellen",
|
||||||
"create-user": "Benutzer anlegen",
|
"create-a-new": "Erstelle eine neue",
|
||||||
"credits": "Credits",
|
"create-a-new-card": "Neue Läuferkarte erstellen",
|
||||||
"csv_import__class": "Klasse",
|
"create-a-new-contact": "Kontakt erstellen",
|
||||||
"csv_import__firstname": "Vorname",
|
"create-a-new-distance-donation": "Erstelle ein neues Sponsoring",
|
||||||
"csv_import__lastname": "Nachname",
|
"create-a-new-donor": "Neue Sponsor:in erstellen",
|
||||||
"csv_import__middlename": "Mittelname",
|
"create-a-new-fixed-donation": "Erstelle eine neue Festbetragsspende",
|
||||||
"csv_import__team": "Team",
|
"create-a-new-organization": "Neue Organisation anlegen",
|
||||||
"danger-zone": "Gefahrenzone",
|
"create-a-new-runner": "Neue Läufer:in erstellen",
|
||||||
"dashboard-greeting": "Hallo",
|
"create-a-new-scan-fixed-only": "Neuen Scan erstellen (nur mit Festdistanz)",
|
||||||
"dashboard-title": "Dashboard",
|
"create-a-new-scanstation": "Neue Station erstellen",
|
||||||
"datatable": {
|
"create-a-new-team": "Erstelle ein neues Team",
|
||||||
"search": "🔍 Suche ...",
|
"create-a-new-track": "Neuen Track erstellen",
|
||||||
"an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten",
|
"create-a-new-user": "Neue Benutzer:in anlegen",
|
||||||
"loading": "Wird geladen...",
|
"create-a-new-user-group": "Erstelle eine neue Gruppe",
|
||||||
"next": "Nächste",
|
"create-and-generate-pdf": "Erstellen und PDF herunterladen",
|
||||||
"of": "von",
|
"create-bulk-blanco-cards": "Blankokarten erstellen",
|
||||||
"previous": "Vorherige",
|
"create-bulk-cards": "Blankokarten erstellen",
|
||||||
"to": "bis",
|
"create-organization": "Organisation erstellen",
|
||||||
"showing": "Zeige",
|
"create-team": "Team erstellen",
|
||||||
"no_matching_records_found": "Keine passenden Einträge gefunden",
|
"create-track": "Track erstellen",
|
||||||
"page": "Seite",
|
"create-user": "Benutzer anlegen",
|
||||||
"records": "Einträge",
|
"create-without-pdf": "Ohne PDF erstellen",
|
||||||
"sort_column_ascending": "Spalte aufsteigend sortieren",
|
"created-blanco-cards": "Blankokarten wurden erstellt",
|
||||||
"sort_column_descending": "Spalte absteigend sortieren"
|
"creating-blanco-cards": "Erstelle Blankokarten",
|
||||||
},
|
"credits": "Credits",
|
||||||
"delete": "Löschen",
|
"csv_import__class": "Klasse",
|
||||||
"delete-contact": "Kontakt löschen",
|
"csv_import__firstname": "Vorname",
|
||||||
"delete-donation": "Sponsporing löschen",
|
"csv_import__lastname": "Nachname",
|
||||||
"delete-donor": "Sponsor:in löschen",
|
"csv_import__middlename": "Mittelname",
|
||||||
"delete-group": "Gruppe löschen",
|
"csv_import__team": "Team",
|
||||||
"delete-organization": "Organisation löschen",
|
"danger-zone": "Gefahrenzone",
|
||||||
"delete-profile": "Profil löschen",
|
"dashboard-greeting": "Hallo",
|
||||||
"delete-runner": "Läufer:in löschen",
|
"dashboard-title": "Dashboard",
|
||||||
"delete-scan": "Scan löschen",
|
"datatable": {
|
||||||
"delete-station": "Station löschen",
|
"search": "🔍 Suche ...",
|
||||||
"delete-team": "Team Löschen",
|
"an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten",
|
||||||
"delete-user": "Benutzer:in löschen",
|
"loading": "Wird geladen...",
|
||||||
"deleted-scan": "Scan wurde gelöscht",
|
"next": "Nächste",
|
||||||
"dependency_name": "Name",
|
"of": "von",
|
||||||
"description": "Beschreibung",
|
"previous": "Vorherige",
|
||||||
"description-optional": "Beschreibung (optional)",
|
"to": "bis",
|
||||||
"deselect-all": "Alle abwählen",
|
"showing": "Zeige",
|
||||||
"details": "Details",
|
"no_matching_records_found": "Keine passenden Einträge gefunden",
|
||||||
"disabled": "deaktiviert",
|
"page": "Seite",
|
||||||
"distance": "Distanz",
|
"records": "Einträge",
|
||||||
"distance-donation": "Sponsoring",
|
"sort_column_ascending": "Spalte aufsteigend sortieren",
|
||||||
"distance-in-km": "Distanz (in KM)",
|
"sort_column_descending": "Spalte absteigend sortieren"
|
||||||
"distance-track": "Distanz (+Track)",
|
},
|
||||||
"do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?",
|
"delete": "Löschen",
|
||||||
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
|
"delete-contact": "Kontakt löschen",
|
||||||
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?",
|
"delete-donation": "Sponsoring löschen",
|
||||||
"do-you-want-to-delete-this-donor-with-all-related-donations": "Möchtest du diese Sponsor:in mit all ihren Sponsorings löschen?",
|
"delete-donor": "Sponsor:in löschen",
|
||||||
"documentation": "Dokumentation",
|
"delete-group": "Gruppe löschen",
|
||||||
"donation-amount": "Sponsoringbetrag",
|
"delete-organization": "Organisation löschen",
|
||||||
"donation-amount-must-be-greater-that-0-00eur": "Der Sponsoringbetrag muss größer als 0.00€ sein.",
|
"delete-profile": "Profil löschen",
|
||||||
"donations": "Sponsorings",
|
"delete-runner": "Läufer:in löschen",
|
||||||
"donor": "Sponsor:in",
|
"delete-scan": "Scan löschen",
|
||||||
"donor-added": "Sponsor:in hinzugefügt",
|
"delete-station": "Station löschen",
|
||||||
"donor-deleted": "Sponsor:in gelöscht",
|
"delete-team": "Team Löschen",
|
||||||
"donor-has-no-associated-donations": "Zur Sponsor:in gibt es noch keine Sponsorings",
|
"delete-user": "Benutzer:in löschen",
|
||||||
"donor-is-being-added": "Sponsor:in wird hinzugefügt...",
|
"deleted-scan": "Scan wurde gelöscht",
|
||||||
"donor-is-being-updated": "Sponsor:in wird aktualisiert",
|
"dependency_name": "Name",
|
||||||
"donors": "Sponsor:innen",
|
"description": "Beschreibung",
|
||||||
"donors-are-being-loaded": "Sponsor:innen werden geladen",
|
"description-optional": "Beschreibung (optional)",
|
||||||
"dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?",
|
"deselect-all": "Alle abwählen",
|
||||||
"dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌",
|
"details": "Details",
|
||||||
"e-mail-adress": "E-Mail-Adresse",
|
"disabled": "deaktiviert",
|
||||||
"edit": "Bearbeiten",
|
"distance": "Distanz",
|
||||||
"edit-permissions": "Berechtigungen bearbeiten",
|
"distance-donation": "Sponsoring",
|
||||||
"email_address_or_username": "E-Mail-Adresse/ Benutzername",
|
"distance-in-km": "Distanz (in KM)",
|
||||||
"enabled": "aktiviert",
|
"distance-track": "Distanz (+Track)",
|
||||||
"enabled_large": "Disabled",
|
"do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?",
|
||||||
"english": "Englisch",
|
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
|
||||||
"error-during-import": "Fehler beim Importieren",
|
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?",
|
||||||
"error-whyile-copying-to-clipboard": "Fehler beim Kopieren in die Zwischenablage",
|
"do-you-want-to-delete-this-donor-with-all-related-donations": "Möchtest du diese Sponsor:in mit all ihren Sponsorings löschen?",
|
||||||
"error_on_login": "😢Fehler beim Login",
|
"documentation": "Dokumentation",
|
||||||
"erteilte": "Direkt erteilte",
|
"donation-amount": "Sponsoringbetrag",
|
||||||
"everything-concerning-your-profile": "Alles zu deinem Profil",
|
"donation-amount-must-be-greater-that-0-00eur": "Der Sponsoringbetrag muss größer als 0.00€ sein.",
|
||||||
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃♂️🏃♀️🏃♂️",
|
"donation-deleted": "Sponsoring gelöscht",
|
||||||
"faq": "FAQ",
|
"donation-updated": "Sponsoring wurde aktualisiert",
|
||||||
"filter-by-organization-team": "Filtern nach Organisation / Team",
|
"donation_added": "Sponsoring hinzugefügt",
|
||||||
"first-name": "Vorname",
|
"donations": "Sponsorings",
|
||||||
"first-name-is-required": "Vorname muss angegeben werden",
|
"donor": "Sponsor:in",
|
||||||
"first-scan-of-the-day": "Erster Scan des Tages",
|
"donor-added": "Sponsor:in hinzugefügt",
|
||||||
"fixed-donation": "Festbetragsspende",
|
"donor-deleted": "Sponsor:in gelöscht",
|
||||||
"forgot_password": "Passwort vergessen?",
|
"donor-has-no-associated-donations": "Zur Sponsor:in gibt es noch keine Sponsorings",
|
||||||
"geerbte": "geerbte",
|
"donor-is-being-added": "Sponsor:in wird hinzugefügt...",
|
||||||
"general-stats": "Allgemeine Statistiken",
|
"donor-is-being-updated": "Sponsor:in wird aktualisiert",
|
||||||
"general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten",
|
"donors": "Sponsor:innen",
|
||||||
"generate-sponsoring-contract": "Sponsoringvertrag generieren",
|
"donors-are-being-loaded": "Sponsor:innen werden geladen",
|
||||||
"generate-sponsoring-contracts": "Sponsoringverträge generieren",
|
"dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?",
|
||||||
"generating-pdf": "Pdf wird generiert...",
|
"dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌",
|
||||||
"generating-pdfs": "PDFs werden generiert...",
|
"e-mail-adress": "E-Mail-Adresse",
|
||||||
"generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.",
|
"edit": "Bearbeiten",
|
||||||
"german": "Deutsch",
|
"edit-a-card": "Läuferkarte bearbeiten",
|
||||||
"go-to-login": "Zum Login",
|
"edit-permissions": "Berechtigungen bearbeiten",
|
||||||
"goback": "Zur Startseite",
|
"email_address_or_username": "E-Mail-Adresse/ Benutzername",
|
||||||
"granted": "Gewährt",
|
"enabled": "aktiviert",
|
||||||
"group": "Gruppe",
|
"enabled_large": "Aktiviert",
|
||||||
"group-added": "Gruppe hinzugefügt",
|
"english": "Englisch",
|
||||||
"group-is-being-added": "Gruppe wird erstellt",
|
"enter-payment": "Zahlung eingeben",
|
||||||
"group-name-is-required": "Der Gruppenname muss angegeben werden.",
|
"error-during-import": "Fehler beim Importieren",
|
||||||
"group-updated": "Gruppe aktualisiert",
|
"error-whyile-copying-to-clipboard": "Fehler beim Kopieren in die Zwischenablage",
|
||||||
"groups": "Gruppen",
|
"error_on_login": "😢Fehler beim Login",
|
||||||
"groups-are-being-loaded": "Gruppen werden geladen",
|
"erteilte": "Direkt erteilte",
|
||||||
"home": "Start",
|
"everything-concerning-your-profile": "Alles zu deinem Profil",
|
||||||
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
|
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃♂️🏃♀️🏃♂️",
|
||||||
"import-finished": "Import abgeschlossen",
|
"faq": "FAQ",
|
||||||
"import-runners": "Läufer:innen importieren",
|
"filename_sponsoringquittungsliste": "SponsoringQuittungsListe",
|
||||||
"import__target-organization": "Ziel Organisation",
|
"filter-by-organization-team": "Filtern nach Organisation / Team",
|
||||||
"imprint": "Impressum ",
|
"first-name": "Vorname",
|
||||||
"imprint-loading": "Impressum lädt...",
|
"first-name-is-required": "Vorname muss angegeben werden",
|
||||||
"inactive": "Inaktiv",
|
"first-scan-of-the-day": "Erster Scan des Tages",
|
||||||
"installed-version": "Installierte Version",
|
"fixed-donation": "Festbetragsspende",
|
||||||
"internal-error": "Interner Fehler",
|
"forgot_password": "Passwort vergessen?",
|
||||||
"invalid": "Ungültig",
|
"geerbte": "geerbte",
|
||||||
"invalid-mail-reset": "Das ist keine gültige E-Mail",
|
"general-stats": "Allgemeine Statistiken",
|
||||||
"laeufer-hinzufuegen": "Läufer:in hinzufügen",
|
"general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten",
|
||||||
"laeufer-importieren": "Läufer:innen importieren",
|
"generate-runner-certificate": "Urkunde generieren",
|
||||||
"laptime": "Rundenzeit",
|
"generate-runner-certificates": "Urkunden generieren",
|
||||||
"last-name": "Nachname",
|
"generate-runnercards": "Läuferkarten generieren",
|
||||||
"last-name-is-required": "Nachname muss angegeben werden",
|
"generate-sponsoring-contract": "Sponsoringvertrag generieren",
|
||||||
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
|
"generate-sponsoring-contracts": "Sponsoringverträge generieren",
|
||||||
"license": "Lizenz",
|
"generating-pdf": "PDF wird generiert...",
|
||||||
"licenses-are-being-loaded": "Lizenzen werden geladen...",
|
"generating-pdfs": "PDFs werden generiert...",
|
||||||
"loading-contact-details": "Kontaktdaten werden geladen ...",
|
"generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.",
|
||||||
"loading-donation-details": "Lade Sponsoringdetails",
|
"german": "Deutsch",
|
||||||
"loading-donor-details": "Lade Details",
|
"go-to-login": "Zum Login",
|
||||||
"loading-group-detail": "Lade Gruppendetails...",
|
"goback": "Zur Startseite",
|
||||||
"loading-profile-data": "Lade Profildaten",
|
"granted": "Gewährt",
|
||||||
"loading-runners": "Läufer:innen werden geladen...",
|
"group": "Gruppe",
|
||||||
"loading-station-details": "Lade Scanstation-Details ...",
|
"group-added": "Gruppe hinzugefügt",
|
||||||
"log_in": "Anmelden",
|
"group-is-being-added": "Gruppe wird erstellt",
|
||||||
"log_in_to_your_account": "Bitte melde dich an",
|
"group-name-is-required": "Der Gruppenname muss angegeben werden.",
|
||||||
"login_is_checked": "Login wird überprüft",
|
"group-updated": "Gruppe aktualisiert",
|
||||||
"logout": "Abmelden",
|
"groups": "Gruppen",
|
||||||
"mail-validation-in-progress": "E-Mail Verifizierung läuft... ",
|
"groups-are-being-loaded": "Gruppen werden geladen",
|
||||||
"manage-admin-users": "Nutzer verwalten",
|
"home": "Start",
|
||||||
"middle-name": "Mittelname",
|
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
|
||||||
"minimum-lap-time-in-s": "Minimale Rundenzeit (in Sekunden)",
|
"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.",
|
||||||
"minimum-lap-time-must-be-a-positive-number-or-0": "Die minimale Rundenzeit muss eine positive Zahl oder 0 sein",
|
"import-finished": "Import abgeschlossen",
|
||||||
"name": "Name",
|
"import-runners": "Läufer:innen importieren",
|
||||||
"name-is-required": "Der Gruppenname muss angegeben werden",
|
"import__target-organization": "Ziel Organisation",
|
||||||
"new-password": "Neues Passwort",
|
"imprint": "Impressum ",
|
||||||
"no-contact-found": "Keine Kontakte gefunden",
|
"imprint-loading": "Impressum lädt...",
|
||||||
"no-contact-selected": "Kein Kontakt ausgewählt",
|
"inactive": "Inaktiv",
|
||||||
"no-contact-specified": "Kein Kontakt angegeben",
|
"installed-version": "Installierte Version",
|
||||||
"no-donors-found": "Keine Spender:innen gefunden",
|
"internal-error": "Interner Fehler",
|
||||||
"no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢",
|
"invalid": "Ungültig",
|
||||||
"no-organization-or-team-found": "Keine Organisationen oder Teams gefunden",
|
"invalid-mail-reset": "Das ist keine gültige E-Mail",
|
||||||
"no-organization-specified": "Keine Organisation angegeben",
|
"just-enter-how-many-you-want-and-the-system-will-create-them": "Gebe einfach ein, wie viele Blankokarten das System erstellen soll.",
|
||||||
"no-organizations-found": "Keine Organisationen gefunden",
|
"laeufer-hinzufuegen": "Läufer:in hinzufügen",
|
||||||
"no-runners-found": "Keine Läufer:innen gefunden",
|
"laeufer-importieren": "Läufer:innen importieren",
|
||||||
"no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.",
|
"laptime": "Rundenzeit",
|
||||||
"organization": "Organisation",
|
"last-name": "Nachname",
|
||||||
"organization-added": "Organisation hinzugefügt",
|
"last-name-is-required": "Nachname muss angegeben werden",
|
||||||
"organization-deleted": "Organisation gelöscht",
|
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
|
||||||
"organization-detail-is-being-loaded": "Organisationsdetails werden geladen ...",
|
"license": "Lizenz",
|
||||||
"organization-is-being-added": "Organisation wird hinzugefügt ...",
|
"licenses-are-being-loaded": "Lizenzen werden geladen...",
|
||||||
"organization-name-is-required": "Der Name muss angegeben werden",
|
"loading-cards": "Läuferkarten werden geladen",
|
||||||
"organizations": "Organisationen",
|
"loading-contact-details": "Kontaktdaten werden geladen ...",
|
||||||
"organizations-are-being-loaded": "Organisationen werden geladen ...",
|
"loading-donation-details": "Lade Sponsoringdetails",
|
||||||
"orgs": "Organisationen",
|
"loading-donor-details": "Lade Details",
|
||||||
"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!",
|
"loading-group-detail": "Lade Gruppendetails...",
|
||||||
"password": "Passwort",
|
"loading-profile-data": "Lade Profildaten",
|
||||||
"password-changed": "Passwort wurde aktualisiert!",
|
"loading-runners": "Läufer:innen werden geladen...",
|
||||||
"password-is-required": "Passwort muss angegeben werden",
|
"loading-station-details": "Lade Scanstation-Details ...",
|
||||||
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
|
"log_in": "Anmelden",
|
||||||
"password-reset-in-progress": "Passwort wird zurückgesetzt...",
|
"log_in_to_your_account": "Bitte melde dich an",
|
||||||
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
|
"login_is_checked": "Login wird überprüft",
|
||||||
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
|
"logout": "Abmelden",
|
||||||
"passwords-dont-match": "Die Passwörter stimmen nicht überein.",
|
"mail-validation-in-progress": "E-Mail Verifizierung läuft... ",
|
||||||
"pdf-generation-failed": "PDF Generierung fehlgeschlagen!",
|
"manage-admin-users": "Nutzer verwalten",
|
||||||
"pdf-successfully-generated": "PDF wurde erfolgreich generiert!",
|
"middle-name": "Mittelname",
|
||||||
"pdfs-successfully-generated": "Alle PDFs wurden generiert!",
|
"minimum-lap-time-in-s": "Minimale Rundenzeit (in Sekunden)",
|
||||||
"per-kilometer": "pro Kilometer",
|
"minimum-lap-time-must-be-a-positive-number-or-0": "Die minimale Rundenzeit muss eine positive Zahl oder 0 sein",
|
||||||
"permissions": "Berechtigungen",
|
"must-be-at-least-10-characters-long": "Passwort muss mindestens 10 Zeichen lang sein!",
|
||||||
"permissions-updated": "Berechtigungen aktualisiert!",
|
"must-contain-a-lowercase-letter": "Passwort muss einen Großbuchstaben enthalten!",
|
||||||
"phone": "Telefon",
|
"must-contain-a-number": "Passwort muss eine Zahl enthalten!",
|
||||||
"please-copy-the-token-and-store-it-somewhere-save": "Bitte kopiere dir den Token und bewahre ihn gut auf.",
|
"must-contain-a-uppercase-letter": "Passwort muss einen Kleinbuchstaben enthalten!",
|
||||||
"please-provide-a-password": "Bitte gebe ein Passwort an...",
|
"name": "Name",
|
||||||
"please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen",
|
"name-is-required": "Der Gruppenname muss angegeben werden",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.",
|
"new-password": "Neues Passwort",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-scan": "Bitte gebe alle notwendigen Informationen an, um einen neuen Scan zu erstellen.",
|
"no-contact-found": "Keine Kontakte gefunden",
|
||||||
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
|
"no-contact-selected": "Kein Kontakt ausgewählt",
|
||||||
"please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.",
|
"no-contact-specified": "Kein Kontakt angegeben",
|
||||||
"please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.",
|
"no-donors-found": "Keine Spender:innen gefunden",
|
||||||
"please-provide-the-required-information-to-add-a-new-organization": "Bitte gebe alle nötigen Informationen an, im die neue Organisation zu erstellen.",
|
"no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢",
|
||||||
"please-provide-the-required-information-to-add-a-new-runner": "Bitte die benötigten Informationen angeben.",
|
"no-organization-or-team-found": "Keine Organisationen oder Teams gefunden",
|
||||||
"please-provide-the-required-information-to-add-a-new-team": "Bitte gebe alle nötigen Informationen an, im das neue Team zu erstellen.",
|
"no-organization-specified": "Keine Organisation angegeben",
|
||||||
"please-provide-the-required-information-to-add-a-new-track": "Bitte die benötigten Informationen angeben.",
|
"no-organizations-found": "Keine Organisationen gefunden",
|
||||||
"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-runners-found": "Keine Läufer:innen gefunden",
|
||||||
"please-provide-the-required-information-to-create-a-new-scanstation": "Bitte gebe alle für eine Scannerstation notwendigen Informationen an",
|
"no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.",
|
||||||
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
|
"non-blanko": "Keine/Blankokarte",
|
||||||
"privacy": "Datenschutz",
|
"open": "OFFEN",
|
||||||
"privacy-loading": "Datenschutzerklärung lädt...",
|
"organization": "Organisation",
|
||||||
"profile": "Profil",
|
"organization-added": "Organisation hinzugefügt",
|
||||||
"profile-picture": "Profilbild",
|
"organization-deleted": "Organisation gelöscht",
|
||||||
"profile-updated": "Profil wurde aktualisiert!",
|
"organization-detail-is-being-loaded": "Organisationsdetails werden geladen ...",
|
||||||
"read-license": "Lizenz-Text lesen",
|
"organization-is-being-added": "Organisation wird hinzugefügt ...",
|
||||||
"receipt-needed": "Spendenquittung benötigt",
|
"organization-name-is-required": "Der Name muss angegeben werden",
|
||||||
"repo_link": "Link",
|
"organizations": "Organisationen",
|
||||||
"request-a-new-reset-mail": "Neue Reset-Mail anfordern",
|
"organizations-are-being-loaded": "Organisationen werden geladen ...",
|
||||||
"reset-my-password": "Passwort zurücksetzen",
|
"orgs": "Organisationen",
|
||||||
"reset-password": "Passwort zurücksetzen",
|
"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!",
|
||||||
"runner": "Läufer:in",
|
"paid": "BEZAHLT",
|
||||||
"runner-added": "Läufer:in hinzugefügt",
|
"paid-amount": "Gezahlter Betrag",
|
||||||
"runner-import": "Läufer:innen Import",
|
"password": "Passwort",
|
||||||
"runner-is-being-added": "Läufer:in wird hinzugefügt...",
|
"password-changed": "Passwort wurde aktualisiert!",
|
||||||
"runner-updated": "Läufer:in aktualisiert!",
|
"password-is-required": "Passwort muss angegeben werden",
|
||||||
"runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen",
|
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
|
||||||
"runners": "Läufer",
|
"password-reset-in-progress": "Passwort wird zurückgesetzt...",
|
||||||
"runners-are-being-imported": "Läufer:innen werden importiert ...",
|
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
|
||||||
"runners-are-being-loaded": "Läufer:innen werden geladen ...",
|
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
|
||||||
"save": "Speichern",
|
"passwords-dont-match": "Die Passwörter stimmen nicht überein!",
|
||||||
"save-changes": "Änderungen speichern",
|
"payment-amount-must-be-greater-than-0-00eur": "Der Zahlungsbetrag muss größer als 0.00€ sein!",
|
||||||
"scan-added": "Scan hinzugefügt",
|
"pdf-generation-failed": "PDF Generierung fehlgeschlagen!",
|
||||||
"scan-is-being-updated": "Scan wird aktualisiert",
|
"pdf-successfully-generated": "PDF wurde erfolgreich generiert!",
|
||||||
"scan-with-fixed-distance": "Scan mit Festdistanz",
|
"pdfs-successfully-generated": "Alle PDFs wurden generiert!",
|
||||||
"scans": "Scans",
|
"per-kilometer": "pro Kilometer",
|
||||||
"scans-are-being-loaded": "Scans werden geladen",
|
"permissions": "Berechtigungen",
|
||||||
"scanstation": "Scanner Station",
|
"permissions-updated": "Berechtigungen aktualisiert!",
|
||||||
"scanstation-added": "Station wurde erstellt",
|
"phone": "Telefon",
|
||||||
"scanstation-is-being-added": "Scannerstation wird angelegt...",
|
"please-copy-the-token-and-store-it-somewhere-save": "Bitte kopiere dir den Token und bewahre ihn gut auf.",
|
||||||
"scanstations": "Scanner Stationen",
|
"please-provide-a-password": "Bitte gebe ein Passwort an...",
|
||||||
"scanstations-are-being-loaded": "Scannerstationen werden geladen...",
|
"please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen",
|
||||||
"search-for-an-organization-by-name-or-id": "Suche eine Organisation (via Name oder Id)",
|
"please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.",
|
||||||
"search-for-an-organization-or-team-by-name-or-id": "Suche eine Organisation oder ein Team (via Name oder Id)",
|
"please-provide-the-nessecary-information-to-create-a-new-scan": "Bitte gebe alle notwendigen Informationen an, um einen neuen Scan zu erstellen.",
|
||||||
"search-for-donor-name-or-id": "Suche eine Spender:in (via Name oder Id)",
|
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
|
||||||
"search-for-permission": "Berechtigungen durchsuchen",
|
"please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.",
|
||||||
"search-for-runner-by-name-or-id": "Suche eine Läufer:in (via Name oder Id)",
|
"please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.",
|
||||||
"select-all": "Alle auswählen",
|
"please-provide-the-required-information-to-add-a-new-organization": "Bitte gebe alle nötigen Informationen an, im die neue Organisation zu erstellen.",
|
||||||
"select-language": "Sprache auswählen",
|
"please-provide-the-required-information-to-add-a-new-runner": "Bitte die benötigten Informationen angeben.",
|
||||||
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
|
"please-provide-the-required-information-to-add-a-new-team": "Bitte gebe alle nötigen Informationen an, im das neue Team zu erstellen.",
|
||||||
"set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen",
|
"please-provide-the-required-information-to-add-a-new-track": "Bitte die benötigten Informationen angeben.",
|
||||||
"settings": "Einstellungen",
|
"please-provide-the-required-information-to-add-a-new-user": "Bitte gebe alle nötigen Informationen an, im die neue Benutzer:in zu erstellen.",
|
||||||
"settings-for-your-profile": "Die Einstellungen deines Accounts",
|
"please-provide-the-required-information-to-create-a-new-scanstation": "Bitte gebe alle für eine Scannerstation notwendigen Informationen an",
|
||||||
"something-about-the-group": "Infos zur Gruppe",
|
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
|
||||||
"stats-are-being-loaded": "Die Statistiken werden geladen...",
|
"please-wait-a-moment-your-login-is-still-being-processed": "Bitte warte einen Moment, deine Anmeldung wird verarbeitet",
|
||||||
"status": "Status",
|
"privacy": "Datenschutz",
|
||||||
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
|
"privacy-loading": "Datenschutzerklärung lädt...",
|
||||||
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
|
"profile": "Profil",
|
||||||
"team": "Team",
|
"profile-deleted": "Profil gelöscht!",
|
||||||
"team-detail-is-being-loaded": "Team wird geladen...",
|
"profile-picture": "Profilbild",
|
||||||
"team-name": "Teamname",
|
"profile-updated": "Profil wurde aktualisiert!",
|
||||||
"team-name-is-required": "Teamname ist erforderlich",
|
"read-license": "Lizenz-Text lesen",
|
||||||
"teams": "Teams",
|
"receipt-needed": "Spendenquittung benötigt",
|
||||||
"teams-are-being-loaded": "Teams werden geladen ...",
|
"repo_link": "Link",
|
||||||
"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...",
|
"request-a-new-reset-mail": "Neue Reset-Mail anfordern",
|
||||||
"the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.",
|
"reset-my-password": "Passwort zurücksetzen",
|
||||||
"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!",
|
"reset-password": "Passwort zurücksetzen",
|
||||||
"there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.",
|
"runner": "Läufer:in",
|
||||||
"there-are-no-donations-yet": "Es gibt noch keine Sponsorings",
|
"runner-added": "Läufer:in hinzugefügt",
|
||||||
"there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen",
|
"runner-import": "Läufer:innen Import",
|
||||||
"there-are-no-groups-yet": "Es gibt noch keine Gruppen",
|
"runner-is-being-added": "Läufer:in wird hinzugefügt...",
|
||||||
"there-are-no-organizations-added-yet": "Es wurden noch keine Organisationen hinzugefügt.",
|
"runner-updated": "Läufer:in aktualisiert!",
|
||||||
"there-are-no-runners-added-yet": "Es wurden noch keine Läufer:innen hinzugefügt.",
|
"runnercards": "Laeuferkarten",
|
||||||
"there-are-no-scans-yet": "Es gibt noch keine Scans",
|
"runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen",
|
||||||
"there-are-no-teams-added-yet": "Es wurden noch keine Teams hinzugefügt.",
|
"runners": "Läufer",
|
||||||
"there-are-no-users-added-yet": "Es wurden noch keine Benutzer hinzugefügt.",
|
"runners-are-being-imported": "Läufer:innen werden importiert ...",
|
||||||
"this-might-take-a-moment": "Das könnte einen kleinen Moment dauern",
|
"runners-are-being-loaded": "Läufer:innen werden geladen ...",
|
||||||
"this-scanstation-is": "Diese Station ist",
|
"save": "Speichern",
|
||||||
"token": "Token",
|
"save-changes": "Änderungen speichern",
|
||||||
"total-distance": "gelaufene Strecke",
|
"scan-added": "Scan hinzugefügt",
|
||||||
"total-donation-amount": "Gesamtbetrag",
|
"scan-is-being-updated": "Scan wird aktualisiert",
|
||||||
"total-donations": "Spendensumme",
|
"scan-with-fixed-distance": "Scan mit Festdistanz",
|
||||||
"total-scans": "gesamte Scans",
|
"scans": "Scans",
|
||||||
"track": "Track",
|
"scans-are-being-loaded": "Scans werden geladen",
|
||||||
"track-added": "Track hinzugefügt",
|
"scanstation": "Scanner Station",
|
||||||
"track-data-is-being-loaded": "Trackdaten werden geladen",
|
"scanstation-added": "Station wurde erstellt",
|
||||||
"track-is-being-added": "Track wird hinzugefügt...",
|
"scanstation-is-being-added": "Scannerstation wird angelegt...",
|
||||||
"track-length-in-m": "Tracklänge (in Metern)",
|
"scanstations": "Scanner Stationen",
|
||||||
"track-length-must-be-greater-than-0": "Die Länge muss größer als 0 (Meter) sein",
|
"scanstations-are-being-loaded": "Scannerstationen werden geladen...",
|
||||||
"track-name": "Trackname",
|
"search-for-an-organization-by-name-or-id": "Suche eine Organisation (via Name oder Id)",
|
||||||
"track-name-must-not-be-empty": "Der Name muss angegeben werden",
|
"search-for-an-organization-or-team-by-name-or-id": "Suche eine Organisation oder ein Team (via Name oder Id)",
|
||||||
"tracks": "Tracks",
|
"search-for-donor-name-or-id": "Suche eine Spender:in (via Name oder Id)",
|
||||||
"update-password": "Passwort ändern",
|
"search-for-permission": "Berechtigungen durchsuchen",
|
||||||
"updated-contact": "Kontakt aktualisiert!",
|
"search-for-runner-by-name-or-id": "Suche eine Läufer:in (via Name oder Id)",
|
||||||
"updated-donor": "Sponsor:in wurde aktualisiert",
|
"select-all": "Alle auswählen",
|
||||||
"updated-organization": "Organisation wurde aktualisiert",
|
"select-language": "Sprache auswählen",
|
||||||
"updated-scan": "Scan wurde aktualisiert",
|
"selfservice-registration": "Selfservice Registrierung",
|
||||||
"updateing-group": "Gruppe wird aktualisiert...",
|
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
|
||||||
"updating-organization": "Organisation wird aktualisiert",
|
"set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen",
|
||||||
"updating-permissions": "Berechtigungen werden aktualisiert...",
|
"settings": "Einstellungen",
|
||||||
"updating-runner": "Läufer:in wird aktualisiert.",
|
"settings-for-your-profile": "Die Einstellungen deines Accounts",
|
||||||
"updating-user": "Benutzer:in wird aktualisiert...",
|
"something-about-the-group": "Infos zur Gruppe",
|
||||||
"updating-your-profile": "Profil wird aktualisiert...",
|
"sponsoring-quittungs-liste_herunterladen": "Sponsoring-Quittungs-Liste herunterladen",
|
||||||
"user-added": "Benutzer hinzugefügt",
|
"sponsorings": "Sponsoringerklaerungen",
|
||||||
"user-groups": "Benutzergruppen",
|
"stats-are-being-loaded": "Die Statistiken werden geladen...",
|
||||||
"user-is-being-added": "Benutzer wird hinzugefügt ...",
|
"status": "Status",
|
||||||
"user-updated": "Benutzer:in wurde aktualisiert",
|
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
|
||||||
"username": "Benutzername",
|
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
|
||||||
"users": "Benutzer",
|
"team": "Team",
|
||||||
"valid": "Gültig",
|
"team-added": "Team wurde hinzugefügt",
|
||||||
"valid-city-is-required": "Du musst eine Stadt angeben",
|
"team-deleted": "Team gelöscht",
|
||||||
"valid-email-is-required": "Es wird eine valide E-Mail Adresse benötigt",
|
"team-detail-is-being-loaded": "Team wird geladen...",
|
||||||
"valid-international-phone-number-is-required": "Du musst eine Telefonnummer im internationalen Format angeben...",
|
"team-is-being-added": "Team wird erstellt...",
|
||||||
"valid-zipcode-postal-code-is-required": "Du musst eine valide Postleitzahl angeben",
|
"team-name": "Teamname",
|
||||||
"verfuegbare": "Verfügbar",
|
"team-name-is-required": "Teamname ist erforderlich",
|
||||||
"welcome_wavinghand": "Willkommen 👋",
|
"teams": "Teams",
|
||||||
"yes-i-copied-the-token": "Ja, ich habe den Token kopiert",
|
"teams-are-being-loaded": "Teams werden geladen ...",
|
||||||
"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!",
|
"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...",
|
||||||
"you-can-now-use-your-new-password-to-log-in-to-your-account": "Du kannst dich jetzt mit deinem neuen Passwort anmelden! 🎉",
|
"the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.",
|
||||||
"you-dont-have-any-scanstations-yet": "Es gibt noch keine Scannerstationen",
|
"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!",
|
||||||
"you-have-to-provide-an-organization": "Du musst eine Organisation angeben",
|
"there-are-no-cards-yet": "Es gibt noch keine Läuferkarten.",
|
||||||
"zip-postal-code": "Postleitzahl"
|
"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-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",
|
||||||
|
"statsclients": "Statsclient (aka Beamershow)",
|
||||||
|
"create-a-new-statsclient": "Neuen Statsclient erstellen",
|
||||||
|
"statsclients-are-being-loaded": "Statsclients werden geladen",
|
||||||
|
"prefix": "Prefix",
|
||||||
|
"key": "Schlüssel",
|
||||||
|
"statsclient-deleted": "Statsclient wurde gelöscht",
|
||||||
|
"cancel-keep-statsclient": "Abbrechen und Statsclient behalten",
|
||||||
|
"confirm-delete-statsclient": "Bestätigung, Statsclient löschen",
|
||||||
|
"statsclient-is-being-added": "Statsclient wird angelegt...",
|
||||||
|
"please-provide-the-required-information-to-create-a-new-statsclient": "Bitte gebe alle für einen Statsclient notwendigen Informationen an",
|
||||||
|
"you-dont-have-any-scanclients-yet": "Es gibt noch keine Statsclients",
|
||||||
|
"add-the-first-statsclient": "Erstelle deinen ersten Statsclient.",
|
||||||
|
"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!",
|
||||||
|
"delete-statsclient": "Statsclient löschen"
|
||||||
|
}
|
||||||
+475
-391
@@ -1,392 +1,476 @@
|
|||||||
{
|
{
|
||||||
"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-user-group": "Add User Group",
|
||||||
"add-your-first-group": "Add your first group",
|
"add-your-first-card": "Add your first card",
|
||||||
"add-your-first-organization": "Add your first organization",
|
"add-your-first-contact": "Add your first contact",
|
||||||
"add-your-first-runner": "Add your first runner",
|
"add-your-first-donor": "add your first donor",
|
||||||
"add-your-first-team": "Add your first team",
|
"add-your-first-group": "Add your first group",
|
||||||
"add-your-first-track": "Add your first track.",
|
"add-your-first-organization": "Add your first organization",
|
||||||
"add-your-first-user": "Add your first user",
|
"add-your-first-runner": "Add your first runner",
|
||||||
"add-your-fist-donation": "Add your fist donation",
|
"add-your-first-team": "Add your first team",
|
||||||
"add-your-fist-scan": "Add your fist scan",
|
"add-your-first-track": "Add your first track.",
|
||||||
"adding-scan": "Adding Scan",
|
"add-your-first-user": "Add your first user",
|
||||||
"address": "Address",
|
"add-your-fist-donation": "Add your fist donation",
|
||||||
"address-is-required": "Address is required",
|
"add-your-fist-scan": "Add your fist scan",
|
||||||
"after-deletion-we-cant-restore-your-old-profile": "After deletion we can't restore your old profile!",
|
"adding-card": "Adding Card",
|
||||||
"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-donation": "Adding donation...",
|
||||||
"all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well",
|
"adding-scan": "Adding Scan",
|
||||||
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
|
"address": "Address",
|
||||||
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!",
|
"address-is-required": "Address is required",
|
||||||
"amount-per-kilometer": "Amount per kilometer",
|
"after-deletion-we-cant-restore-your-old-profile": "After deletion we can't restore your old profile!",
|
||||||
"apartment-suite-etc": "Apartment, suite, etc.",
|
"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.",
|
||||||
"application_name": "Lauf für Kaya! - Admin",
|
"all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well",
|
||||||
"applying-changes": "Applying Changes",
|
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
|
||||||
"attention": "Attention!",
|
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!",
|
||||||
"author": "Author",
|
"already-paid": "Already paid",
|
||||||
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.",
|
"amount": "Amount",
|
||||||
"by": "by",
|
"amount-per-kilometer": "Amount per kilometer",
|
||||||
"cancel": "Cancel",
|
"apartment-suite-etc": "Apartment, suite, etc.",
|
||||||
"cancel-delete": "Cancel Delete",
|
"application_name": "Lauf für Kaya! - Admin",
|
||||||
"cancel-keep-donor": "Cancel, keep donor",
|
"applying-changes": "Applying Changes",
|
||||||
"cancel-keep-my-profile": "Cancel, keep my profile",
|
"attention": "Attention!",
|
||||||
"cancel-keep-organization": "Cancel, keep organization",
|
"author": "Author",
|
||||||
"cancel-keep-team": "Cancel, keep team",
|
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.",
|
||||||
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
|
"by": "by",
|
||||||
"change-your-password-here": "Change your password here",
|
"cancel": "Cancel",
|
||||||
"changing-your-password": "Changing your password",
|
"cancel-delete": "Cancel Delete",
|
||||||
"city": "City",
|
"cancel-keep-donor": "Cancel, keep donor",
|
||||||
"click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard",
|
"cancel-keep-my-profile": "Cancel, keep my profile",
|
||||||
"close": "Close",
|
"cancel-keep-organization": "Cancel, keep organization",
|
||||||
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
|
"cancel-keep-team": "Cancel, keep team",
|
||||||
"confirm": "Confirm",
|
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
|
||||||
"confirm-delete": "Confirm Delete",
|
"card-added": "Card added",
|
||||||
"confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations",
|
"card-deleted": "Card deleted",
|
||||||
"confirm-delete-my-user-profile": "Confirm, delete my user profile",
|
"card-updated": "Card updated",
|
||||||
"confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.",
|
"cards": "Cards",
|
||||||
"confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.",
|
"certificates": "Certificates",
|
||||||
"confirm-deletion": "Confirm Deletion",
|
"change-your-password-here": "Change your password here",
|
||||||
"confirm-the-new-password": "Confirm the new password",
|
"changing-your-password": "Changing your password",
|
||||||
"contact": "Contact",
|
"city": "City",
|
||||||
"contact-deleted": "Contact deleted",
|
"click-to-copy-the-link-into-your-clipboard": "Click to copy the link into your clipboard",
|
||||||
"contact-information": "Contact Information",
|
"click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard",
|
||||||
"contact-is-being-updated": "Contact is being updated...",
|
"close": "Close",
|
||||||
"contact-is-not-a-member-in-any-group": "Contact is not a member in any group",
|
"code": "Code",
|
||||||
"contacts": "Contacts",
|
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
|
||||||
"contacts-are-being-loaded": "contacts are being loaded...",
|
"confirm": "Confirm",
|
||||||
"copied-token-to-clipboard": "Copied token to clipboard",
|
"confirm-delete": "Confirm Delete",
|
||||||
"count_organizations": "# Organizations",
|
"confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations",
|
||||||
"count_teams": "# Teams",
|
"confirm-delete-my-user-profile": "Confirm, delete my user profile",
|
||||||
"create": "Create",
|
"confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.",
|
||||||
"create-a-new": "Create a new",
|
"confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.",
|
||||||
"create-a-new-contact": "Create a new contact",
|
"confirm-deletion": "Confirm Deletion",
|
||||||
"create-a-new-distance-donation": "Create a new distance donation",
|
"confirm-the-new-password": "Confirm the new password",
|
||||||
"create-a-new-donor": "Create a new donor",
|
"contact": "Contact",
|
||||||
"create-a-new-fixed-donation": "Create a new fixed donation",
|
"contact-added": "Contact added",
|
||||||
"create-a-new-organization": "Create a new Organization",
|
"contact-deleted": "Contact deleted",
|
||||||
"create-a-new-runner": "Create a new Runner",
|
"contact-information": "Contact Information",
|
||||||
"create-a-new-scan-fixed-only": "Create a new scan (fixed only)",
|
"contact-is-being-added": "Contact is being added...",
|
||||||
"create-a-new-scanstation": "Create a new station",
|
"contact-is-being-updated": "Contact is being updated...",
|
||||||
"create-a-new-team": "Create a new team",
|
"contact-is-not-a-member-in-any-group": "Contact is not a member in any group",
|
||||||
"create-a-new-track": "Create a new Track",
|
"contacts": "Contacts",
|
||||||
"create-a-new-user": "Create a new User",
|
"contacts-are-being-loaded": "contacts are being loaded...",
|
||||||
"create-a-new-user-group": "Create a new user group",
|
"copied-link-to-clipboard": "Copied link to clipboard",
|
||||||
"create-organization": "Create Organization",
|
"copied-token-to-clipboard": "Copied token to clipboard",
|
||||||
"create-team": "Create Team",
|
"count_organizations": "# Organizations",
|
||||||
"create-track": "Create Track",
|
"count_teams": "# Teams",
|
||||||
"create-user": "Create User",
|
"create": "Create",
|
||||||
"credits": "Credits",
|
"create-a-new": "Create a new",
|
||||||
"csv_import__class": "Class",
|
"create-a-new-card": "Create a new card",
|
||||||
"csv_import__firstname": "Firstname",
|
"create-a-new-contact": "Create a new contact",
|
||||||
"csv_import__lastname": "Lastname",
|
"create-a-new-distance-donation": "Create a new distance donation",
|
||||||
"csv_import__middlename": "Middlename",
|
"create-a-new-donor": "Create a new donor",
|
||||||
"csv_import__team": "Team",
|
"create-a-new-fixed-donation": "Create a new fixed donation",
|
||||||
"danger-zone": "Danger zone",
|
"create-a-new-organization": "Create a new Organization",
|
||||||
"dashboard-greeting": "Hello",
|
"create-a-new-runner": "Create a new Runner",
|
||||||
"dashboard-title": "Dashboard",
|
"create-a-new-scan-fixed-only": "Create a new scan (fixed only)",
|
||||||
"datatable": {
|
"create-a-new-scanstation": "Create a new station",
|
||||||
"search": "🔍 Search...",
|
"create-a-new-team": "Create a new team",
|
||||||
"sort_column_ascending": "Sort column ascending",
|
"create-a-new-track": "Create a new Track",
|
||||||
"sort_column_descending": "Sort column descending",
|
"create-a-new-user": "Create a new User",
|
||||||
"previous": "Previous",
|
"create-a-new-user-group": "Create a new user group",
|
||||||
"next": "Next",
|
"create-and-generate-pdf": "Create and generate PDF",
|
||||||
"page": "Page",
|
"create-bulk-blanco-cards": "Create bulk blanco cards",
|
||||||
"showing": "Showing",
|
"create-bulk-cards": "Add blanco cards",
|
||||||
"records": "Records",
|
"create-organization": "Create Organization",
|
||||||
"of": "of",
|
"create-team": "Create Team",
|
||||||
"to": "to",
|
"create-track": "Create Track",
|
||||||
"loading": "Loading...",
|
"create-user": "Create User",
|
||||||
"no_matching_records_found": "No matching records found",
|
"create-without-pdf": "Create without PDF",
|
||||||
"an_error_happened_while_fetching_the_data": "An error happened while fetching the data"
|
"created-blanco-cards": "Created blanco cards",
|
||||||
},
|
"creating-blanco-cards": "Creating blanco cards",
|
||||||
"delete": "Delete",
|
"credits": "Credits",
|
||||||
"delete-contact": "Delete Contact",
|
"csv_import__class": "Class",
|
||||||
"delete-donation": "Delete Donation",
|
"csv_import__firstname": "Firstname",
|
||||||
"delete-donor": "Delete donor",
|
"csv_import__lastname": "Lastname",
|
||||||
"delete-group": "Delete Group",
|
"csv_import__middlename": "Middlename",
|
||||||
"delete-organization": "Delete Organization",
|
"csv_import__team": "Team",
|
||||||
"delete-profile": "Delete Profile",
|
"danger-zone": "Danger zone",
|
||||||
"delete-runner": "Delete Runner",
|
"dashboard-greeting": "Hello",
|
||||||
"delete-scan": "Delete scan",
|
"dashboard-title": "Dashboard",
|
||||||
"delete-station": "Delete station",
|
"datatable": {
|
||||||
"delete-team": "Delete Team",
|
"search": "🔍 Search...",
|
||||||
"delete-user": "Delete User",
|
"sort_column_ascending": "Sort column ascending",
|
||||||
"deleted-scan": "Deleted scan",
|
"sort_column_descending": "Sort column descending",
|
||||||
"dependency_name": "Name",
|
"previous": "Previous",
|
||||||
"description": "description",
|
"next": "Next",
|
||||||
"description-optional": "Description (optional)",
|
"page": "Page",
|
||||||
"deselect-all": "deselect all",
|
"showing": "Showing",
|
||||||
"details": "Details",
|
"records": "Records",
|
||||||
"disabled": "disabled",
|
"of": "of",
|
||||||
"distance": "Distance",
|
"to": "to",
|
||||||
"distance-donation": "distance donation",
|
"loading": "Loading...",
|
||||||
"distance-in-km": "Distance in km",
|
"no_matching_records_found": "No matching records found",
|
||||||
"distance-track": "Distance (+Track)",
|
"an_error_happened_while_fetching_the_data": "An error happened while fetching the data"
|
||||||
"do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?",
|
},
|
||||||
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
|
"delete": "Delete",
|
||||||
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
|
"delete-contact": "Delete Contact",
|
||||||
"do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations",
|
"delete-donation": "Delete Donation",
|
||||||
"documentation": "Documentation",
|
"delete-donor": "Delete donor",
|
||||||
"donation-amount": "Donation amount",
|
"delete-group": "Delete Group",
|
||||||
"donation-amount-must-be-greater-that-0-00eur": "Donation amount must be greater that 0.00€",
|
"delete-organization": "Delete Organization",
|
||||||
"donations": "Donations",
|
"delete-profile": "Delete Profile",
|
||||||
"donor": "Donor",
|
"delete-runner": "Delete Runner",
|
||||||
"donor-added": "Donor added",
|
"delete-scan": "Delete scan",
|
||||||
"donor-deleted": "donor deleted",
|
"delete-station": "Delete station",
|
||||||
"donor-has-no-associated-donations": "Donor has no associated donations.",
|
"delete-team": "Delete Team",
|
||||||
"donor-is-being-added": "Donor is being added...",
|
"delete-user": "Delete User",
|
||||||
"donor-is-being-updated": "Donor is being updated",
|
"deleted-scan": "Deleted scan",
|
||||||
"donors": "Donors",
|
"dependency_name": "Name",
|
||||||
"donors-are-being-loaded": "donors are being loaded",
|
"description": "description",
|
||||||
"dont-have-your-email-connected": "Don't have your email connected?",
|
"description-optional": "Description (optional)",
|
||||||
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
|
"deselect-all": "deselect all",
|
||||||
"e-mail-adress": "E-Mail Adress",
|
"details": "Details",
|
||||||
"edit": "Edit",
|
"disabled": "disabled",
|
||||||
"edit-permissions": "edit permissions",
|
"distance": "Distance",
|
||||||
"email_address_or_username": "Email / username",
|
"distance-donation": "distance donation",
|
||||||
"enabled": "enabled",
|
"distance-in-km": "Distance in km",
|
||||||
"enabled_large": "Enabled",
|
"distance-track": "Distance (+Track)",
|
||||||
"english": "English",
|
"do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?",
|
||||||
"error-during-import": "Error during import",
|
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
|
||||||
"error-whyile-copying-to-clipboard": "Error while copying to clipboard",
|
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
|
||||||
"error_on_login": "Error on login",
|
"do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations",
|
||||||
"erteilte": "Directly granted",
|
"documentation": "Documentation",
|
||||||
"everything-concerning-your-profile": "Everything concerning your profile",
|
"donation-amount": "Donation amount",
|
||||||
"everything-is-more-fun-together": "everything is more fun together 🏃♂️🏃♀️🏃♂️",
|
"donation-amount-must-be-greater-that-0-00eur": "Donation amount must be greater that 0.00€",
|
||||||
"faq": "FAQ",
|
"donation-deleted": "Donation deleted",
|
||||||
"filter-by-organization-team": "Filter by Organization/ Team",
|
"donation-updated": "Donation updated",
|
||||||
"first-name": "First name",
|
"donation_added": "Donation_added",
|
||||||
"first-name-is-required": "First Name is required",
|
"donations": "Donations",
|
||||||
"first-scan-of-the-day": "First scan of the day.",
|
"donor": "Donor",
|
||||||
"fixed-donation": "fixed donation",
|
"donor-added": "Donor added",
|
||||||
"forgot_password": "Forgot your password?",
|
"donor-deleted": "donor deleted",
|
||||||
"geerbte": "inherited",
|
"donor-has-no-associated-donations": "Donor has no associated donations.",
|
||||||
"general-stats": "General Stats",
|
"donor-is-being-added": "Donor is being added...",
|
||||||
"general_promise_error": "😢 Error",
|
"donor-is-being-updated": "Donor is being updated",
|
||||||
"generate-sponsoring-contract": "generate sponsoring contract",
|
"donors": "Donors",
|
||||||
"generate-sponsoring-contracts": "generate sponsoring contracts",
|
"donors-are-being-loaded": "donors are being loaded",
|
||||||
"generating-pdf": "generating PDF...",
|
"dont-have-your-email-connected": "Don't have your email connected?",
|
||||||
"generating-pdfs": "generating PDFs...",
|
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
|
||||||
"generic-ui-logic-error": "Something went wrong in the UI logic",
|
"e-mail-adress": "E-Mail Adress",
|
||||||
"german": "German",
|
"edit": "Edit",
|
||||||
"go-to-login": "Go To Login",
|
"edit-a-card": "Edit a card",
|
||||||
"goback": "Go Home",
|
"edit-permissions": "edit permissions",
|
||||||
"granted": "granted",
|
"email_address_or_username": "Email / username",
|
||||||
"group": "Group",
|
"enabled": "enabled",
|
||||||
"group-added": "Group added",
|
"enabled_large": "Enabled",
|
||||||
"group-is-being-added": "Group is being added...",
|
"english": "English",
|
||||||
"group-name-is-required": "Group name is required",
|
"enter-payment": "Enter payment",
|
||||||
"group-updated": "group updated",
|
"error-during-import": "Error during import",
|
||||||
"groups": "Groups",
|
"error-whyile-copying-to-clipboard": "Error while copying to clipboard",
|
||||||
"groups-are-being-loaded": "Groups are being loaded",
|
"error_on_login": "Error on login",
|
||||||
"home": "Home",
|
"erteilte": "Directly granted",
|
||||||
"icon-image-credits": "We also want to thank these projects for illustrations and icons:",
|
"everything-concerning-your-profile": "Everything concerning your profile",
|
||||||
"import-finished": "Import finished",
|
"everything-is-more-fun-together": "everything is more fun together 🏃♂️🏃♀️🏃♂️",
|
||||||
"import-runners": "Import runners",
|
"faq": "FAQ",
|
||||||
"import__target-organization": "Target Organization",
|
"filename_sponsoringquittungsliste": "DonorReceiptList",
|
||||||
"imprint": "Imprint",
|
"filter-by-organization-team": "Filter by Organization/ Team",
|
||||||
"imprint-loading": "Imprint loading...",
|
"first-name": "First name",
|
||||||
"inactive": "Inactive",
|
"first-name-is-required": "First Name is required",
|
||||||
"installed-version": "Installed version",
|
"first-scan-of-the-day": "First scan of the day.",
|
||||||
"internal-error": "Internal Error",
|
"fixed-donation": "fixed donation",
|
||||||
"invalid": "Invalid",
|
"forgot_password": "Forgot your password?",
|
||||||
"invalid-mail-reset": "the provided email is invalid",
|
"geerbte": "inherited",
|
||||||
"laeufer-hinzufuegen": "Add runner",
|
"general-stats": "General Stats",
|
||||||
"laeufer-importieren": "Läufer importieren",
|
"general_promise_error": "😢 Error",
|
||||||
"laptime": "Laptime",
|
"generate-runner-certificate": "Generate runner certificate",
|
||||||
"last-name": "Last name",
|
"generate-runner-certificates": "Generate runner certificates",
|
||||||
"last-name-is-required": "Last Name is required",
|
"generate-runnercards": "Generate Runnercards",
|
||||||
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
|
"generate-sponsoring-contract": "generate sponsoring contract",
|
||||||
"license": "License",
|
"generate-sponsoring-contracts": "generate sponsoring contracts",
|
||||||
"licenses-are-being-loaded": "Licenses are being loaded...",
|
"generating-pdf": "generating PDF...",
|
||||||
"loading-contact-details": "Loading contact details...",
|
"generating-pdfs": "generating PDFs...",
|
||||||
"loading-donation-details": "Loading donation details",
|
"generic-ui-logic-error": "Something went wrong in the UI logic",
|
||||||
"loading-donor-details": "Loading donor details",
|
"german": "German",
|
||||||
"loading-group-detail": "Loading group detail...",
|
"go-to-login": "Go To Login",
|
||||||
"loading-profile-data": "Loading profile data",
|
"goback": "Go Home",
|
||||||
"loading-runners": "loading runners...",
|
"granted": "granted",
|
||||||
"loading-station-details": "Loading station details",
|
"group": "Group",
|
||||||
"log_in": "Log in",
|
"group-added": "Group added",
|
||||||
"log_in_to_your_account": "Log in to your account",
|
"group-is-being-added": "Group is being added...",
|
||||||
"login_is_checked": "Login is being checked...",
|
"group-name-is-required": "Group name is required",
|
||||||
"logout": "Logout",
|
"group-updated": "group updated",
|
||||||
"mail-validation-in-progress": "mail validation in progress...",
|
"groups": "Groups",
|
||||||
"manage-admin-users": "manage admin users",
|
"groups-are-being-loaded": "Groups are being loaded",
|
||||||
"middle-name": "Middle name",
|
"home": "Home",
|
||||||
"minimum-lap-time-in-s": "minimum lap time in s",
|
"icon-image-credits": "We also want to thank these projects for illustrations and icons:",
|
||||||
"minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0",
|
"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.",
|
||||||
"name": "Name",
|
"import-finished": "Import finished",
|
||||||
"name-is-required": "Name is required",
|
"import-runners": "Import runners",
|
||||||
"new-password": "New password",
|
"import__target-organization": "Target Organization",
|
||||||
"no-contact-found": "No contacts found",
|
"imprint": "Imprint",
|
||||||
"no-contact-selected": "No contact selected",
|
"imprint-loading": "Imprint loading...",
|
||||||
"no-contact-specified": "no contact specified",
|
"inactive": "Inactive",
|
||||||
"no-donors-found": "No donors found",
|
"installed-version": "Installed version",
|
||||||
"no-license-text-could-be-found": "No license text could be found 😢",
|
"internal-error": "Internal Error",
|
||||||
"no-organization-or-team-found": "No organization or team found",
|
"invalid": "Invalid",
|
||||||
"no-organization-specified": "no organization specified",
|
"invalid-mail-reset": "the provided email is invalid",
|
||||||
"no-organizations-found": "No organizations found",
|
"just-enter-how-many-you-want-and-the-system-will-create-them": "Just enter how many you want and the system will create them",
|
||||||
"no-runners-found": "No runners found",
|
"laeufer-hinzufuegen": "Add runner",
|
||||||
"no-tracks-added-yet": "there are no tracks added yet.",
|
"laeufer-importieren": "Läufer importieren",
|
||||||
"organization": "Organization",
|
"laptime": "Laptime",
|
||||||
"organization-added": "Organization added",
|
"last-name": "Last name",
|
||||||
"organization-deleted": "Organization deleted",
|
"last-name-is-required": "Last Name is required",
|
||||||
"organization-detail-is-being-loaded": "organization detail is being loaded...",
|
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
|
||||||
"organization-is-being-added": "Organization is being added...",
|
"license": "License",
|
||||||
"organization-name-is-required": "Organization name is required",
|
"licenses-are-being-loaded": "Licenses are being loaded...",
|
||||||
"organizations": "Organizations",
|
"loading-cards": "Loading cards",
|
||||||
"organizations-are-being-loaded": "organizations are being loaded...",
|
"loading-contact-details": "Loading contact details...",
|
||||||
"orgs": "Organizations",
|
"loading-donation-details": "Loading donation details",
|
||||||
"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!",
|
"loading-donor-details": "Loading donor details",
|
||||||
"password": "Password",
|
"loading-group-detail": "Loading group detail...",
|
||||||
"password-changed": "Password changed!",
|
"loading-profile-data": "Loading profile data",
|
||||||
"password-is-required": "Password is required",
|
"loading-runners": "loading runners...",
|
||||||
"password-reset-failed": "Password reset failed!",
|
"loading-station-details": "Loading station details",
|
||||||
"password-reset-in-progress": "Password Reset in Progress...",
|
"log_in": "Log in",
|
||||||
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
|
"log_in_to_your_account": "Log in to your account",
|
||||||
"password-reset-successful": "Password Reset successful!",
|
"login_is_checked": "Login is being checked...",
|
||||||
"passwords-dont-match": "Passwords don't match",
|
"logout": "Logout",
|
||||||
"pdf-generation-failed": "PDF generation failed!",
|
"mail-validation-in-progress": "mail validation in progress...",
|
||||||
"pdf-successfully-generated": "PDF successfully generated!",
|
"manage-admin-users": "manage admin users",
|
||||||
"pdfs-successfully-generated": "PDFs successfully generated!",
|
"middle-name": "Middle name",
|
||||||
"per-kilometer": "per Kilometer",
|
"minimum-lap-time-in-s": "minimum lap time in s",
|
||||||
"permissions": "Permissions",
|
"minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0",
|
||||||
"permissions-updated": "Permissions updated!",
|
"must-be-at-least-10-characters-long": "Must be at least 10 characters long!",
|
||||||
"phone": "Phone",
|
"must-contain-a-lowercase-letter": "Must contain a lowercase letter!",
|
||||||
"please-copy-the-token-and-store-it-somewhere-save": "Please copy the token and store it somewhere safe.",
|
"must-contain-a-number": "Must contain a number!",
|
||||||
"please-provide-a-password": "Please provide a password...",
|
"must-contain-a-uppercase-letter": "Must contain a uppercase letter!",
|
||||||
"please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor",
|
"name": "Name",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation",
|
"name-is-required": "Name is required",
|
||||||
"please-provide-the-nessecary-information-to-create-a-new-scan": "Please provide the nessecary information to create a new scan.",
|
"new-password": "New password",
|
||||||
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
|
"no-contact-found": "No contacts found",
|
||||||
"please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.",
|
"no-contact-selected": "No contact selected",
|
||||||
"please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.",
|
"no-contact-specified": "no contact specified",
|
||||||
"please-provide-the-required-information-to-add-a-new-organization": "Please provide the required information to add a new organization.",
|
"no-donors-found": "No donors found",
|
||||||
"please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.",
|
"no-license-text-could-be-found": "No license text could be found 😢",
|
||||||
"please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.",
|
"no-organization-or-team-found": "No organization or team found",
|
||||||
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
|
"no-organization-specified": "no organization specified",
|
||||||
"please-provide-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.",
|
"no-organizations-found": "No organizations found",
|
||||||
"please-provide-the-required-information-to-create-a-new-scanstation": "Please provide the required information to create a new scanstation",
|
"no-runners-found": "No runners found",
|
||||||
"please-request-a-new-reset-mail": "Please request a new reset mail...",
|
"no-tracks-added-yet": "there are no tracks added yet.",
|
||||||
"privacy": "Privacy",
|
"non-blanko": "Non/Blanko",
|
||||||
"privacy-loading": "Privacy loading...",
|
"open": "OPEN",
|
||||||
"profile": "Profile",
|
"organization": "Organization",
|
||||||
"profile-picture": "Profile Picture",
|
"organization-added": "Organization added",
|
||||||
"profile-updated": "Profile updated!",
|
"organization-deleted": "Organization deleted",
|
||||||
"read-license": "Read License",
|
"organization-detail-is-being-loaded": "organization detail is being loaded...",
|
||||||
"receipt-needed": "Receipt needed",
|
"organization-is-being-added": "Organization is being added...",
|
||||||
"repo_link": "Link",
|
"organization-name-is-required": "Organization name is required",
|
||||||
"request-a-new-reset-mail": "Request a new reset mail",
|
"organizations": "Organizations",
|
||||||
"reset-my-password": "Reset my password",
|
"organizations-are-being-loaded": "organizations are being loaded...",
|
||||||
"reset-password": "Reset your password",
|
"orgs": "Organizations",
|
||||||
"runner": "Runner",
|
"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!",
|
||||||
"runner-added": "Runner added",
|
"paid": "PAID",
|
||||||
"runner-import": "Runner Import",
|
"paid-amount": "Paid amount",
|
||||||
"runner-is-being-added": "Runner is being added...",
|
"password": "Password",
|
||||||
"runner-updated": "Runner updated!",
|
"password-changed": "Password changed!",
|
||||||
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
|
"password-is-required": "Password is required",
|
||||||
"runners": "Runners",
|
"password-reset-failed": "Password reset failed!",
|
||||||
"runners-are-being-imported": "Runners are being imported...",
|
"password-reset-in-progress": "Password Reset in Progress...",
|
||||||
"runners-are-being-loaded": "runners are being loaded...",
|
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
|
||||||
"save": "Save",
|
"password-reset-successful": "Password Reset successful!",
|
||||||
"save-changes": "Save Changes",
|
"passwords-dont-match": "Passwords don't match!",
|
||||||
"scan-added": "Scan added",
|
"payment-amount-must-be-greater-than-0-00eur": "Payment amount must be greater than 0.00€!",
|
||||||
"scan-is-being-updated": "Scan is being updated",
|
"pdf-generation-failed": "PDF generation failed!",
|
||||||
"scan-with-fixed-distance": "Scan with fixed distance",
|
"pdf-successfully-generated": "PDF successfully generated!",
|
||||||
"scans": "Scans",
|
"pdfs-successfully-generated": "PDFs successfully generated!",
|
||||||
"scans-are-being-loaded": "Scans are being loaded",
|
"per-kilometer": "per Kilometer",
|
||||||
"scanstation": "Scanstation",
|
"permissions": "Permissions",
|
||||||
"scanstation-added": "Scanstation added",
|
"permissions-updated": "Permissions updated!",
|
||||||
"scanstation-is-being-added": "Adding scanstation...",
|
"phone": "Phone",
|
||||||
"scanstations": "Scanstations",
|
"please-copy-the-token-and-store-it-somewhere-save": "Please copy the token and store it somewhere safe.",
|
||||||
"scanstations-are-being-loaded": "Loading scanstations...",
|
"please-provide-a-password": "Please provide a password...",
|
||||||
"search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)",
|
"please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor",
|
||||||
"search-for-an-organization-or-team-by-name-or-id": "Search for an organization or team (by name or id)",
|
"please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation",
|
||||||
"search-for-donor-name-or-id": "Search for donor (by name or id)",
|
"please-provide-the-nessecary-information-to-create-a-new-scan": "Please provide the nessecary information to create a new scan.",
|
||||||
"search-for-permission": "Search for permission",
|
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
|
||||||
"search-for-runner-by-name-or-id": "Search for runner (by name or id)",
|
"please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.",
|
||||||
"select-all": "select all",
|
"please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.",
|
||||||
"select-language": "Select language",
|
"please-provide-the-required-information-to-add-a-new-organization": "Please provide the required information to add a new organization.",
|
||||||
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
|
"please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.",
|
||||||
"set-the-user-active-inactive": "set the user active/ inactive",
|
"please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.",
|
||||||
"settings": "Settings",
|
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
|
||||||
"settings-for-your-profile": "Settings for your profile",
|
"please-provide-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.",
|
||||||
"something-about-the-group": "Something about the group...",
|
"please-provide-the-required-information-to-create-a-new-scanstation": "Please provide the required information to create a new scanstation",
|
||||||
"stats-are-being-loaded": "stats are being loaded...",
|
"please-request-a-new-reset-mail": "Please request a new reset mail...",
|
||||||
"status": "Status",
|
"please-wait-a-moment-your-login-is-still-being-processed": "Please wait a moment, your login is still being processed",
|
||||||
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
|
"privacy": "Privacy",
|
||||||
"successful-password-reset": "Successful password reset!",
|
"privacy-loading": "Privacy loading...",
|
||||||
"team": "Team",
|
"profile": "Profile",
|
||||||
"team-detail-is-being-loaded": "team detail is being loaded...",
|
"profile-deleted": "Profile deleted!",
|
||||||
"team-name": "Team name",
|
"profile-picture": "Profile Picture",
|
||||||
"team-name-is-required": "team name is required",
|
"profile-updated": "Profile updated!",
|
||||||
"teams": "Teams",
|
"read-license": "Read License",
|
||||||
"teams-are-being-loaded": "teams are being loaded...",
|
"receipt-needed": "Receipt needed",
|
||||||
"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...",
|
"repo_link": "Link",
|
||||||
"the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m",
|
"request-a-new-reset-mail": "Request a new reset mail",
|
||||||
"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!",
|
"reset-my-password": "Reset my password",
|
||||||
"there-are-no-contacts-added-yet": "There are no contacts added yet.",
|
"reset-password": "Reset your password",
|
||||||
"there-are-no-donations-yet": "There are no donations yet",
|
"runner": "Runner",
|
||||||
"there-are-no-donors-yet": "There are no donors yet",
|
"runner-added": "Runner added",
|
||||||
"there-are-no-groups-yet": "There are no groups yet",
|
"runner-import": "Runner Import",
|
||||||
"there-are-no-organizations-added-yet": "There are no organizations added yet.",
|
"runner-is-being-added": "Runner is being added...",
|
||||||
"there-are-no-runners-added-yet": "There are no runners added yet.",
|
"runner-updated": "Runner updated!",
|
||||||
"there-are-no-scans-yet": "There are no scans yet",
|
"runnercards": "Runnercards",
|
||||||
"there-are-no-teams-added-yet": "There are no teams added yet.",
|
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
|
||||||
"there-are-no-users-added-yet": "There are no users added yet.",
|
"runners": "Runners",
|
||||||
"this-might-take-a-moment": "This might take a moment 👀",
|
"runners-are-being-imported": "Runners are being imported...",
|
||||||
"this-scanstation-is": "This scanstation is",
|
"runners-are-being-loaded": "runners are being loaded...",
|
||||||
"token": "Token",
|
"save": "Save",
|
||||||
"total-distance": "total distance",
|
"save-changes": "Save Changes",
|
||||||
"total-donation-amount": "total donation amount",
|
"scan-added": "Scan added",
|
||||||
"total-donations": "total donations",
|
"scan-is-being-updated": "Scan is being updated",
|
||||||
"total-scans": "total scans",
|
"scan-with-fixed-distance": "Scan with fixed distance",
|
||||||
"track": "Track",
|
"scans": "Scans",
|
||||||
"track-added": "Track added",
|
"scans-are-being-loaded": "Scans are being loaded",
|
||||||
"track-data-is-being-loaded": "Track data is being loaded",
|
"scanstation": "Scanstation",
|
||||||
"track-is-being-added": "Track is being added...",
|
"scanstation-added": "Scanstation added",
|
||||||
"track-length-in-m": "Track Length in m",
|
"scanstation-is-being-added": "Adding scanstation...",
|
||||||
"track-length-must-be-greater-than-0": "Track length must be greater than 0",
|
"scanstations": "Scanstations",
|
||||||
"track-name": "Track name",
|
"scanstations-are-being-loaded": "Loading scanstations...",
|
||||||
"track-name-must-not-be-empty": "Track name must not be empty",
|
"search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)",
|
||||||
"tracks": "Tracks",
|
"search-for-an-organization-or-team-by-name-or-id": "Search for an organization or team (by name or id)",
|
||||||
"update-password": "Update password",
|
"search-for-donor-name-or-id": "Search for donor (by name or id)",
|
||||||
"updated-contact": "Updated contact!",
|
"search-for-permission": "Search for permission",
|
||||||
"updated-donor": "updated donor",
|
"search-for-runner-by-name-or-id": "Search for runner (by name or id)",
|
||||||
"updated-organization": "updated organization",
|
"select-all": "select all",
|
||||||
"updated-scan": "updated scan",
|
"select-language": "Select language",
|
||||||
"updateing-group": "updateing group...",
|
"selfservice-registration": "Selfservice registration",
|
||||||
"updating-organization": "updating organization",
|
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
|
||||||
"updating-permissions": "updating permissions...",
|
"set-the-user-active-inactive": "set the user active/ inactive",
|
||||||
"updating-runner": "Updating runner...",
|
"settings": "Settings",
|
||||||
"updating-user": "updating user...",
|
"settings-for-your-profile": "Settings for your profile",
|
||||||
"updating-your-profile": "Updating your profile...",
|
"something-about-the-group": "Something about the group...",
|
||||||
"user-added": "User added",
|
"sponsoring-quittungs-liste_herunterladen": "Download donor receipt list",
|
||||||
"user-groups": "User Groups",
|
"sponsorings": "Sponsorings",
|
||||||
"user-is-being-added": "User is being added...",
|
"stats-are-being-loaded": "stats are being loaded...",
|
||||||
"user-updated": "User updated",
|
"status": "Status",
|
||||||
"username": "Username",
|
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
|
||||||
"users": "Users",
|
"successful-password-reset": "Successful password reset!",
|
||||||
"valid": "Valid",
|
"team": "Team",
|
||||||
"valid-city-is-required": "Valid city is required",
|
"team-added": "Team added",
|
||||||
"valid-email-is-required": "valid email is required",
|
"team-deleted": "Team deleted",
|
||||||
"valid-international-phone-number-is-required": "valid international phone number is required...",
|
"team-detail-is-being-loaded": "team detail is being loaded...",
|
||||||
"valid-zipcode-postal-code-is-required": "Valid zipcode/ postal code is required",
|
"team-is-being-added": "Team is being added...",
|
||||||
"verfuegbare": "availdable",
|
"team-name": "Team name",
|
||||||
"welcome_wavinghand": "Welcome 👋",
|
"team-name-is-required": "team name is required",
|
||||||
"yes-i-copied-the-token": "Yes, I copied the token",
|
"teams": "Teams",
|
||||||
"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!",
|
"teams-are-being-loaded": "teams are being loaded...",
|
||||||
"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! 🎉",
|
"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...",
|
||||||
"you-dont-have-any-scanstations-yet": "You don't have any scanstations yet",
|
"the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m",
|
||||||
"you-have-to-provide-an-organization": "You have to provide an organization",
|
"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!",
|
||||||
"zip-postal-code": "ZIP/ postal code"
|
"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-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",
|
||||||
|
"statsclients": "Statsclients (aka Beamershow)",
|
||||||
|
"create-a-new-statsclient": "Create a new statsclient",
|
||||||
|
"statsclients-are-being-loaded": "Loading statsclients",
|
||||||
|
"prefix": "Prefix",
|
||||||
|
"key": "Key",
|
||||||
|
"statsclient-deleted": "Deleted statsclient",
|
||||||
|
"cancel-keep-statsclient": "Cancel and keep statsclient",
|
||||||
|
"confirm-delete-statsclient": "Confirm, delete statsclient",
|
||||||
|
"statsclient-is-being-added": "Statsclient is being added...",
|
||||||
|
"please-provide-the-required-information-to-create-a-new-statsclient": "Please provide the required information to create a new statsclient",
|
||||||
|
"you-dont-have-any-scanclients-yet": "You don't have any statsclients yet",
|
||||||
|
"add-the-first-statsclient": "Add your first statsclient.",
|
||||||
|
"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!",
|
||||||
|
"delete-statsclient": "Delete statsclient"
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import './style.css';
|
||||||
|
import "toastify-js/src/toastify.css";
|
||||||
|
import "gridjs/dist/theme/mermaid.css";
|
||||||
|
import App from './App.svelte';
|
||||||
|
|
||||||
|
const app = new App({
|
||||||
|
target: document.body
|
||||||
|
});
|
||||||
|
export default app;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
export const register = () => {
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
navigator.serviceWorker.register('/sw.js').then(
|
|
||||||
(registration) => {
|
|
||||||
// console.log(`sw successful with scope: ${registration.scope}`);
|
|
||||||
},
|
|
||||||
(err) => {
|
|
||||||
// console.log(`sw failed: ${err}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
+10
-9
@@ -1,14 +1,15 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
purge: {
|
mode: 'jit',
|
||||||
content: [ './src/**/*.svelte' ]
|
purge: [ './src/**/*.svelte' ],
|
||||||
},
|
|
||||||
// darkMode: 'media',
|
|
||||||
variants: {},
|
|
||||||
plugins: [],
|
|
||||||
theme: {
|
theme: {
|
||||||
container: {
|
extend: {
|
||||||
center: true,
|
colors: {
|
||||||
padding: '1.5rem'
|
reepolee: {
|
||||||
|
500: '#b40000',
|
||||||
|
600: '#9c0000',
|
||||||
|
700: '#750000'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
const fs = require('fs');
|
|
||||||
let content_svelteconfig = fs.readFileSync('./s-config.template.js', { encoding: 'utf8' });
|
|
||||||
let content_html = fs.readFileSync('./index.template.html', { encoding: 'utf8' });
|
|
||||||
if (process.env.NODE_ENV_ODIT == 'development_fast') {
|
|
||||||
content_html = content_html.replace(
|
|
||||||
'__TAILWIND_INSERT__',
|
|
||||||
'<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss@2.0.2/dist/tailwind.min.css">'
|
|
||||||
);
|
|
||||||
content_svelteconfig = content_svelteconfig.replace('__insert__', '{postcss:{}}');
|
|
||||||
} else {
|
|
||||||
content_html = content_html.replace('__TAILWIND_INSERT__', '');
|
|
||||||
content_svelteconfig = content_svelteconfig.replace(
|
|
||||||
'__insert__',
|
|
||||||
"{postcss:{plugins:[require('tailwindcss'),require('autoprefixer')]}}"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
fs.writeFileSync('./public/index.html', content_html);
|
|
||||||
fs.writeFileSync('./svelte.config.js', content_svelteconfig);
|
|
||||||
console.info('dev setup script done');
|
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const package = JSON.parse(fs.readFileSync(`./package.json`, { encoding: 'utf-8' }));
|
const package = JSON.parse(fs.readFileSync(`./package.json`, { encoding: 'utf-8' }));
|
||||||
const original = fs.readFileSync(`./index.template.html`, { encoding: 'utf-8' });
|
const original = fs.readFileSync(`./index.html`, { encoding: 'utf-8' });
|
||||||
let out = original.replace(/RELEASE_INFO-(\S)+-RELEASE_INFO/gi, 'RELEASE_INFO-' + package.version + '-RELEASE_INFO');
|
let out = original.replace(/RELEASE_INFO-(\S)+-RELEASE_INFO/gi, 'RELEASE_INFO-' + package.version + '-RELEASE_INFO');
|
||||||
fs.writeFileSync(`./index.template.html`, out);
|
fs.writeFileSync(`./index.html`, out);
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import svelte from '@sveltejs/vite-plugin-svelte';
|
||||||
|
import { minify } from 'html-minifier';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
//
|
||||||
|
const indexReplace = () => {
|
||||||
|
return {
|
||||||
|
name: 'html-transform',
|
||||||
|
transformIndexHtml(html) {
|
||||||
|
return minify(html, {
|
||||||
|
collapseWhitespace: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defineConfig(({ command, mode }) => {
|
||||||
|
const isProduction = mode === 'production';
|
||||||
|
return {
|
||||||
|
// base: './',
|
||||||
|
build: {
|
||||||
|
polyfillDynamicImport: false,
|
||||||
|
cssCodeSplit: false,
|
||||||
|
minify: isProduction
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
svelte({
|
||||||
|
//@ts-ignore
|
||||||
|
hot: !isProduction,
|
||||||
|
emitCss: true,
|
||||||
|
extensions: [ '.md', '.svx', '.svelte' ],
|
||||||
|
preprocess: [
|
||||||
|
//
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
indexReplace()
|
||||||
|
]
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
globDirectory: 'public',
|
|
||||||
globPatterns: [ '**/*.{js,ico,png,svg,html,webmanifest,txt,json}' ],
|
|
||||||
globIgnores: [ 'env.js', 'env.sample.js' ],
|
|
||||||
swDest: 'public/sw.js',
|
|
||||||
cleanupOutdatedCaches: true,
|
|
||||||
mode: 'production',
|
|
||||||
sourcemap: false
|
|
||||||
};
|
|
||||||
Reference in new issue
Block a user