diff --git a/CHANGELOG.md b/CHANGELOG.md index 2686faf4..0bd10a4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,143 @@ All notable changes to this project will be documented in this file. Dates are displayed in UTC. +#### [0.11.0](https://git.odit.services/lfk/frontend/compare/0.10.0...0.11.0) + +- Merge pull request 'Generate and print bulk blank cards feature/116-download_blanc_cards' (#117) from feature/116-download_blanc_cards into dev [`25d8b86`](https://git.odit.services/lfk/frontend/commit/25d8b86efd89c442d1bf308a8743134820acfd1f) +- Added button (including translations [`0614c76`](https://git.odit.services/lfk/frontend/commit/0614c76e924b18b512bab59933a26fec07cf483d) +- Added button (including translations [`97e338f`](https://git.odit.services/lfk/frontend/commit/97e338f9d4f388596d550990457254c7fa1a3492) +- Sorted translations [`89bb9c2`](https://git.odit.services/lfk/frontend/commit/89bb9c215e356e0940678f5cabd9e38bc203040e) +- Added function for generating cards with pdf [`c8d6390`](https://git.odit.services/lfk/frontend/commit/c8d639024a5f2f72d6e30d2ce990b08bd71a5471) +- Fixed button styling [`08cb079`](https://git.odit.services/lfk/frontend/commit/08cb079e9798392e26515d559af2637e74deea97) +- Now returning cards on creation with pdf [`1d999d4`](https://git.odit.services/lfk/frontend/commit/1d999d4910acb5efa21b3f9922cdb359babff404) +- Added comment [`636f018`](https://git.odit.services/lfk/frontend/commit/636f018daa33b99468a257bfc33477e1e644d081) +- Bumped lfk client js version [`2d18686`](https://git.odit.services/lfk/frontend/commit/2d18686ce782a434ca7bd34c07c36a35b9497273) +- Bumped lfk-client-js [`7dfaa75`](https://git.odit.services/lfk/frontend/commit/7dfaa7579a22b13194fcdd1c02b4437958261472) + +#### [0.10.0](https://git.odit.services/lfk/frontend/compare/0.9.1...0.10.0) + +> 26 March 2021 + +- Added translations [`79c447b`](https://git.odit.services/lfk/frontend/commit/79c447b4c65e55ebb5af71fb0b09174c36e2cecf) +- Sorted translations 🌍 [`5bd3a46`](https://git.odit.services/lfk/frontend/commit/5bd3a463f00abaf2c98ab554f88e5542d01f364a) +- Reset can now only be triggered if pw is strong enoug [`75d8f73`](https://git.odit.services/lfk/frontend/commit/75d8f7331b6ae78f3979bb62148188a16f83cb8d) +- Module now exports functions that check if a password is strong enough and equal to a potential confirmation field [`b2509e9`](https://git.odit.services/lfk/frontend/commit/b2509e9e53ab6b51dfd55e26712e8928160cd64b) +- 🚀RELEASE v0.10.0 [`f7fc196`](https://git.odit.services/lfk/frontend/commit/f7fc1967a50f302af1d8b668628be2f4ab2975a3) +- Added more cirteria to the password strength component [`5fa9939`](https://git.odit.services/lfk/frontend/commit/5fa9939696a35d60d762feb0cebef61d31869218) +- Now using pw strength component [`6aaf838`](https://git.odit.services/lfk/frontend/commit/6aaf8384512185a3a319ce6b3e2505e910468e64) +- Added a password strength verification [`ad3bd31`](https://git.odit.services/lfk/frontend/commit/ad3bd312e9a5785f81029ea2b7e302ea1addd988) +- Implemented a custom password strength component [`4956bb0`](https://git.odit.services/lfk/frontend/commit/4956bb0e9c3c1d22d60e849aea5664e35330f897) +- User creation can now only be triggered if pw is strong enoug [`540304f`](https://git.odit.services/lfk/frontend/commit/540304f947f60a7072c592ca8088996ce7e95cb4) +- Now using pw strength component for user creation [`7862f44`](https://git.odit.services/lfk/frontend/commit/7862f446532903f1a2eac7b21d5c80c3245785e5) +- Added missing exports [`962dd0c`](https://git.odit.services/lfk/frontend/commit/962dd0c1bbc0df7f20bcec5b4247188c8935c87e) +- new license file version [CI SKIP] [`aedb8a7`](https://git.odit.services/lfk/frontend/commit/aedb8a765ba053545adbba9eb014b3bb0e5aac8c) +- Bumped lfk-client version 🔝 [`cf58bd1`](https://git.odit.services/lfk/frontend/commit/cf58bd15c3541c417ab2be83d96135e931a2b6f6) +- new license file version [CI SKIP] [`34f4f68`](https://git.odit.services/lfk/frontend/commit/34f4f68524918fd3d1963966a1e259d5b60efaca) +- Merge pull request 'Implemented password strength test feature/106-password_strength' (#115) from feature/106-password_strength into dev [`09b8144`](https://git.odit.services/lfk/frontend/commit/09b81440804cf98303fcb723a9717d6d0f432da8) +- Formatting🛠 [`4167819`](https://git.odit.services/lfk/frontend/commit/4167819e7a864d3b1dd95ba48ab1525a454f7f30) +- Now using pw strength component for reset [`5d5f7c7`](https://git.odit.services/lfk/frontend/commit/5d5f7c7f5c6a69146f41996f4facfeff95791be0) + +#### [0.9.1](https://git.odit.services/lfk/frontend/compare/0.9.0...0.9.1) + +> 26 March 2021 + +- 🚀RELEASE v0.9.1 [`2ca63fd`](https://git.odit.services/lfk/frontend/commit/2ca63fd1f675f0da2b18ba43095074dd4823991d) +- Merge pull request 'Org selfservice Link feature/112-org_registration_links' (#114) from feature/112-org_registration_links into dev [`a5d25e7`](https://git.odit.services/lfk/frontend/commit/a5d25e7d92c7c37e90dbb4ba74b787873f920c6b) +- Added checkbox to enable registration [`f9fe793`](https://git.odit.services/lfk/frontend/commit/f9fe79357317653b46c09eb95b0db13845cddcf9) +- Sorted translations [`c074c12`](https://git.odit.services/lfk/frontend/commit/c074c12be75f285612f7a732c106404d9fb4538a) +- You can now copy the selfservice links to your clipboard [`fcd55f8`](https://git.odit.services/lfk/frontend/commit/fcd55f89d72e6ceb9bb2bdd194cc3420145d6d0d) +- Formatting [`f185d55`](https://git.odit.services/lfk/frontend/commit/f185d559c0d6476f2f2b9ea74aaad3297411801d) +- Copy now 100% worX [`a3921b4`](https://git.odit.services/lfk/frontend/commit/a3921b45c70b410293db593a75d2fdd34c131733) +- Fixed changes in wrong file [`73d95bc`](https://git.odit.services/lfk/frontend/commit/73d95bc0042f8f586ba2f2345342e25da1d280c2) +- Added check if key exists [`c2d29ff`](https://git.odit.services/lfk/frontend/commit/c2d29ff233f6b3e9dd2555b7e0b845592da2ba35) +- Added check if key exists [`2316baa`](https://git.odit.services/lfk/frontend/commit/2316baa8984832382be9f3b4549ca62cf9ccb5a3) +- Added translations [`ddbc293`](https://git.odit.services/lfk/frontend/commit/ddbc293e9ca0525910bf3d995de970ee2c35c56a) +- new license file version [CI SKIP] [`ded9b58`](https://git.odit.services/lfk/frontend/commit/ded9b589fe087915176c5b54f3c55e412541bc8f) +- Merge pull request 'first merge to main 🚀' (#71) from dev into main [`9aa8e7e`](https://git.odit.services/lfk/frontend/commit/9aa8e7edffa7e51b00a5ab7a8f16828b7a469181) + +#### [0.9.0](https://git.odit.services/lfk/frontend/compare/0.8.7...0.9.0) + +> 26 March 2021 + +- 🚀RELEASE v0.9.0 [`67c3732`](https://git.odit.services/lfk/frontend/commit/67c3732fad5a7c64ae11dcbebaaa095e1a2b387c) +- Merge pull request 'Runner cards feature/94-runnercard_mgnt' (#111) from feature/94-runnercard_mgnt into dev [`2932f45`](https://git.odit.services/lfk/frontend/commit/2932f4591e62187a4903511051d110e9679c0993) +- Sorted translations 🌍 [`1665a1a`](https://git.odit.services/lfk/frontend/commit/1665a1a093862a13be78ec65dcdf64eb7d855593) +- Added translations [`6b5945a`](https://git.odit.services/lfk/frontend/commit/6b5945add86a77630c500872545bb91724b2047f) +- Sorted translations 🌍 [`d6c315a`](https://git.odit.services/lfk/frontend/commit/d6c315ab8e020bc65b967e2c3f4cd921392d66d5) +- Sorted translations [`de2fe0e`](https://git.odit.services/lfk/frontend/commit/de2fe0e9f171efb3deeea8cfe638f60e3ca90423) +- Added basic cards page [`5c5ef95`](https://git.odit.services/lfk/frontend/commit/5c5ef95d2be65c0e951dcd472113c8ce0593c9e0) +- Moved contract generation to it's own component [`0cfc87f`](https://git.odit.services/lfk/frontend/commit/0cfc87fbe6adfacab5c2fab732866aead3231fbf) +- Teams now use the new sponsoring contracts module [`014ba3b`](https://git.odit.services/lfk/frontend/commit/014ba3bf6718ff28f35c67c8f732b53aae50723c) +- Basic card generation worX 🎉🎉 [`d467475`](https://git.odit.services/lfk/frontend/commit/d467475b6d61d50bec3a043ea8792533e8593df6) +- Orgs now use the new sponsoring contracts module [`8b451b3`](https://git.odit.services/lfk/frontend/commit/8b451b3c6794e7df09898a687533ce8fadd56192) +- Added runnercard detail/edit modal [`0313f8c`](https://git.odit.services/lfk/frontend/commit/0313f8cc495088df1237d00e6b9ed1a94f019644) +- Implemented Add card modal [`535b23a`](https://git.odit.services/lfk/frontend/commit/535b23ae917de154e08962f5d486c50d6e091fe0) +- Added bulk card creation modal [`8a32569`](https://git.odit.services/lfk/frontend/commit/8a32569a3be1ad26ba163f4e2b67a368cfeeb422) +- Added basic card overview [`c6a1526`](https://git.odit.services/lfk/frontend/commit/c6a15264b3d13d516f3d97ea4b891ed1c328cead) +- Fixed org generation not hiding the generation toast [`c87321f`](https://git.odit.services/lfk/frontend/commit/c87321f804858f84fcccd85a15b9c3fb003c18be) +- Working runner runnercard generation [`c907486`](https://git.odit.services/lfk/frontend/commit/c907486c4d1c64114124deb3cd0d0cf11d38a6b1) +- Implemented bulk creation [`7ad6b73`](https://git.odit.services/lfk/frontend/commit/7ad6b73574174f24f2d6f23b3caf4823881a85e7) +- Now w/ working dialog🎉🎉🎉 [`ae96730`](https://git.odit.services/lfk/frontend/commit/ae9673070c3959ff6190a37123f3fc609b182c5a) +- Now w/working editing [`fac059f`](https://git.odit.services/lfk/frontend/commit/fac059f02cae84261443ee95448ec8db06dd755a) +- Added runnercard generation for teams [`23e0b53`](https://git.odit.services/lfk/frontend/commit/23e0b53107623c505d07a99a51ce836c9324acce) +- Added bulk creation modal to cards view [`f46ccb6`](https://git.odit.services/lfk/frontend/commit/f46ccb610e01654a4ee5e47d78ab500045dd494b) +- Added a new runenrcard logo [`acf78a8`](https://git.odit.services/lfk/frontend/commit/acf78a88221d0988f6501ae341e028a4113b578d) +- Moved modal import to overview for simplification [`1a52aaf`](https://git.odit.services/lfk/frontend/commit/1a52aaf8d1ad19b03d355aec0e1c48182db024f9) +- Added CardsEmptyState + Emtystate graphic [`2d0beaa`](https://git.odit.services/lfk/frontend/commit/2d0beaaaad4efefd036bbef09f10c8c22bdb2760) +- Added message for missing runner/blanco card) [`4715978`](https://git.odit.services/lfk/frontend/commit/4715978f810bbb283876f06d147b1ec86d373786) +- Fixed counting bug [`f5c1ec9`](https://git.odit.services/lfk/frontend/commit/f5c1ec9939d856804c9ec3ead4b3ed869fc2ea63) +- Added card generation/printing from detail [`4a36fb6`](https://git.odit.services/lfk/frontend/commit/4a36fb6d952d9fe4d5edbe1ed0779c7fbcd50ef0) +- Formatting [`a516aa7`](https://git.odit.services/lfk/frontend/commit/a516aa7775faa2244862bb2e3c4de623c6405e5b) +- Moved the pdf generation related componenets to their own folder [`ddd82a7`](https://git.odit.services/lfk/frontend/commit/ddd82a71a7b67ead892626addfd56ba4cc632750) +- Now routing the cards page [`e852305`](https://git.odit.services/lfk/frontend/commit/e852305400a139f8169350077c30012aed556828) +- Fuggin snowpack bs [`44bc148`](https://git.odit.services/lfk/frontend/commit/44bc14820fed26d5e0d8b12ecd6b46ca0608ae7b) +- Formatting [`9f7d223`](https://git.odit.services/lfk/frontend/commit/9f7d2234fb9603a7391ec9a64253724c2c25c333) +- Now with working org runenrcard generation [`4b3d38b`](https://git.odit.services/lfk/frontend/commit/4b3d38b05b3ed74fc3c0d77e00fa2ed245e6325c) +- Now importing runner overview [`77e9c20`](https://git.odit.services/lfk/frontend/commit/77e9c205f94cf56c2e3584444899adb1e8bdf3c6) +- CardsOverview - move to 'enabled' language key [`df53c07`](https://git.odit.services/lfk/frontend/commit/df53c0745035a220d4c07fdce1b5a5e4d763411d) +- ✒ typo - "Geb" -> "Gebe" [`f794af0`](https://git.odit.services/lfk/frontend/commit/f794af0950de59a7a7b468c30abdcb5c145f65fb) +- Bumped lfk client lib version [`3cd0468`](https://git.odit.services/lfk/frontend/commit/3cd0468b1921824b131178cb02677540b079f9b0) +- drop console log - CardDetailModal [`40899e9`](https://git.odit.services/lfk/frontend/commit/40899e9d80ba07a3fbbcac72782db53d98dc318e) +- Removed debug info [`55693de`](https://git.odit.services/lfk/frontend/commit/55693de93420c2d76af296fcacc6bcad644a3cbf) + +#### [0.8.7](https://git.odit.services/lfk/frontend/compare/0.8.6...0.8.7) + +> 25 March 2021 + +- 🚀RELEASE v0.8.7 [`0af2647`](https://git.odit.services/lfk/frontend/commit/0af26479656393b0baea88f6f83c778740a67e62) +- Fixed listen on wrong permission🐞 [`0844215`](https://git.odit.services/lfk/frontend/commit/08442154f4bf94fc1101808b4585dc1f95afe8b2) + +#### [0.8.6](https://git.odit.services/lfk/frontend/compare/0.8.5...0.8.6) + +> 25 March 2021 + +- 🚀RELEASE v0.8.6 [`c3c95bf`](https://git.odit.services/lfk/frontend/commit/c3c95bf2916618efe6764a33d9a42d35764d15be) +- Merge pull request 'Know Production Bugs 🐞' (#109) from bugfix/107-prod_issues into dev [`d2050b5`](https://git.odit.services/lfk/frontend/commit/d2050b5948890a6077cbb41d82d1a6a1d1106652) +- Errors now toast errors❌ [`17e0805`](https://git.odit.services/lfk/frontend/commit/17e0805fe64f6d181f55b81afa502ee6443ebabe) +- Sorted translations 👀 [`82b1811`](https://git.odit.services/lfk/frontend/commit/82b1811971b974b686e7618b8a381e1589c168f6) +- Fixed missing translations for scanstations🌍 [`aeadef6`](https://git.odit.services/lfk/frontend/commit/aeadef60bbe71da09bb569d20ca7377645beba7f) +- Sorted translations🌍 [`a1ab65a`](https://git.odit.services/lfk/frontend/commit/a1ab65a0e975c02c01c603bf6d95a79ada1caa0b) +- Fixed runner import getting triggered with invalid information [`ddd9c39`](https://git.odit.services/lfk/frontend/commit/ddd9c396b6bfd39a7b1627d4975151943b367ebf) +- Removed middlename search from all files that had it [`6b92405`](https://git.odit.services/lfk/frontend/commit/6b92405bae21e78d694601cbc0b33eed56ef4533) +- Fixed mail login bug🐞📧 [`0768939`](https://git.odit.services/lfk/frontend/commit/076893981ff4f7f17330746c561acc570339adac) +- Now disabled search by middlename as a quick workaround 🐞 [`49e87cc`](https://git.odit.services/lfk/frontend/commit/49e87ccb15a7ed5edea22a3c3e235f7bee07d3f4) +- Fixed conflicting css [`50fffef`](https://git.odit.services/lfk/frontend/commit/50fffef13b8fce885964d8ac277b4ca24d944b2b) +- Commented out the buggy runner search to prevent bad UX [`fbe74a5`](https://git.odit.services/lfk/frontend/commit/fbe74a5d8090553a35576a17c97019939cf4f386) +- Fixed outsideclick not clearing import modal🛠 [`ef49e50`](https://git.odit.services/lfk/frontend/commit/ef49e507c175510eeb466d33f222755fac8a2a0b) + +#### [0.8.5](https://git.odit.services/lfk/frontend/compare/0.8.4...0.8.5) + +> 20 March 2021 + +- 🚀RELEASE v0.8.5 [`e838e6f`](https://git.odit.services/lfk/frontend/commit/e838e6f321bef1565a7e4316890a3c600b242e5a) +- Fixed dupliacate mutation 🐞 [`91dd525`](https://git.odit.services/lfk/frontend/commit/91dd5256e9545f62e4342ae5477c36262d6e3401) + #### [0.8.4](https://git.odit.services/lfk/frontend/compare/0.8.3...0.8.4) +> 20 March 2021 + - CONFIG: default_username + default_password [`cc926e8`](https://git.odit.services/lfk/frontend/commit/cc926e84fb8bd9d6c9fd37349e25eb802e1bb324) +- 🚀RELEASE v0.8.4 [`3d4dc2d`](https://git.odit.services/lfk/frontend/commit/3d4dc2d72b129f0134ae9f230810c3301dbd5caa) - CONFIG: add 'demo' as default username/password [`ba34710`](https://git.odit.services/lfk/frontend/commit/ba3471068ab00e2d5dbe21d6d763094e662f8347) #### [0.8.3](https://git.odit.services/lfk/frontend/compare/0.8.2...0.8.3) diff --git a/package.json b/package.json index bc5288f7..f50b79d3 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "license": "CC-BY-NC-SA-4.0", "devDependencies": { + "check-password-strength": "2.0.2", "@odit/lfk-client-js": "0.9.2", "@odit/license-exporter": "0.0.11", "@sveltejs/vite-plugin-svelte": "1.0.0-next.5", diff --git a/public/imprint_en.md b/public/imprint_en.md deleted file mode 100644 index a56808ce..00000000 --- a/public/imprint_en.md +++ /dev/null @@ -1 +0,0 @@ -Nostrud tempor dolor aute ea excepteur aute mollit elit eiusmod exercitation. Magna laborum pariatur adipisicing pariatur cupidatat exercitation duis aliquip pariatur sint exercitation deserunt labore. Consectetur id laboris dolore nostrud do velit ipsum. Eu laboris velit do commodo ad ea sint ex cillum. Cillum ipsum qui eiusmod laborum mollit sunt dolore incididunt. Cillum sunt culpa veniam voluptate et qui ut magna anim occaecat ut mollit dolor. Duis irure proident eu incididunt dolore sunt nisi aute dolore amet eu fugiat laboris quis. \ No newline at end of file diff --git a/src/App.svelte b/src/App.svelte index b488a061..4eef8994 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -1,4 +1,6 @@ @@ -180,6 +182,14 @@ import ScanDetail from "./components/scans/ScanDetail.svelte"; + + + + + + diff --git a/src/components/auth/Login.svelte b/src/components/auth/Login.svelte index 35fbbe38..6be88339 100644 --- a/src/components/auth/Login.svelte +++ b/src/components/auth/Login.svelte @@ -5,6 +5,7 @@ store.init(); import { OpenAPI, AuthService } from "@odit/lfk-client-js"; import Footer from "../general/Footer.svelte"; + import isEmail from "validator/es/lib/isEmail"; import Toastify from "toastify-js"; // ------ let username = config.default_username || ""; @@ -36,10 +37,19 @@ text: $_("login_is_checked"), duration: 500, }).showToast(); - AuthService.authControllerLogin({ - username, - password, - }) + let postdata = {}; + if (isEmail(username)) { + postdata = { + email: username, + password, + }; + } else { + postdata = { + username, + password, + }; + } + AuthService.authControllerLogin(postdata) .then(async (result) => { await localForage.setItem("logindata", result); OpenAPI.TOKEN = result.access_token; diff --git a/src/components/auth/PasswordStrength.svelte b/src/components/auth/PasswordStrength.svelte new file mode 100644 index 00000000..a629ae5b --- /dev/null +++ b/src/components/auth/PasswordStrength.svelte @@ -0,0 +1,52 @@ + + + + + + + {#if !strength.contains.includes('lowercase')} + {$_('must-contain-a-lowercase-letter')} + {/if} + {#if !strength.contains.includes('uppercase')} + {$_('must-contain-a-uppercase-letter')} + {/if} + {#if !strength.contains.includes('number')} + {$_('must-contain-a-number')} + {/if} + {#if !(strength.length > 9)} + {$_('must-be-at-least-10-characters-long')} + {/if} + {#if !(passwords_match == true)} + {$_('passwords-dont-match')} + {/if} + + diff --git a/src/components/auth/ResetPassword.svelte b/src/components/auth/ResetPassword.svelte index ad8b9792..510f718b 100644 --- a/src/components/auth/ResetPassword.svelte +++ b/src/components/auth/ResetPassword.svelte @@ -1,38 +1,43 @@ -{#if state==="reset_success"} +{#if state === 'reset_success'} @@ -56,31 +61,31 @@ -{:else if state==="reset_error"} - - - - - {$_('application_name')} - - - {$_('password-reset-failed')} - - - {$_('please-request-a-new-reset-mail')} - - +{:else if state === 'reset_error'} + + + + + {$_('application_name')} + + + {$_('password-reset-failed')} + + + {$_('please-request-a-new-reset-mail')} + - - {$_('request-a-new-reset-mail')} - + + + {$_('request-a-new-reset-mail')} + + - -{:else if state==="reset_in_progress"} +{:else if state === 'reset_in_progress'} @@ -102,11 +107,14 @@ placeholder={$_('new-password')} bind:value={password} /> + diff --git a/src/components/cards/AddCardBulkModal.svelte b/src/components/cards/AddCardBulkModal.svelte new file mode 100644 index 00000000..1ab16278 --- /dev/null +++ b/src/components/cards/AddCardBulkModal.svelte @@ -0,0 +1,240 @@ + + +{#if bulk_modal_open} + { + bulk_modal_open = false; + }}> + + + + + + + + + + + + + + + {$_('create-bulk-blanco-cards')} + + + + {$_('just-enter-how-many-you-want-and-the-system-will-create-them')} + + + + + {$_('amount')} + + + {$_('cards')} + + {#if !is_card_count_valid} + + {$_('you-must-create-at-least-one-card-or-cancel')} + + {/if} + + + + + + + + {$_('create-and-generate-pdf')} + + + {$_('create-without-pdf')} + + { + 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')} + + + + + +{/if} diff --git a/src/components/cards/AddCardModal.svelte b/src/components/cards/AddCardModal.svelte new file mode 100644 index 00000000..f72dd529 --- /dev/null +++ b/src/components/cards/AddCardModal.svelte @@ -0,0 +1,170 @@ + + +{#if modal_open} + { + modal_open = false; + }}> + + + + + + + + + + + + + + + {$_('create-a-new-card')} + + + + {$_('you-can-provide-a-runner-but-you-dont-have-to')} + {$_('if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button')} + + + + + {$_('runner')} + 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)} /> + + + + + + + + {$_('create')} + + { + 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')} + + + + + +{/if} diff --git a/src/components/cards/CardDetailModal.svelte b/src/components/cards/CardDetailModal.svelte new file mode 100644 index 00000000..46404cbf --- /dev/null +++ b/src/components/cards/CardDetailModal.svelte @@ -0,0 +1,186 @@ + + +{#if edit_modal_open} + { + edit_modal_open = false; + }}> + + + + + + + + + + + + + + + {$_('edit-a-card')} + + + + {$_('you-can-provide-a-runner-but-you-dont-have-to')} + + + + + {$_('runner')} + 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)} /> + + + + { + 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} + + + + + + + + + {$_('save-changes')} + + { + 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')} + + + + + +{/if} diff --git a/src/components/cards/Cards.svelte b/src/components/cards/Cards.svelte new file mode 100644 index 00000000..87ce7c4e --- /dev/null +++ b/src/components/cards/Cards.svelte @@ -0,0 +1,40 @@ + + + + + {$_('cards')} + {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:CREATE')} + { + 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')} + + { + 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')} + + {/if} + + + + +{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:CREATE')} + + +{/if} diff --git a/src/components/cards/CardsEmptyState.svelte b/src/components/cards/CardsEmptyState.svelte new file mode 100644 index 00000000..defdfd40 --- /dev/null +++ b/src/components/cards/CardsEmptyState.svelte @@ -0,0 +1,12 @@ + + + + + + {$_('there-are-no-cards-yet')} + {$_('add-your-first-card')} + + diff --git a/src/components/cards/CardsOverview.svelte b/src/components/cards/CardsOverview.svelte new file mode 100644 index 00000000..d5cabea8 --- /dev/null +++ b/src/components/cards/CardsOverview.svelte @@ -0,0 +1,237 @@ + + +{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:UPDATE')} + +{/if} + +{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:GET')} + {#await cards_promise} + + {$_('loading-cards')} + {$_('this-might-take-a-moment')} + + {:then} + {#if current_cards.length === 0} + + {:else} + + + + + + + + + + { + 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} + + + + {$_('code')} + + + {$_('runner')} + + + {$_('status')} + + + {$_('action')} + + + + + {#each current_cards as card} + {#if card.code + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || card.runner?.firstname + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || card.runner?.middlename + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || card.runner?.lastname + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || should_display_based_on_id(card.id)} + + + + + + {card.code} + + + + {#if card.runner} + {card.runner.firstname} + {card.runner.middlename || ''} + {card.runner.lastname} + {:else}{$_('non-blanko')}{/if} + + + + + {#if card.enabled} + {$_('enabled')} + {:else} + {$_('disabled')} + {/if} + + + + {#if active_deletes[card.id] === true} + + { + active_deletes[card.id] = false; + }} + tabindex="0" + class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')} + { + 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')} + + {:else} + + { + open_edit_modal(card); + }} + class="text-indigo-600 hover:text-indigo-900">{$_('details')} + {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')} + { + active_deletes[card.id] = true; + }} + tabindex="0" + class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')} + {/if} + + {/if} + + {/if} + {/each} + + + + {/if} + {:catch error} + + + {$_('general_promise_error')} + {error} + + + {/await} +{/if} diff --git a/src/components/cards/cards.svg b/src/components/cards/cards.svg new file mode 100644 index 00000000..bd82462d --- /dev/null +++ b/src/components/cards/cards.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/dashboard/Dashboard.svelte b/src/components/dashboard/Dashboard.svelte index 38505b49..b7957edf 100644 --- a/src/components/dashboard/Dashboard.svelte +++ b/src/components/dashboard/Dashboard.svelte @@ -1,308 +1,327 @@ - - - - - - - Lauf für Kaya! Admin - - - - - - - {$_('dashboard-title')} - - {#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:GET')} - - - - {$_('orgs')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('USER:GET')} - - - - {$_('users')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:GET')} - - - {$_('user-groups')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')} - - - - {$_('runners')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')} - - - {$_('teams')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')} - - - - {$_('donors')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')} - - - - {$_('donations')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('TRACK:GET')} - - - {$_('tracks')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:GET')} - - - - Scans - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:GET')} - - - - {$_('contacts')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('STATION:GET')} - - - - {$_('scanstations')} - - {/if} - - - - - {$_('settings')} - - - - - {$_('about')} - - { - AuthService.authControllerLogout(); - logout(); - }}> - - - {$_('logout')} - - - - - { - navOpen = true; - }} - class="flex items-center justify-between w-full px-4 bg-white border-b h-14 md:hidden"> - - Menu - - - - - - { - navOpen = false; - }} - class:hidden={!navOpen} - class="fixed inset-0 z-10 w-screen h-screen bg-black bg-opacity-25 md:hidden" /> - + + + + + + + Lauf für Kaya! Admin + + + + + + + {$_('dashboard-title')} + + {#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:GET')} + + + + {$_('orgs')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('USER:GET')} + + + + {$_('users')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:GET')} + + + {$_('user-groups')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')} + + + + {$_('runners')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')} + + + {$_('teams')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')} + + + + {$_('donors')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')} + + + + {$_('donations')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('TRACK:GET')} + + + {$_('tracks')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:GET')} + + + + + {$_('cards')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:GET')} + + + + Scans + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:GET')} + + + + {$_('contacts')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('STATION:GET')} + + + + {$_('scanstations')} + + {/if} + + + + + {$_('settings')} + + + + + {$_('about')} + + { + AuthService.authControllerLogout(); + logout(); + }}> + + + {$_('logout')} + + + + + { + navOpen = true; + }} + class="flex items-center justify-between w-full px-4 bg-white border-b h-14 md:hidden"> + + Menu + + + + + + { + navOpen = false; + }} + class:hidden={!navOpen} + class="fixed inset-0 z-10 w-screen h-screen bg-black bg-opacity-25 md:hidden" /> + diff --git a/src/components/donations/DonationsOverview.svelte b/src/components/donations/DonationsOverview.svelte index d067c1f6..c417614b 100644 --- a/src/components/donations/DonationsOverview.svelte +++ b/src/components/donations/DonationsOverview.svelte @@ -74,20 +74,12 @@ .toLowerCase() .includes( searchvalue.toLowerCase() - ) || donation.donor.middlename - .toLowerCase() - .includes( - searchvalue.toLowerCase() - ) || donation.donor.lastname + ) || donation.donor.lastname .toLowerCase() .includes( searchvalue.toLowerCase() ) || donation.runner?.firstname .toLowerCase() - .includes( - searchvalue.toLowerCase() - ) || donation.runner?.middlename - .toLowerCase() .includes( searchvalue.toLowerCase() ) || donation.runner?.lastname diff --git a/src/components/donors/DonorsOverview.svelte b/src/components/donors/DonorsOverview.svelte index 86ddf16a..88984241 100644 --- a/src/components/donors/DonorsOverview.svelte +++ b/src/components/donors/DonorsOverview.svelte @@ -88,11 +88,7 @@ .toLowerCase() .includes( searchvalue.toLowerCase() - ) || donor.middlename - .toLowerCase() - .includes( - searchvalue.toLowerCase() - ) || donor.lastname + ) || donor.lastname .toLowerCase() .includes( searchvalue.toLowerCase() diff --git a/src/components/general/Imprint.svelte b/src/components/general/Imprint.svelte index 33c878e6..0c81c55e 100644 --- a/src/components/general/Imprint.svelte +++ b/src/components/general/Imprint.svelte @@ -6,13 +6,15 @@ let html = ""; async function load() { let md = await fetch("/imprint_" + getLocaleFromNavigator() + ".md"); - if((await md.text()).includes(" diff --git a/src/components/general/Privacy.svelte b/src/components/general/Privacy.svelte index 0400908c..6ec94a46 100644 --- a/src/components/general/Privacy.svelte +++ b/src/components/general/Privacy.svelte @@ -6,13 +6,15 @@ let html = ""; async function load() { let md = await fetch("/privacy_" + getLocaleFromNavigator() + ".md"); - if((await md.text()).includes(" diff --git a/src/components/orgs/OrgDetail.svelte b/src/components/orgs/OrgDetail.svelte index 21798b06..6fdcd8d6 100644 --- a/src/components/orgs/OrgDetail.svelte +++ b/src/components/orgs/OrgDetail.svelte @@ -10,6 +10,9 @@ import ImportRunnerModal from "../runners/ImportRunnerModal.svelte"; import PromiseError from "../base/PromiseError.svelte"; import Select from "svelte-select"; + import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; + import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; + import { tick } from "svelte"; $: delete_triggered = false; $: address_valid_or_none = (isAddress1Valid && iszipcodevalid && iscityvalid) || @@ -18,6 +21,9 @@ let original = ""; let original_object = {}; let contacts = []; + let valueCopy = null; + let areaDom; + let copied = false; export let params; $: editable = {}; $: contact = {}; @@ -26,7 +32,10 @@ $: isAddress1Valid = editable.address?.address1?.trim().length !== 0; $: iszipcodevalid = editable.address?.postalcode?.trim().length !== 0; $: iscityvalid = editable.address?.city?.trim().length !== 0; - $: sponsoring_contracts_download_open = false; + $: sponsoring_contracts_show = true; + $: cards_show = true; + $: generate_orgs = [original_object]; + $: registrationLink = `${config.baseurl}/selfservice/register/${editable.registrationKey}`; const getContactLabel = (option) => option.firstname + " " + (option.middlename || "") + " " + option.lastname; const promise = RunnerOrganizationService.runnerOrganizationControllerGetOne( @@ -60,14 +69,6 @@ }); let modal_open = false; 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() { RunnerOrganizationService.runnerOrganizationControllerRemove( original_object.id, @@ -102,6 +103,7 @@ postdata ) .then((resp) => { + editable.registrationKey = resp.registrationKey; original_object = Object.assign({}, editable); original = JSON.stringify(original_object); Toastify({ @@ -114,58 +116,46 @@ } else { } } - export let import_modal_open = false; - async function generateSponsoringContract(locale) { - sponsoring_contracts_download_open = false; - const runners = await RunnerOrganizationService.runnerOrganizationControllerGetRunners( - original_object.id - ); - const toast = Toastify({ - text: $_("generating-pdf"), - duration: -1, - }).showToast(); - fetch( - `${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(runners), + async function copy() { + if(!editable.registrationKey){ + Toastify({ + text: $_('you-have-to-save-your-changes-to-generate-a-link'), + duration: 500, + backgroundColor: + "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", + }).showToast(); + return; + } + valueCopy = registrationLink; + await tick(); + areaDom.focus(); + areaDom.select(); + try { + const successful = document.execCommand("copy"); + if (!successful) { + throw new Error(); } - ) - .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_" + 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) => {}); + Toastify({ + text: $_("copied-link-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; } + export let import_modal_open = false; +{#if valueCopy != null}{valueCopy}{/if} { import_modal_open = false; @@ -182,64 +172,10 @@ {original_object.name} - - - { - 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')} - - - - - {#if sponsoring_contracts_download_open} - - - {$_('select-language')} - { - 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')} - - { - 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')} - - - - {/if} - + + {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')} { @@ -382,99 +318,151 @@ on:select={(selectedValue) => (editable.contact = selectedValue.detail.value)} on:clear={() => (editable.contact = null)} /> - - - - + + + + + + + {$_('selfservice-registration')} + - - {$_('address')} + + {#if editable.registrationEnabled} + + + + {#if editable.registrationKey} + {registrationLink} + {:else} + {$_('you-have-to-save-your-changes-to-generate-a-link')} + {/if} + + + + + + + {#if editable.registrationKey} + + {$_('click-to-copy-the-link-into-your-clipboard')} + + {/if} + + {/if} + + + + + + + + {$_('address')} + + + + {#if editable.address_checked === true} + + {$_('address')} + + {#if !isAddress1Valid} + + {$_('address-is-required')} + + {/if} + + + {$_('apartment-suite-etc')} + + + + {$_('zip-postal-code')} + + {#if !iszipcodevalid} + + {$_('valid-zipcode-postal-code-is-required')} + + {/if} + + + {$_('city')} + + {#if !iscityvalid} + + {$_('valid-city-is-required')} + + {/if} + + {/if} - {#if editable.address_checked === true} - - {$_('address')} - - {#if !isAddress1Valid} - - {$_('address-is-required')} - - {/if} - - - {$_('apartment-suite-etc')} - - - - {$_('zip-postal-code')} - - {#if !iszipcodevalid} - - {$_('valid-zipcode-postal-code-is-required')} - - {/if} - - - {$_('city')} - - {#if !iscityvalid} - - {$_('valid-city-is-required')} - - {/if} - - {/if} {:else} {#await promise} diff --git a/src/components/orgs/OrgOverview.svelte b/src/components/orgs/OrgOverview.svelte index 1d33261f..9c792be5 100644 --- a/src/components/orgs/OrgOverview.svelte +++ b/src/components/orgs/OrgOverview.svelte @@ -1,5 +1,6 @@ - {#if current_organizations.some((r) => r.is_selected === true)} - - - { - 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')} - - - - {#if sponsoring_contracts_download_open} - - - {$_('select-language')} - { - 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')} - - { - 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')} - - - - {/if} - - {/if} + + diff --git a/src/components/pdf_generation/GenerateRunnerCards.svelte b/src/components/pdf_generation/GenerateRunnerCards.svelte new file mode 100644 index 00000000..76386dec --- /dev/null +++ b/src/components/pdf_generation/GenerateRunnerCards.svelte @@ -0,0 +1,339 @@ + + +{#if cards_show} + + + { + 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')} + + + + + {#if cards_dropdown_open} + + + {$_('select-language')} + { + 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')} + + { + 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')} + + + + {/if} + +{/if} diff --git a/src/components/pdf_generation/GenerateSponsoringContracts.svelte b/src/components/pdf_generation/GenerateSponsoringContracts.svelte new file mode 100644 index 00000000..f24ea294 --- /dev/null +++ b/src/components/pdf_generation/GenerateSponsoringContracts.svelte @@ -0,0 +1,254 @@ + + +{#if sponsoring_contracts_show} + + + { + 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')} + + + + + {#if sponsoring_contracts_download_open} + + + {$_('select-language')} + { + 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')} + + { + 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')} + + + + {/if} + +{/if} diff --git a/src/components/runners/ImportRunnerModal.svelte b/src/components/runners/ImportRunnerModal.svelte index 63088e64..1932ca1c 100644 --- a/src/components/runners/ImportRunnerModal.svelte +++ b/src/components/runners/ImportRunnerModal.svelte @@ -19,6 +19,11 @@ export let current_runners; export let import_modal_open; $: searchvalue = ""; + $: importButtonEnabled = + recent_processed && + (!(selected_org_or_team == "" || selected_org_or_team == null) || + !(passed_org?.id == null || passed_org?.id == 0) || + !(passed_team?.id == null || passed_team?.id == 0)); const dispatch = createEventDispatcher(); function cancelModal() { json_output = []; @@ -44,7 +49,10 @@ groups = groups.concat(orgs); RunnerTeamService.runnerTeamControllerGetAll().then((val) => { const teams = val.map((r) => { - return { label: `${r.parentGroup.name} > ${r.name}`, value: `TEAM_${r.id}` }; + return { + label: `${r.parentGroup.name} > ${r.name}`, + value: `TEAM_${r.id}`, + }; }); groups = groups.concat(teams); }); @@ -120,6 +128,13 @@ .catch((err) => { toast.hideToast(); recent_processed = true; + Toastify({ + text: $_("error-during-import"), + duration: 500, + backgroundColor: + "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", + }).showToast(); + cancelModal(); }); } if (opened_from === "TeamDetail") { @@ -137,6 +152,13 @@ .catch((err) => { toast.hideToast(); recent_processed = true; + Toastify({ + text: $_("error-during-import"), + duration: 500, + backgroundColor: + "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", + }).showToast(); + cancelModal(); }); } if (opened_from === "RunnerOverview") { @@ -160,6 +182,13 @@ .catch((err) => { toast.hideToast(); recent_processed = true; + Toastify({ + text: $_("error-during-import"), + duration: 500, + backgroundColor: + "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", + }).showToast(); + cancelModal(); }); } if (selected_org_or_team.includes("TEAM_")) { @@ -182,6 +211,13 @@ .catch((err) => { toast.hideToast(); recent_processed = true; + Toastify({ + text: $_("error-during-import"), + duration: 500, + backgroundColor: + "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", + }).showToast(); + cancelModal(); }); } } @@ -195,7 +231,7 @@ use:focusTrap use:clickOutside on:click_outside={() => { - import_modal_open = false; + cancelModal(); }}> @@ -349,6 +385,8 @@ diff --git a/src/components/runners/RunnerDetail.svelte b/src/components/runners/RunnerDetail.svelte index fda1c21f..c998cf69 100644 --- a/src/components/runners/RunnerDetail.svelte +++ b/src/components/runners/RunnerDetail.svelte @@ -1,398 +1,297 @@ - - -{#await runner_promise} - {$_('loading-runners')} -{:then} - - - - - - - - - - - {$_('runners')} - - - - {original_data.firstname} - {original_data.middlename || ''} - {original_data.lastname} - - - - - - - {original_data.firstname} - {original_data.middlename || ''} - {original_data.lastname} - - {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')} - {#if delete_triggered} - {$_('confirm-deletion')} - { - 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')} - {/if} - - - { - 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-contract')} - - - - - {#if sponsoring_contracts_download_open} - - - {$_('select-language')} - { - 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')} - - { - 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')} - - - - {/if} - - {#if !delete_triggered} - { - 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-runner')} - {/if} - {/if} - {#if !delete_triggered} - {$_('save-changes')} - {/if} - - - - - {$_('first-name')} - - {#if !isFirstnameValid} - - {$_('first-name-is-required')} - - {/if} - - - {$_('middle-name')} - - - - {$_('last-name')} - - {#if !isLastnameValid} - - {$_('last-name-is-required')} - - {/if} - - - {$_('e-mail-adress')} - - {#if !isEmailValid} - - {$_('valid-email-is-required')} - - {/if} - - - {$_('phone')} - - - - {$_('group')} - 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)} /> - - - {$_('distance')} - - {original_data.distance} km - - -{:catch error} - -{/await} + + +{#await runner_promise} + {$_('loading-runners')} +{:then} + + + + + + + + + + + {$_('runners')} + + + + {original_data.firstname} + {original_data.middlename || ''} + {original_data.lastname} + + + + + + + {original_data.firstname} + {original_data.middlename || ''} + {original_data.lastname} + + {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')} + {#if delete_triggered} + {$_('confirm-deletion')} + { + 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')} + {/if} + + + {#if !delete_triggered} + { + 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-runner')} + {/if} + {/if} + {#if !delete_triggered} + {$_('save-changes')} + {/if} + + + + + {$_('first-name')} + + {#if !isFirstnameValid} + + {$_('first-name-is-required')} + + {/if} + + + {$_('middle-name')} + + + + {$_('last-name')} + + {#if !isLastnameValid} + + {$_('last-name-is-required')} + + {/if} + + + {$_('e-mail-adress')} + + {#if !isEmailValid} + + {$_('valid-email-is-required')} + + {/if} + + + {$_('phone')} + + + + {$_('group')} + 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)} /> + + + {$_('distance')} + + {original_data.distance} km + + +{:catch error} + +{/await} diff --git a/src/components/runners/RunnersOverview.svelte b/src/components/runners/RunnersOverview.svelte index bfc06a15..6a740f74 100644 --- a/src/components/runners/RunnersOverview.svelte +++ b/src/components/runners/RunnersOverview.svelte @@ -1,364 +1,256 @@ - - -{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')} - {#await runners_promise} - - {$_('runners-are-being-loaded')} - {$_('this-might-take-a-moment')} - - {:then} - {#if current_runners.length === 0} - - {:else} - - - {$_('filter-by-organization-team')} - { - selectedFilter = event.detail; - }} - selectedValue={selectedFilter} - placeholder={$_('filter-by-organization-team')} - containerClasses="mt-1 py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" - items={selectgroups} - isMulti={true} /> - - - {#if current_runners.some((r) => r.is_selected === true)} - - - { - 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')} - - - - - {#if sponsoring_contracts_download_open} - - - {$_('select-language')} - { - 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')} - - { - 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')} - - - - {/if} - - {/if} - - - - - - - { - const newstate = !current_runners.some((r) => r.is_selected === true); - current_runners = current_runners.map((r) => { - r.is_selected = newstate; - return r; - }); - }} - class="underline cursor-pointer select-none">{#if current_runners.some((r) => r.is_selected === true)} - {$_('deselect-all')} - {:else}{$_('select-all')}{/if} - - - - {$_('name')} - - - {$_('contact-information')} - - - {$_('group')} - - - {$_('distance-in-km')} - - - {$_('action')} - - - - - {#each current_runners as runner} - {#if runner.firstname - .toLowerCase() - .includes( - searchvalue.toLowerCase() - ) || runner.middlename - .toLowerCase() - .includes( - searchvalue.toLowerCase() - ) || runner.lastname - .toLowerCase() - .includes( - searchvalue.toLowerCase() - ) || should_display_based_on_id(runner.id)} - {#if filterGroupIDs.includes(runner.group.id) || filterGroupIDs.includes(runner.group.parentGroup?.id) || filterGroupIDs.length === 0} - - - - - - - - - {runner.firstname} - {runner.middlename || ''} - {runner.lastname} - - - - - - {#if runner.email} - {runner.email} - {/if} - {#if runner.phone} - {runner.phone} - {/if} - {#if runner.address.address1 !== null} - {runner.address.address1} - {runner.address.address2 || ''} - {runner.address.postalcode} - {runner.address.city} - {runner.address.country} - {/if} - - - {#if runner.group.responseType === 'RUNNERTEAM'} - {runner.group.name} - {/if} - {#if runner.group.responseType === 'RUNNERORGANIZATION'} - {runner.group.name} - {/if} - - - {runner.distance} - - {#if active_deletes[runner.id] === true} - - { - active_deletes[runner.id] = false; - }} - tabindex="0" - class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')} - { - 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')} - - {:else} - - {$_('details')} - {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')} - { - active_deletes[runner.id] = true; - }} - tabindex="0" - class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')} - {/if} - - {/if} - - {/if} - {/if} - {/each} - - - - {/if} - {:catch error} - - - {$_('general_promise_error')} - {error} - - - {/await} -{/if} + + +{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')} + {#await runners_promise} + + {$_('runners-are-being-loaded')} + {$_('this-might-take-a-moment')} + + {:then} + {#if current_runners.length === 0} + + {:else} + + + {$_('filter-by-organization-team')} + { + selectedFilter = event.detail; + }} + selectedValue={selectedFilter} + placeholder={$_('filter-by-organization-team')} + containerClasses="mt-1 py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" + items={selectgroups} + isMulti={true} /> + + + + + + + + + + + { + const newstate = !current_runners.some((r) => r.is_selected === true); + current_runners = current_runners.map((r) => { + r.is_selected = newstate; + return r; + }); + }} + class="underline cursor-pointer select-none">{#if current_runners.some((r) => r.is_selected === true)} + {$_('deselect-all')} + {:else}{$_('select-all')}{/if} + + + + {$_('name')} + + + {$_('contact-information')} + + + {$_('group')} + + + {$_('distance-in-km')} + + + {$_('action')} + + + + + {#each current_runners as runner} + {#if runner.firstname + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || runner.lastname + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || should_display_based_on_id(runner.id)} + {#if filterGroupIDs.includes(runner.group.id) || filterGroupIDs.includes(runner.group.parentGroup?.id) || filterGroupIDs.length === 0} + + + + + + + + + {runner.firstname} + {runner.middlename || ''} + {runner.lastname} + + + + + + {#if runner.email} + {runner.email} + {/if} + {#if runner.phone} + {runner.phone} + {/if} + {#if runner.address.address1 !== null} + {runner.address.address1} + {runner.address.address2 || ''} + {runner.address.postalcode} + {runner.address.city} + {runner.address.country} + {/if} + + + {#if runner.group.responseType === 'RUNNERTEAM'} + {runner.group.name} + {/if} + {#if runner.group.responseType === 'RUNNERORGANIZATION'} + {runner.group.name} + {/if} + + + {runner.distance} + + {#if active_deletes[runner.id] === true} + + { + active_deletes[runner.id] = false; + }} + tabindex="0" + class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')} + { + 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')} + + {:else} + + {$_('details')} + {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')} + { + active_deletes[runner.id] = true; + }} + tabindex="0" + class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')} + {/if} + + {/if} + + {/if} + {/if} + {/each} + + + + {/if} + {:catch error} + + + {$_('general_promise_error')} + {error} + + + {/await} +{/if} diff --git a/src/components/scans/ScansOverview.svelte b/src/components/scans/ScansOverview.svelte index 81ccec1e..c653d614 100644 --- a/src/components/scans/ScansOverview.svelte +++ b/src/components/scans/ScansOverview.svelte @@ -81,10 +81,6 @@ .includes( searchvalue.toLowerCase() ) || scan.runner?.firstname - .toLowerCase() - .includes( - searchvalue.toLowerCase() - ) || scan.runner?.middlename .toLowerCase() .includes( searchvalue.toLowerCase() diff --git a/src/components/scanstations/CopyScanStationTokenModal.svelte b/src/components/scanstations/CopyScanStationTokenModal.svelte index 2067b175..96c0d8ad 100644 --- a/src/components/scanstations/CopyScanStationTokenModal.svelte +++ b/src/components/scanstations/CopyScanStationTokenModal.svelte @@ -23,14 +23,14 @@ throw new Error(); } Toastify({ - text: $_('copied-token-to-clipboard'), + 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'), + text: $_("error-whyile-copying-to-clipboard"), duration: 500, backgroundColor: "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" /> - {$_('token')} + + {$_('token')} + {$_('the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again')} @@ -86,7 +88,7 @@ Token + class="block text-sm font-medium text-gray-700">{$_('token')} - {$_('click-to-copy-token-to-clipboard')} + + {$_('click-to-copy-token-to-clipboard')} + diff --git a/src/components/settings/Settings.svelte b/src/components/settings/Settings.svelte index e570390a..2f8e3c32 100644 --- a/src/components/settings/Settings.svelte +++ b/src/components/settings/Settings.svelte @@ -4,6 +4,9 @@ import { MeService } from "@odit/lfk-client-js"; import Toastify from "toastify-js"; import ConfirmProfileDeletion from "./ConfirmProfileDeletion.svelte"; + import PasswordStrength, { + password_strong_enough_and_equal, + } from "../auth/PasswordStrength.svelte"; $: data_loaded = false; $: delete_triggered = false; $: original_data = {}; @@ -15,8 +18,10 @@ JSON.stringify(editable) === JSON.stringify(original_data) ); $: save_enabled = changes_performed && isEmail(editable.email); - $: update_password_enabled = - password_change.length > 0 && password_change === password_confirm; + $: update_password_enabled = password_strong_enough_and_equal( + password_change, + password_confirm + ); const user_promise = MeService.meControllerGet().then((data) => { data_loaded = true; data.groups = data.groups.map((g) => g.id); @@ -45,7 +50,7 @@ function changePassword() { if (data_loaded === true && update_password_enabled) { Toastify({ - text: $_('changing-your-password'), + text: $_("changing-your-password"), duration: 2500, }).showToast(); let postdata = Object.assign({}, original_data); @@ -56,7 +61,7 @@ password_change = ""; postdata = {}; Toastify({ - text: $_('password-changed'), + text: $_("password-changed"), duration: 2500, backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", }).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" placeholder={$_('password')} /> - {#if password_change != password_confirm && password_change.length > 0} - {$_('passwords-dont-match')} - {/if} + {#if update_password_enabled} - - {$_('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')} + {/if} diff --git a/src/components/teams/TeamDetail.svelte b/src/components/teams/TeamDetail.svelte index ec21a79a..24400507 100644 --- a/src/components/teams/TeamDetail.svelte +++ b/src/components/teams/TeamDetail.svelte @@ -1,399 +1,297 @@ - - - { - import_modal_open = false; - }} - passed_team={teamdata} - passed_orgs={[]} - passed_org={{}} - opened_from="TeamDetail" - bind:import_modal_open /> - -{#if data_loaded} - - - {original.name} - - - - { - 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')} - - - - - {#if sponsoring_contracts_download_open} - - - {$_('select-language')} - { - 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')} - - { - 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')} - - - - {/if} - - {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')} - { - import_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"> - {$_('import-runners')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')} - {#if delete_triggered} - {$_('confirm-delete')} - { - 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')} - {/if} - {#if !delete_triggered} - { - 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-team')} - {/if} - {/if} - {#if !delete_triggered} - {$_('save-changes')} - {/if} - - - - - - - - - - - - Home - - - - - - - Teams - - - - Team-Details #{params.teamid} - - - - - - - Name - - - - {$_('contact')} - 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)} /> - - - {$_('organization')} - 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)} /> - - -{:else} - {#await promise} - {$_('team-detail-is-being-loaded')} - {:catch error} - - {/await} -{/if} + + + { + import_modal_open = false; + }} + passed_team={teamdata} + passed_orgs={[]} + passed_org={{}} + opened_from="TeamDetail" + bind:import_modal_open /> + +{#if data_loaded} + + + {original.name} + + + + {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')} + { + import_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"> + {$_('import-runners')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')} + {#if delete_triggered} + {$_('confirm-delete')} + { + 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')} + {/if} + {#if !delete_triggered} + { + 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-team')} + {/if} + {/if} + {#if !delete_triggered} + {$_('save-changes')} + {/if} + + + + + + + + + + + + Home + + + + + + + Teams + + + + Team-Details #{params.teamid} + + + + + + + Name + + + + {$_('contact')} + 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)} /> + + + {$_('organization')} + 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)} /> + + +{:else} + {#await promise} + {$_('team-detail-is-being-loaded')} + {:catch error} + + {/await} +{/if} diff --git a/src/components/teams/Teams.svelte b/src/components/teams/Teams.svelte index 09eb65dc..1da06e57 100644 --- a/src/components/teams/Teams.svelte +++ b/src/components/teams/Teams.svelte @@ -10,7 +10,7 @@ {$_('teams')} - {#if store.state.jwtinfo.userdetails.permissions.includes('USER:CREATE')} + {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:CREATE')} { modal_open = true; @@ -27,6 +27,6 @@ -{#if store.state.jwtinfo.userdetails.permissions.includes('USER:CREATE')} +{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:CREATE')} {/if} diff --git a/src/components/teams/TeamsOverview.svelte b/src/components/teams/TeamsOverview.svelte index d003f2e8..ff6ed46d 100644 --- a/src/components/teams/TeamsOverview.svelte +++ b/src/components/teams/TeamsOverview.svelte @@ -7,9 +7,17 @@ import TeamsEmptyState from "./TeamsEmptyState.svelte"; import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte"; import { clickOutside } from "../base/outsideclick"; + import GenerateSponsoringContracts from "../pdf_generation/GenerateSponsoringContracts.svelte"; + import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte"; $: searchvalue = ""; $: active_deletes = []; - $: sponsoring_contracts_download_open = false; + $: sponsoring_contracts_show = current_teams.some( + (r) => r.is_selected === true + ); + $: cards_show = current_teams.some( + (r) => r.is_selected === true + ); + $: generate_teams = current_teams.filter((r) => r.is_selected === true); export let current_teams = []; let modal_open = false; let delete_team = {}; @@ -19,70 +27,6 @@ teams_promise.then((data) => { usersstore.set(data); }); - 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; - } - }); - async function generateSponsoringContract(locale) { - sponsoring_contracts_download_open = false; - const teams = current_teams.filter((r) => r.is_selected === true); - const toast = Toastify({ - text: $_("generating-pdfs"), - duration: -1, - }).showToast(); - let count = 0; - for (const t of teams) { - count++; - const runners = await RunnerTeamService.runnerTeamControllerGetRunners( - t.id - ); - fetch( - `${config.baseurl}/documents/contracts?locale=${locale}&download=true&key=${config.documentserver_key}`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(runners), - } - ) - .then((response) => { - if (response.status != "200") { - toast.hideToast(); - Toastify({ - text: $_("pdf-generation-failed"), - duration: 3500, - backgroundColor: - "linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)", - }).showToast(); - } else { - return response.blob(); - } - }) - .then((blob) => { - const url = window.URL.createObjectURL(blob); - let a = document.createElement("a"); - a.href = url; - a.download = "Sponsorings_" + t.name + ".pdf"; - document.body.appendChild(a); - a.click(); - a.remove(); - if (count === teams.length) { - toast.hideToast(); - Toastify({ - text: $_("pdfs-successfully-generated"), - duration: 3500, - backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", - }).showToast(); - } - }) - .catch((err) => {}); - } - } - {#if current_teams.some((r) => r.is_selected === true)} - - - { - 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')} - - - - - {#if sponsoring_contracts_download_open} - { - sponsoring_contracts_download_open = false; - }}> - - {$_('select-language')} - { - 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')} - - { - 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')} - - - - {/if} - - {/if} + + diff --git a/src/components/users/AddUserModal.svelte b/src/components/users/AddUserModal.svelte index 14409ddf..e5db70f8 100644 --- a/src/components/users/AddUserModal.svelte +++ b/src/components/users/AddUserModal.svelte @@ -5,6 +5,9 @@ import { UserService } from "@odit/lfk-client-js"; import isEmail from "validator/es/lib/isEmail"; import Toastify from "toastify-js"; + import PasswordStrength, { + password_strong_enough, + } from "../auth/PasswordStrength.svelte"; export let modal_open; export let current_users; let firstname_input; @@ -28,7 +31,10 @@ $: isLastnameValid = lastname_input_value.trim().length !== 0; $: isFirstnameValid = firstname_input_value.trim().length !== 0; $: createbtnenabled = - isFirstnameValid && isLastnameValid && isPasswordValid && isEmailValid; + isFirstnameValid && + isLastnameValid && + password_strong_enough(password_input_value) && + isEmailValid; (function () { document.onkeydown = function (e) { e = e || window.event; @@ -203,12 +209,8 @@ type="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" /> - {#if !isPasswordValid} - - {$_('password-is-required')} - - {/if} + Bitte gebe eine Telefonnummer im internationalen Format an...", "the-scans-distance-must-be-greater-than-0m": "Die Distanz muss größer als 0m sein.", + "the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again": "Der Scannerstation Token wird nur einmal angezeigt - du kannst ihn nicht ändern oder ihn dir nochmal anzeigen lassen!", + "there-are-no-cards-yet": "Es gibt noch keine Läuferkarten.", "there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.", "there-are-no-donations-yet": "Es gibt noch keine Sponsorings", "there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen", @@ -332,8 +373,10 @@ "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", @@ -353,6 +396,7 @@ "updated-organization": "Organisation wurde aktualisiert", "updated-scan": "Scan wurde aktualisiert", "updateing-group": "Gruppe wird aktualisiert...", + "updating-card": "Karte wird aktualisiert", "updating-organization": "Organisation wird aktualisiert", "updating-permissions": "Berechtigungen werden aktualisiert...", "updating-runner": "Läufer:in wird aktualisiert.", @@ -374,7 +418,10 @@ "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-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" } \ No newline at end of file diff --git a/src/locales/en.json b/src/locales/en.json index 24544ac8..b86f6b7c 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -4,11 +4,13 @@ "about": "About", "action": "Action", "active": "Active", + "add-card": "Add Card", "add-donation": "Add donation", "add-donor": "add donor", "add-scan": "Add scan", "add-the-first-scanstation": "Add your first scanstation.", "add-user-group": "Add User Group", + "add-your-first-card": "Add your first card", "add-your-first-contact": "Add your first contact", "add-your-first-donor": "add your first donor", "add-your-first-group": "Add your first group", @@ -19,6 +21,7 @@ "add-your-first-user": "Add your first user", "add-your-fist-donation": "Add your fist donation", "add-your-fist-scan": "Add your fist scan", + "adding-card": "Adding Card", "adding-scan": "Adding Scan", "address": "Address", "address-is-required": "Address is required", @@ -27,6 +30,7 @@ "all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well", "all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!", "all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!", + "amount": "Amount", "amount-per-kilometer": "Amount per kilometer", "apartment-suite-etc": "Apartment, suite, etc.", "application_name": "Lauf für Kaya! - Admin", @@ -42,10 +46,17 @@ "cancel-keep-organization": "Cancel, keep organization", "cancel-keep-team": "Cancel, keep team", "cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity", + "card-added": "Card added", + "card-deleted": "Card deleted", + "card-updated": "Card updated", + "cards": "Cards", "change-your-password-here": "Change your password here", "changing-your-password": "Changing your password", "city": "City", + "click-to-copy-the-link-into-your-clipboard": "Click to copy the link into your clipboard", + "click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard", "close": "Close", + "code": "Code", "configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times", "confirm": "Confirm", "confirm-delete": "Confirm Delete", @@ -62,10 +73,13 @@ "contact-is-not-a-member-in-any-group": "Contact is not a member in any group", "contacts": "Contacts", "contacts-are-being-loaded": "contacts are being loaded...", + "copied-link-to-clipboard": "Copied link to clipboard", + "copied-token-to-clipboard": "Copied token to clipboard", "count_organizations": "# Organizations", "count_teams": "# Teams", "create": "Create", "create-a-new": "Create a new", + "create-a-new-card": "Create a new card", "create-a-new-contact": "Create a new contact", "create-a-new-distance-donation": "Create a new distance donation", "create-a-new-donor": "Create a new donor", @@ -78,10 +92,16 @@ "create-a-new-track": "Create a new Track", "create-a-new-user": "Create a new User", "create-a-new-user-group": "Create a new user group", + "create-and-generate-pdf": "Create and generate PDF", + "create-bulk-blanco-cards": "Create bulk blanco cards", + "create-bulk-cards": "Add blanco cards", "create-organization": "Create Organization", "create-team": "Create Team", "create-track": "Create Track", "create-user": "Create User", + "create-without-pdf": "Create without PDF", + "created-blanco-cards": "Created blanco cards", + "creating-blanco-cards": "Creating blanco cards", "credits": "Credits", "csv_import__class": "Class", "csv_import__firstname": "Firstname", @@ -124,6 +144,7 @@ "description-optional": "Description (optional)", "deselect-all": "deselect all", "details": "Details", + "disabled": "disabled", "distance": "Distance", "distance-donation": "distance donation", "distance-in-km": "Distance in km", @@ -148,10 +169,14 @@ "dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌", "e-mail-adress": "E-Mail Adress", "edit": "Edit", + "edit-a-card": "Edit a card", "edit-permissions": "edit permissions", "email_address_or_username": "Email / username", "enabled": "enabled", + "enabled_large": "Enabled", "english": "English", + "error-during-import": "Error during import", + "error-whyile-copying-to-clipboard": "Error while copying to clipboard", "error_on_login": "Error on login", "erteilte": "Directly granted", "everything-concerning-your-profile": "Everything concerning your profile", @@ -166,6 +191,7 @@ "geerbte": "inherited", "general-stats": "General Stats", "general_promise_error": "😢 Error", + "generate-runnercards": "Generate Runnercards", "generate-sponsoring-contract": "generate sponsoring contract", "generate-sponsoring-contracts": "generate sponsoring contracts", "generating-pdf": "generating PDF...", @@ -184,6 +210,7 @@ "groups-are-being-loaded": "Groups are being loaded", "home": "Home", "icon-image-credits": "We also want to thank these projects for illustrations and icons:", + "if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button": "If you want to create multiple blanco cards: Try the 'Add blanco cards' button.", "import-finished": "Import finished", "import-runners": "Import runners", "import__target-organization": "Target Organization", @@ -194,6 +221,7 @@ "internal-error": "Internal Error", "invalid": "Invalid", "invalid-mail-reset": "the provided email is invalid", + "just-enter-how-many-you-want-and-the-system-will-create-them": "Just enter how many you want and the system will create them", "laeufer-hinzufuegen": "Add runner", "laeufer-importieren": "Läufer importieren", "laptime": "Laptime", @@ -202,6 +230,7 @@ "lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.", "license": "License", "licenses-are-being-loaded": "Licenses are being loaded...", + "loading-cards": "Loading cards", "loading-contact-details": "Loading contact details...", "loading-donation-details": "Loading donation details", "loading-donor-details": "Loading donor details", @@ -218,6 +247,10 @@ "middle-name": "Middle name", "minimum-lap-time-in-s": "minimum lap time in s", "minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0", + "must-be-at-least-10-characters-long": "Must be at least 10 characters long!", + "must-contain-a-lowercase-letter": "Must contain a lowercase letter!", + "must-contain-a-number": "Must contain a number!", + "must-contain-a-uppercase-letter": "Must contain a uppercase letter!", "name": "Name", "name-is-required": "Name is required", "new-password": "New password", @@ -231,6 +264,7 @@ "no-organizations-found": "No organizations found", "no-runners-found": "No runners found", "no-tracks-added-yet": "there are no tracks added yet.", + "non-blanko": "Non/Blanko", "organization": "Organization", "organization-added": "Organization added", "organization-deleted": "Organization deleted", @@ -248,7 +282,7 @@ "password-reset-in-progress": "Password Reset in Progress...", "password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".", "password-reset-successful": "Password Reset successful!", - "passwords-dont-match": "Passwords don't match", + "passwords-dont-match": "Passwords don't match!", "pdf-generation-failed": "PDF generation failed!", "pdf-successfully-generated": "PDF successfully generated!", "pdfs-successfully-generated": "PDFs successfully generated!", @@ -256,6 +290,7 @@ "permissions": "Permissions", "permissions-updated": "Permissions updated!", "phone": "Phone", + "please-copy-the-token-and-store-it-somewhere-save": "Please copy the token and store it somewhere safe.", "please-provide-a-password": "Please provide a password...", "please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor", "please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation", @@ -268,6 +303,7 @@ "please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.", "please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.", "please-provide-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.", + "please-provide-the-required-information-to-create-a-new-scanstation": "Please provide the required information to create a new scanstation", "please-request-a-new-reset-mail": "Please request a new reset mail...", "privacy": "Privacy", "privacy-loading": "Privacy loading...", @@ -297,6 +333,8 @@ "scans": "Scans", "scans-are-being-loaded": "Scans are being loaded", "scanstation": "Scanstation", + "scanstation-added": "Scanstation added", + "scanstation-is-being-added": "Adding scanstation...", "scanstations": "Scanstations", "scanstations-are-being-loaded": "Loading scanstations...", "search-for-an-organization-by-name-or-id": "Search for an organization (by name or id)", @@ -306,6 +344,7 @@ "search-for-runner-by-name-or-id": "Search for runner (by name or id)", "select-all": "select all", "select-language": "Select language", + "selfservice-registration": "Selfservice registration", "send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services", "set-the-user-active-inactive": "set the user active/ inactive", "settings": "Settings", @@ -323,6 +362,8 @@ "teams-are-being-loaded": "teams are being loaded...", "the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "the provided phone number is invalid.please enter a valid international number...", "the-scans-distance-must-be-greater-than-0m": "The scan's distance must be greater than 0m", + "the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again": "The scanstation api token will only get displayed once - you won't be able to change or view it again!", + "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", @@ -332,8 +373,10 @@ "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", @@ -347,12 +390,14 @@ "track-name": "Track name", "track-name-must-not-be-empty": "Track name must not be empty", "tracks": "Tracks", + "update-card": "Update Card", "update-password": "Update password", "updated-contact": "Updated contact!", "updated-donor": "updated donor", "updated-organization": "updated organization", "updated-scan": "updated scan", "updateing-group": "updateing group...", + "updating-card": "Updating card", "updating-organization": "updating organization", "updating-permissions": "updating permissions...", "updating-runner": "Updating runner...", @@ -374,7 +419,10 @@ "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-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" } \ No newline at end of file
- {$_('application_name')} -
- {$_('password-reset-failed')} -
- {$_('please-request-a-new-reset-mail')} -
+ {$_('application_name')} +
+ {$_('password-reset-failed')} +
+ {$_('please-request-a-new-reset-mail')} +
+ {$_('just-enter-how-many-you-want-and-the-system-will-create-them')} +
+ {$_('you-can-provide-a-runner-but-you-dont-have-to')} + {$_('if-you-want-to-create-multiple-blanco-cards-try-the-add-bulk-button')} +
+ {$_('you-can-provide-a-runner-but-you-dont-have-to')} +
+ { + 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} +
+ + {$_('there-are-no-cards-yet')} + {$_('add-your-first-card')} +
{$_('loading-cards')}
{$_('this-might-take-a-moment')}
+ {#if editable.registrationKey} + {registrationLink} + {:else} + {$_('you-have-to-save-your-changes-to-generate-a-link')} + {/if} +
+ {$_('click-to-copy-the-link-into-your-clipboard')} +
{$_('runners-are-being-loaded')}
{$_('the-scanstations-api-token-will-only-get-displayed-once-you-wont-be-able-to-change-or-view-it-again')} @@ -86,7 +88,7 @@
{$_('click-to-copy-token-to-clipboard')}
+ {$_('click-to-copy-token-to-clipboard')} +
- {$_('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')} +