Compare commits

...

19 Commits

Author SHA1 Message Date
c842c203e2 🚀RELEASE v1.3.1
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 18:00:58 +02:00
5bcfc8db75 More filtering 2023-04-19 18:00:41 +02:00
27b4dde755 feat(donors): Added name and address filtering 2023-04-19 18:00:16 +02:00
91ab199769 feat(donations): Donation table filtering 2023-04-19 17:53:24 +02:00
e75be49be4 🚀RELEASE v1.3.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 17:41:40 +02:00
505fb8cb08 feat(donations): Implemented donation deletion via confirm modal 2023-04-19 17:41:21 +02:00
e5c9265588 feat(donations): Implemented add donation payment via datatable refresh 2023-04-19 17:34:34 +02:00
02003ec80e feat(donations): Donations reactive create and load into datatable 2023-04-19 17:21:24 +02:00
133470b6f2 feat(donationsoverview): Switched donations overview to datatable 2023-04-19 17:12:04 +02:00
4a6230c439 Merge branch 'dev' of git.odit.services:lfk/frontend into dev
Some checks failed
continuous-integration/drone/push Build is failing
2023-04-19 16:56:23 +02:00
fdc7d80bbf 🚀RELEASE v1.2.0 2023-04-19 16:56:09 +02:00
352551e168 feat(donorsoverview): Dynamicly add newly generated donors 2023-04-19 16:55:14 +02:00
7aec050419 feat(donorsoverview): Implemented delete confirmation with datatable 2023-04-19 16:49:54 +02:00
4289034436 new license file version [CI SKIP] 2023-04-19 14:45:02 +00:00
8f8858f100 feat(DonationsOverview): i18n loading text
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 16:44:39 +02:00
d98fb0d5b2 feat(donoroverview): Added datatable formatters 2023-04-19 16:39:30 +02:00
5014bf5bc5 feat(donors): Load donors paginated 2023-04-19 16:23:00 +02:00
0708cabc75 🚀RELEASE v1.1.0
Some checks failed
continuous-integration/drone/push Build is failing
2023-04-19 16:05:21 +02:00
4fcb26cf93 feat(dashboard): Updated stats icons 2023-04-19 16:04:02 +02:00
23 changed files with 2355 additions and 1852 deletions

View File

@@ -2,8 +2,53 @@
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.
#### [1.0.0](https://git.odit.services/lfk/frontend/compare/0.19.0...1.0.0) #### [1.3.1](https://git.odit.services/lfk/frontend/compare/1.3.0...1.3.1)
- feat(donations): Donation table filtering [`91ab199`](https://git.odit.services/lfk/frontend/commit/91ab199769c9f4f8051c74ad43a701db321f3995)
- feat(donors): Added name and address filtering [`27b4dde`](https://git.odit.services/lfk/frontend/commit/27b4dde7551995c9d7e8ca33a9bd97d429a35801)
- More filtering [`5bcfc8d`](https://git.odit.services/lfk/frontend/commit/5bcfc8db752fce96e9f523d14cefff1a4f675661)
#### [1.3.0](https://git.odit.services/lfk/frontend/compare/1.2.0...1.3.0)
> 19 April 2023
- feat(donations): Implemented donation deletion via confirm modal [`505fb8c`](https://git.odit.services/lfk/frontend/commit/505fb8cb08b81a7dcb08561bdda0f6464f140d3e)
- 🚀RELEASE v1.3.0 [`e75be49`](https://git.odit.services/lfk/frontend/commit/e75be49be42c3d5581e2204bfa064bfa3778c1b6)
- feat(donationsoverview): Switched donations overview to datatable [`133470b`](https://git.odit.services/lfk/frontend/commit/133470b6f2a63ec087f27c98ef260648a8672e5f)
- feat(donations): Implemented add donation payment via datatable refresh [`e5c9265`](https://git.odit.services/lfk/frontend/commit/e5c92655886ad9a6fcd7565fadd7955c477c3595)
- feat(donations): Donations reactive create and load into datatable [`02003ec`](https://git.odit.services/lfk/frontend/commit/02003ec80efc16aabd126710a6eeac18df43f841)
- feat(DonationsOverview): i18n loading text [`8f8858f`](https://git.odit.services/lfk/frontend/commit/8f8858f10071ddf9988d0ec0e3c4a891db24a102)
- new license file version [CI SKIP] [`4289034`](https://git.odit.services/lfk/frontend/commit/4289034436869750205a946247e7ab5f9892fe98)
#### [1.2.0](https://git.odit.services/lfk/frontend/compare/1.1.0...1.2.0)
> 19 April 2023
- feat(donoroverview): Added datatable formatters [`d98fb0d`](https://git.odit.services/lfk/frontend/commit/d98fb0d5b288c987a45ccbf2bb026ccaab539a71)
- 🚀RELEASE v1.2.0 [`fdc7d80`](https://git.odit.services/lfk/frontend/commit/fdc7d80bbf9bd698128e9ec4f91fa813499777a9)
- feat(donors): Load donors paginated [`5014bf5`](https://git.odit.services/lfk/frontend/commit/5014bf5bc5873cfe4ae04d71b4aff12b257dd2e3)
- feat(donorsoverview): Dynamicly add newly generated donors [`352551e`](https://git.odit.services/lfk/frontend/commit/352551e168b5dced5e7353e82655908d82d28af0)
- feat(donorsoverview): Implemented delete confirmation with datatable [`7aec050`](https://git.odit.services/lfk/frontend/commit/7aec050419f6f1bf853c3e1bc655b01725ed3b65)
#### [1.1.0](https://git.odit.services/lfk/frontend/compare/1.0.0...1.1.0)
> 19 April 2023
- 🚀RELEASE v1.1.0 [`0708cab`](https://git.odit.services/lfk/frontend/commit/0708cabc75e63a876e54a0b343318f8d934ae319)
- feat(dashboar): Added total donors to overview [`e0b6148`](https://git.odit.services/lfk/frontend/commit/e0b61486b089aa1e611ef3569b1521fc331ec0e4)
- feat(dashboard): Updated stats icons [`4fcb26c`](https://git.odit.services/lfk/frontend/commit/4fcb26cf9371e27e5d7e474b3558ef354e9114c0)
- feat(dashboard): Added average sponsoring [`269def2`](https://git.odit.services/lfk/frontend/commit/269def20d114ededaba3153bbd50ec2ddd70e1c6)
- feat(dashboard): Added total donations [`7b2b598`](https://git.odit.services/lfk/frontend/commit/7b2b59858839b98370af6fb1e6028ba0a1639186)
- feat(dashboard): Added average distance [`b8de9e0`](https://git.odit.services/lfk/frontend/commit/b8de9e0e427b3a8b56e6354ad7168ae12c7cce85)
- Lockfile [`3f86f74`](https://git.odit.services/lfk/frontend/commit/3f86f7412ffc4bc27328ad1f7d3c3118546e7e29)
- Bumped client [`6454d96`](https://git.odit.services/lfk/frontend/commit/6454d960de3f9f5ea86679f157b3b7e7cffde74d)
- new license file version [CI SKIP] [`2a64094`](https://git.odit.services/lfk/frontend/commit/2a640940062765a470387103a72ed14a2411d97b)
### [1.0.0](https://git.odit.services/lfk/frontend/compare/0.19.0...1.0.0)
> 19 April 2023
- 🚀RELEASE v1.0.0 [`8da7578`](https://git.odit.services/lfk/frontend/commit/8da7578a0a46a3e97d8c870e29399f6e8821c9fa)
- Merge pull request 'feature/175-request_pagination' (#176) from feature/175-request_pagination into dev [`e9ce964`](https://git.odit.services/lfk/frontend/commit/e9ce9644ff03f981cec6e9ad56aa5fdf0ff71ef4) - Merge pull request 'feature/175-request_pagination' (#176) from feature/175-request_pagination into dev [`e9ce964`](https://git.odit.services/lfk/frontend/commit/e9ce9644ff03f981cec6e9ad56aa5fdf0ff71ef4)
- Donation paginated loading [`ccf8656`](https://git.odit.services/lfk/frontend/commit/ccf865687b34016931a702c0a9b98a0a18e2b03a) - Donation paginated loading [`ccf8656`](https://git.odit.services/lfk/frontend/commit/ccf865687b34016931a702c0a9b98a0a18e2b03a)
- Paginated scan loading [`cac34db`](https://git.odit.services/lfk/frontend/commit/cac34db1fd3bf5dc7c7be64b3a76ca4c8c77938d) - Paginated scan loading [`cac34db`](https://git.odit.services/lfk/frontend/commit/cac34db1fd3bf5dc7c7be64b3a76ca4c8c77938d)

View File

@@ -13,7 +13,7 @@
</head> </head>
<body> <body>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-1.0.0-RELEASE_INFO</span> <span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-1.3.1-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 type="module" src="/src/main.js"></script> <script type="module" src="/src/main.js"></script>

View File

@@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-frontend", "name": "@odit/lfk-frontend",
"version": "1.0.0", "version": "1.3.1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"i18n-order": "node order.js", "i18n-order": "node order.js",

File diff suppressed because one or more lines are too long

View File

@@ -35,7 +35,9 @@
<p class="text-sm">{$_("this-might-take-a-moment")}</p> <p class="text-sm">{$_("this-might-take-a-moment")}</p>
</div> </div>
{:then stats} {:then stats}
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 2xl:grid-cols-6 gap-4"> <div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 2xl:grid-cols-6 gap-4"
>
<StatCard <StatCard
title={$_("runners")} title={$_("runners")}
value={stats.total_runners} value={stats.total_runners}
@@ -59,18 +61,16 @@
href="/scans/" href="/scans/"
> >
<svg <svg
stroke="currentColor"
fill="currentColor" fill="currentColor"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
size="24"
class="stroke-current text-grey-500"
height="24"
width="24" width="24"
height="24"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
><polyline points="22 12 18 12 15 21 9 3 6 12 2 12" /></svg viewBox="0 0 24 24"
><path fill="none" d="M0 0h24v24H0z" />
<path
fill="currentColor"
d="M2 4h2v16H2V4zm4 0h1v16H6V4zm2 0h2v16H8V4zm3 0h2v16h-2V4zm3 0h2v16h-2V4zm3 0h1v16h-1V4zm2 0h3v16h-3V4z"
/></svg
> >
</StatCard> </StatCard>
<StatCard <StatCard
@@ -79,18 +79,15 @@
href="/donors/" href="/donors/"
> >
<svg <svg
stroke="currentColor"
fill="currentColor" fill="currentColor"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
size="24"
class="stroke-current text-grey-500"
height="24"
width="24"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
><polyline points="22 12 18 12 15 21 9 3 6 12 2 12" /></svg viewBox="0 0 24 24"
width="24"
height="24"
><path fill="none" d="M0 0h24v24H0z" />
<path
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
> >
</StatCard> </StatCard>
<StatCard <StatCard
@@ -99,18 +96,15 @@
href="/donations/" href="/donations/"
> >
<svg <svg
stroke="currentColor"
fill="currentColor" fill="currentColor"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
size="24"
class="stroke-current text-grey-500"
height="24"
width="24"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
><polyline points="22 12 18 12 15 21 9 3 6 12 2 12" /></svg viewBox="0 0 24 24"
width="24"
height="24"
><path fill="none" d="M0 0h24v24H0z" />
<path
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
> >
</StatCard> </StatCard>
<StatCard <StatCard
@@ -119,18 +113,15 @@
href="/donations/" href="/donations/"
> >
<svg <svg
stroke="currentColor"
fill="currentColor" fill="currentColor"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
size="24"
class="stroke-current text-grey-500"
height="24"
width="24"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
><polyline points="22 12 18 12 15 21 9 3 6 12 2 12" /></svg viewBox="0 0 24 24"
width="24"
height="24"
><path fill="none" d="M0 0h24v24H0z" />
<path
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
> >
</StatCard> </StatCard>
<StatCard <StatCard

View File

@@ -1,7 +1,7 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { clickOutside } from "../base/outsideclick"; import { clickOutside } from "../base/outsideclick";
import { import {
DonationService, DonationService,
DonorService, DonorService,
@@ -9,9 +9,10 @@
} 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"; import { is_promise } from "svelte/internal";
import { createEventDispatcher } from "svelte";
export let modal_open; export let modal_open;
export let current_donations; const dispatch = createEventDispatcher();
const getDonorLabel = (option) => const getDonorLabel = (option) =>
option.firstname + " " + (option.middlename || "") + " " + option.lastname; option.firstname + " " + (option.middlename || "") + " " + option.lastname;
const filterDonors = (label, filterText, option) => const filterDonors = (label, filterText, option) =>
@@ -59,16 +60,16 @@ import { is_promise } from "svelte/internal";
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 paidAmount: 0,
}; };
if(is_paid){ if (is_paid) {
postdata.paidAmount = amount_cent; postdata.paidAmount = amount_cent;
} }
DonationService.donationControllerPostFixed(postdata) DonationService.donationControllerPostFixed(postdata)
@@ -79,12 +80,11 @@ import { is_promise } from "svelte/internal";
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();
current_donations.push(result); dispatch("created", { donations: [result] });
current_donations = current_donations;
}) })
.catch((err) => { .catch((err) => {
// //
@@ -108,12 +108,11 @@ import { is_promise } from "svelte/internal";
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();
current_donations.push(result); dispatch("created", { donations: [result] });
current_donations = current_donations;
}) })
.catch((err) => { .catch((err) => {
// //
@@ -128,6 +127,207 @@ import { is_promise } from "svelte/internal";
} }
</script> </script>
{#if modal_open}
<div
class="fixed z-10 inset-0 overflow-y-auto"
use:clickOutside
on:click_outside={() => {
modal_open = false;
}}
>
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
>
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop"
/>
</div>
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span
>
<div
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline"
>
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"
>
<svg
class="h-6 w-6 text-blue-600"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
><path fill="none" d="M0 0h24v24H0z" />
<path
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
>
</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">
{#if is_fixed}
{$_("create-a-new-fixed-donation")}
{:else}{$_("create-a-new-distance-donation")}{/if}
</h3>
<label class="content-center align-middle object-center">
<span class="ml-2 text-base" class:text-gray-300={is_fixed}
>{$_("distance-donation")}</span
>
<input
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"
bind:checked={is_fixed}
/>
<span class="ml-2 text-base" class:text-gray-300={!is_fixed}
>{$_("fixed-donation")}</span
>
</label>
<div class="mt-2 mb-6">
<p class="text-sm text-gray-500">
{$_(
"please-provide-the-nessecary-information-to-create-a-new-donation"
)}
</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"
>{$_("donor")}</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) =>
filterDonors(label, filterText, option)}
items={donors}
showChevron={true}
placeholder={$_("search-for-donor-name-or-id")}
noOptionsMessage={$_("no-donors-found")}
on:select={(selectedValue) =>
(donor = selectedValue.detail.value.id)}
on:clear={() => (donors = null)}
/>
</div>
{#if !is_fixed}
<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) =>
filterDonors(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>
{/if}
<div class="col-span-6">
<label
for="donation_amount_eur"
class="block text-sm font-medium text-gray-700"
>
{#if !is_fixed}
{$_("amount-per-kilometer")}
{:else}{$_("donation-amount")}{/if}</label
>
<div class="mt-1 flex rounded-md shadow-sm">
<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={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 border-gray-300 border bg-gray-50 text-gray-500 p-2"
placeholder="2.00"
/>
<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_amount_valid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
>
{$_("donation-amount-must-be-greater-that-0-00eur")}
</span>
{/if}
</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 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}
<style> <style>
.toggle:before { .toggle:before {
content: ""; content: "";
@@ -152,173 +352,3 @@ import { is_promise } from "svelte/internal";
left: 1.25rem; left: 1.25rem;
} }
</style> </style>
{#if modal_open}
<div
class="fixed z-10 inset-0 overflow-y-auto"
use:clickOutside
on:click_outside={() => {
modal_open = false;
}}>
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop" />
</div>
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span>
<div
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
<svg
class="h-6 w-6 text-blue-600"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"><path fill="none" d="M0 0h24v24H0z" />
<path
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>
</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">
{#if is_fixed}
{$_('create-a-new-fixed-donation')}
{:else}{$_('create-a-new-distance-donation')}{/if}
</h3>
<label class="content-center align-middle object-center">
<span
class="ml-2 text-base"
class:text-gray-300={is_fixed}>{$_('distance-donation')}</span>
<input
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"
bind:checked={is_fixed} />
<span
class="ml-2 text-base "
class:text-gray-300={!is_fixed}>{$_('fixed-donation')}</span>
</label>
<div class="mt-2 mb-6">
<p class="text-sm text-gray-500">
{$_('please-provide-the-nessecary-information-to-create-a-new-donation')}
</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">{$_('donor')}</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) => filterDonors(label, filterText, option)}
items={donors}
showChevron={true}
placeholder={$_('search-for-donor-name-or-id')}
noOptionsMessage={$_('no-donors-found')}
on:select={(selectedValue) => (donor = selectedValue.detail.value.id)}
on:clear={() => (donors = null)} />
</div>
{#if !is_fixed}
<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) => filterDonors(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>
{/if}
<div class="col-span-6">
<label
for="donation_amount_eur"
class="block text-sm font-medium text-gray-700">
{#if !is_fixed}
{$_('amount-per-kilometer')}
{:else}{$_('donation-amount')}{/if}</label>
<div class="mt-1 flex rounded-md shadow-sm">
<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={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 border-gray-300 border bg-gray-50 text-gray-500 p-2"
placeholder="2.00" />
<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_amount_valid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
{$_('donation-amount-must-be-greater-that-0-00eur')}
</span>
{/if}
</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 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}

View File

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

View File

@@ -0,0 +1,122 @@
<script>
import { _ } from "svelte-i18n";
import { clickOutside } from "../base/outsideclick";
import { createEventDispatcher, onMount } from "svelte";
export let modal_open;
export let delete_donation = {
id: 0,
runner: {
firstname: "",
lastname: "",
},
donor: {
firstname: "",
lastname: "",
},
};
const dispatch = createEventDispatcher();
onMount(() => {
document.onkeydown = (e) => {
e = e || window.event;
if (e.key === "Escape") {
modal_open = false;
}
if (e.keyCode === 13) {
if (createbtnenabled === true) {
createbtnenabled = false;
submit();
}
}
};
});
async function submit() {
dispatch("delete", { id: delete_donation.id });
modal_open = false;
}
</script>
{#if modal_open}
<div
class="fixed z-10 inset-0 overflow-y-auto"
use:clickOutside
on:click_outside={() => {
modal_open = false;
}}
>
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
>
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop"
/>
</div>
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span
>
<div
class="inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline"
>
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"
>
<svg
class="h-6 w-6 text-blue-600"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
><path fill="none" d="M0 0h24v24H0z" />
<path
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
>
</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">
{$_("confirm-delete")}
</h3>
<div class="mt-2 mb-6">
<p class="text-sm text-gray-500">
{$_("please-confirm-the-deletion-of-donation")}
</p>
</div>
<div class="w-full">
<span class="inline-block"
><b>{$_("donor")}</b>: {delete_donation.donor.firstname}
{delete_donation.donor.lastname}</span
>
</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={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"
>
{$_("delete")}
</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}

View File

@@ -0,0 +1,18 @@
<script>
import { _ } from "svelte-i18n";
export let donor;
</script>
{#if !donor || donor.firstname == 0}
{$_("donor-has-no-associated-donations")}
{:else}
<div class="flex items-center">
<a
href="../donors/{donor.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>{donor.firstname}
{#if donor.middlename}{donor.middlename}{/if}
{donor.lastname}</a
>
</div>
{/if}

View File

@@ -0,0 +1,18 @@
<script>
import { _ } from "svelte-i18n";
export let runner;
</script>
{#if !runner || runner.firstname == 0}
{$_("fixed-donation")}
{:else}
<div class="text-sm font-medium text-gray-900">
<a
href="../runners/{runner.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>{runner.firstname}
{#if runner.middlename}{runner.middlename}{/if}
{runner.lastname}</a
>
</div>
{/if}

View File

@@ -0,0 +1,16 @@
<script>
import { _ } from "svelte-i18n";
export let status;
</script>
{#if 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}

View File

@@ -0,0 +1,21 @@
<script>
import { _ } from "svelte-i18n";
import TableActions from "../shared/TableActions.svelte";
export let detailsLink;
export let detailsAction;
export let deleteEnabled;
export let deleteAction;
export let paymentAction;
</script>
<button
on:click={paymentAction}
class="text-[#025a21] hover:text-green-900 mr-4">{$_("enter-payment")}</button
>
<TableActions
bind:detailsAction
bind:detailsLink
bind:deleteAction
bind:deleteEnabled
/>

View File

@@ -5,25 +5,33 @@
import DonationsOverview from "./DonationsOverview.svelte"; import DonationsOverview from "./DonationsOverview.svelte";
$: current_donations = []; $: current_donations = [];
export let modal_open = false; export let modal_open = false;
let addDonations;
</script> </script>
<section class="container p-5"> <section class="container p-5">
<span class="mb-1 text-3xl font-extrabold leading-tight"> <span class="mb-1 text-3xl font-extrabold leading-tight">
{$_('donations')} {$_("donations")}
{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:CREATE')} {#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:CREATE")}
<button <button
on:click={() => { on:click={() => {
modal_open = true; modal_open = true;
}} }}
type="button" type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"> class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"
{$_('add-donation')} >
{$_("add-donation")}
</button> </button>
{/if} {/if}
</span> </span>
<DonationsOverview bind:current_donations /> <DonationsOverview bind:current_donations bind:addDonations />
</section> </section>
{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:CREATE')} {#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:CREATE")}
<AddDonationModal bind:current_donations bind:modal_open /> <AddDonationModal
on:created={(event) => {
console.log(event)
addDonations(event.detail.donations);
}}
bind:modal_open
/>
{/if} {/if}

View File

@@ -1,31 +1,171 @@
<script> <script>
import { getLocaleFromNavigator, _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { DonationService, DonorService } from "@odit/lfk-client-js"; import { DonationService } from "@odit/lfk-client-js";
import store from "../../store"; import store from "../../store";
import Toastify from "toastify-js";
import DonationsEmptyState from "./DonationsEmptyState.svelte"; import DonationsEmptyState from "./DonationsEmptyState.svelte";
import AddDonationPaymentModal from "./AddDonationPaymentModal.svelte"; import AddDonationPaymentModal from "./AddDonationPaymentModal.svelte";
import { onMount } from "svelte"; import { onMount } from "svelte";
import {
createSvelteTable,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
renderComponent,
} from "@tanstack/svelte-table";
import { writable } from "svelte/store";
import TableBottom from "../shared/TableBottom.svelte";
import InputElement from "../shared/InputElement.svelte";
import TableHeader from "../shared/TableHeader.svelte";
import DonationDonor from "./DonationDonor.svelte";
import DonationRunner from "./DonationRunner.svelte";
import DonationStatus from "./DonationStatus.svelte";
import DonationTableAction from "./DonationTableAction.svelte";
import DeleteDonationModal from "./DeleteDonationModal.svelte";
import { donationDonorFilter, donationRunnerFilter } from "../shared/tablefilters";
$: searchvalue = ""; $: searchvalue = "";
$: active_deletes = []; $: active_deletes = [];
$: active_edits = [];
$: selectedDonations =
$table?.getSelectedRowModel().rows.map((row) => row.original) || [];
$: selected =
$table?.getSelectedRowModel().rows.map((row) => row.index) || [];
$: dataLoaded = false; $: dataLoaded = false;
export let current_donations = [];
export let payment_modal_open = false;
export let editable = {};
export let original_data = {};
export let paid_amount_input = 0;
function should_display_based_on_id(id) { export let current_donations = [];
if (searchvalue.toString().slice(-1) === "*") { export const addDonations = (donations) => {
return id.toString().startsWith(searchvalue.replace("*", "")); current_donations = current_donations.concat(...donations);
} options.update((options) => ({
return id.toString() === searchvalue; ...options,
} data: current_donations,
function open_payment_modal(donation) { }));
editable = Object.assign({}, donation); };
original_data = Object.assign({}, donation);
paid_amount_input = (donation.paidAmount / 100).toFixed(2); //Section table
payment_modal_open = true; const columns = [
{
accessorKey: "id",
header: () => "id",
filterFn: `equalsString`,
},
{
accessorKey: "donor",
header: () => $_("donor"),
cell: (info) => {
return renderComponent(DonationDonor, { donor: info.getValue() });
},
filterFn: `donor`,
},
{
accessorKey: "runner",
header: () => $_("runner"),
cell: (info) => {
return renderComponent(DonationRunner, { runner: info.getValue() });
},
filterFn: `runner`,
},
{
accessorKey: "amountPerDistance",
header: () => $_("amount-per-kilometer"),
cell: (info) => {
if (!info.getValue()) {
return $_("fixed-donation");
}
return `${(info.getValue() / 100)
.toFixed(2)
.toLocaleString("de-DE", { valute: "EUR" })} €`;
},
enableColumnFilter: false,
},
{
accessorKey: "amount",
header: () => $_("donation-amount"),
cell: (info) => {
return `${(info.getValue() / 100)
.toFixed(2)
.toLocaleString("de-DE", { valute: "EUR" })} €`;
},
enableColumnFilter: false,
},
{
accessorKey: "paidAmount",
header: () => $_("total-paid-amount"),
cell: (info) => {
return `${(info.getValue() / 100)
.toFixed(2)
.toLocaleString("de-DE", { valute: "EUR" })} €`;
},
enableColumnFilter: false,
},
{
accessorKey: "status",
header: () => $_("status"),
cell: (info) => {
return renderComponent(DonationStatus, { status: info.getValue() });
},
enableColumnFilter: false,
},
{
accessorKey: "actions",
header: () => $_("action"),
cell: (info) => {
return renderComponent(DonationTableAction, {
detailsLink: `./${info.row.original.id}`,
deleteAction: () => {
active_deletes = current_donations.filter(
(r) => r.id == info.row.original.id
);
},
paymentAction: () => {
active_edits = current_donations.filter(
(r) => r.id == info.row.original.id
);
},
deleteEnabled:
store.state.jwtinfo.userdetails.permissions.includes(
"DONATION:DELETE"
),
});
},
enableColumnFilter: false,
enableSorting: false,
},
];
const options = writable({
data: [],
columns: columns,
initialState: {
pagination: {
pageSize: 50,
},
},
filterFns: {
donor: donationDonorFilter,
runner: donationRunnerFilter,
},
enableRowSelection: true,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
});
const table = createSvelteTable(options);
async function deleteDonation(delete_donation_id) {
await DonationService.donationControllerRemove(delete_donation_id, true);
current_donations = current_donations.filter(
(r) => r.id !== delete_donation_id
);
options.update((options) => ({
...options,
data: current_donations,
}));
Toastify({
text: $_("donation-deleted"),
duration: 3500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
} }
onMount(async () => { onMount(async () => {
@@ -40,6 +180,10 @@
} }
current_donations = current_donations.concat(...donations); current_donations = current_donations.concat(...donations);
options.update((options) => ({
...options,
data: current_donations,
}));
dataLoaded = true; dataLoaded = true;
page++; page++;
@@ -49,11 +193,25 @@
</script> </script>
<AddDonationPaymentModal <AddDonationPaymentModal
bind:current_donations original_data={active_edits[0]}
bind:original_data payment_modal_open={active_edits.length > 0}
bind:editable paid_amount_input={(active_edits[0]?.paidAmount || 0) / 100}
bind:paid_amount_input on:created={(event) => {
bind:payment_modal_open current_donations[
current_donations.findIndex((d) => d.id === event.detail.donation.id)
].paidAmount = event.detail.donation.paidAmount;
options.update((options) => ({
...options,
data: current_donations,
}));
}}
/>
<DeleteDonationModal
delete_donation={active_deletes[0]}
modal_open={active_deletes.length > 0}
on:delete={(event) => {
deleteDonation(event.detail.id);
}}
/> />
{#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:GET")} {#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:GET")}
{#if !dataLoaded} {#if !dataLoaded}
@@ -61,7 +219,7 @@
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
role="alert" role="alert"
> >
<p class="font-bold">donations are being loaded</p> <p class="font-bold">{$_("donations-are-being-loaded")}</p>
<p class="text-sm">{$_("this-might-take-a-moment")}</p> <p class="text-sm">{$_("this-might-take-a-moment")}</p>
</div> </div>
{:else if current_donations.length === 0} {:else if current_donations.length === 0}
@@ -77,197 +235,50 @@
<div <div
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"
> >
<table class="divide-y divide-gray-200 w-full"> <table class="w-full">
<thead class="bg-gray-50"> <thead>
<tr> {#each $table.getHeaderGroups() as headerGroup}
<th <tr class="select-none">
scope="col" <th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" <InputElement
> type="checkbox"
{$_("donor")} checked={$table.getIsAllRowsSelected()}
</th> indeterminate={$table.getIsSomeRowsSelected()}
<th on:change={() => $table.toggleAllRowsSelected()}
scope="col" />
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" </th>
> {#each headerGroup.headers as header}
{$_("runner")} <TableHeader {header} />
</th> {/each}
<th </tr>
scope="col" {/each}
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
{$_("amount-per-kilometer")}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
{$_("donation-amount")}
</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">
<span class="sr-only">{$_("action")}</span>
</th>
</tr>
</thead> </thead>
<tbody class="divide-y divide-gray-200"> <tbody>
{#each current_donations as donation} {#each $table.getRowModel().rows as row}
{#if donation.donor.firstname <tr>
.toLowerCase() <td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
.includes(searchvalue.toLowerCase()) || donation.donor.lastname <InputElement
.toLowerCase() type="checkbox"
.includes(searchvalue.toLowerCase()) || donation.runner?.firstname checked={row.getIsSelected()}
.toLowerCase() on:change={() => row.toggleSelected()}
.includes(searchvalue.toLowerCase()) || donation.runner?.lastname />
.toLowerCase() </td>
.includes(searchvalue.toLowerCase()) || should_display_based_on_id(donation.id)} {#each row.getVisibleCells() as cell}
<tr data-rowid="donation_{donation.id}"> <td>
<td class="px-6 py-4 whitespace-nowrap"> <svelte:component
<div class="flex items-center"> this={flexRender(
<a cell.column.columnDef.cell,
href="../donors/{donation.donor.id}" cell.getContext()
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800" )}
>{donation.donor.firstname} />
{donation.donor.middlename || ""}
{donation.donor.lastname}</a
>
</div>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap"> {/each}
{#if donation.runner} </tr>
<div class="text-sm font-medium text-gray-900">
<a
href="../runners/{donation.runner.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>{donation.runner.firstname}
{donation.runner.middlename || ""}
{donation.runner.lastname}</a
>
</div>
{:else}
<div class="text-sm font-medium text-gray-900">
{$_("fixed-donation")}
</div>
{/if}
</td>
<td class="px-6 py-4 whitespace-nowrap">
{#if donation.amountPerDistance}
<div class="text-sm font-medium text-gray-900">
{(donation.amountPerDistance / 100)
.toFixed(2)
.toLocaleString("de-DE", { valute: "EUR" })}
</div>
{:else}
<div class="text-sm font-medium text-gray-900">
{$_("fixed-donation")}
</div>
{/if}
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-gray-900">
{(donation.amount / 100)
.toFixed(2)
.toLocaleString("de-DE", { valute: "EUR" })}
</div>
</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}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
>
<button
on:click={() => {
active_deletes[donation.id] = false;
}}
tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer"
>{$_("cancel-delete")}</button
>
<button
on:click={() => {
DonationService.donationControllerRemove(
donation.id,
false
).then((resp) => {
current_donations = current_donations.filter(
(obj) => obj.id !== donation.id
);
Toastify({
text: $_("donation-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_payment_modal(donation);
}}
class="text-[#025a21] hover:text-green-900 mr-4"
>{$_("enter-payment")}</button
>
<a
href="./{donation.id}"
class="text-indigo-600 hover:text-indigo-900"
>{$_("details")}</a
>
{#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:DELETE")}
<button
on:click={() => {
active_deletes[donation.id] = true;
}}
tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer"
>{$_("delete")}</button
>
{/if}
</td>
{/if}
</tr>
{/if}
{/each} {/each}
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="h-2" />
<TableBottom {table} {selected} />
{/if} {/if}
{/if} {/if}

View File

@@ -1,15 +1,13 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { clickOutside } from "../base/outsideclick"; import { clickOutside } from "../base/outsideclick";
import { import { DonorService } from "@odit/lfk-client-js";
DonorService
} from "@odit/lfk-client-js";
import isEmail from "validator/es/lib/isEmail"; import isEmail from "validator/es/lib/isEmail";
import isMobilePhone from "validator/es/lib/isMobilePhone"; import isMobilePhone from "validator/es/lib/isMobilePhone";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import { createEventDispatcher } from "svelte";
export let modal_open; export let modal_open;
export let current_donors;
let firstname_input; let firstname_input;
let lastname_input; let lastname_input;
let middlename_input; let middlename_input;
@@ -19,6 +17,7 @@
let address_input2; let address_input2;
let address_zipcode; let address_zipcode;
let address_city; let address_city;
const dispatch = createEventDispatcher();
function focus(el) { function focus(el) {
el.focus(); el.focus();
} }
@@ -75,7 +74,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: $_('donor-is-being-added'), text: $_("donor-is-being-added"),
duration: -1, duration: -1,
}).showToast(); }).showToast();
let address = {}; let address = {};
@@ -92,7 +91,7 @@
firstname: firstname_input_value, firstname: firstname_input_value,
lastname: lastname_input_value, lastname: lastname_input_value,
address, address,
receiptNeeded: address_checked receiptNeeded: address_checked,
}; };
if (middlename_input_value) { if (middlename_input_value) {
postdata.middlename = middlename_input_value; postdata.middlename = middlename_input_value;
@@ -112,12 +111,11 @@
modal_open = false; modal_open = false;
// //
Toastify({ Toastify({
text: $_('donor-added'), text: $_("donor-added"),
duration: 500, duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
current_donors.push(result); dispatch("created", { donors: [result] });
current_donors = current_donors;
}) })
.catch((err) => { .catch((err) => {
// //
@@ -134,58 +132,70 @@
{#if modal_open} {#if modal_open}
<div <div
class="fixed z-10 inset-0 overflow-y-auto" class="fixed z-10 inset-0 overflow-y-auto"
use:clickOutside use:clickOutside
on:click_outside={() => { on:click_outside={() => {
modal_open = false; modal_open = false;
}}> }}
>
<div <div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
>
<div class="fixed inset-0 transition-opacity" aria-hidden="true"> <div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div <div
class="absolute inset-0 bg-gray-500 opacity-75" class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop" /> data-id="modal_backdrop"
/>
</div> </div>
<span <span
class="hidden sm:inline-block sm:align-middle sm:h-screen" class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span> aria-hidden="true">&#8203;</span
>
<div <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" 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" role="dialog"
aria-modal="true" aria-modal="true"
aria-labelledby="modal-headline"> aria-labelledby="modal-headline"
>
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4"> <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start"> <div class="sm:flex sm:items-start">
<div <div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"> class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"
>
<svg <svg
class="h-6 w-6 text-blue-600" class="h-6 w-6 text-blue-600"
fill="currentColor" fill="currentColor"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width="24" width="24"
height="24"><path fill="none" d="M0 0h24v24H0z" /> height="24"
><path fill="none" d="M0 0h24v24H0z" />
<path <path
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> 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
>
</div> </div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left"> <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900"> <h3 class="text-lg leading-6 font-medium text-gray-900">
{$_('create-a-new-donor')} {$_("create-a-new-donor")}
</h3> </h3>
<div class="mt-2 mb-6"> <div class="mt-2 mb-6">
<p class="text-sm text-gray-500"> <p class="text-sm text-gray-500">
{$_('please-provide-the-nessecary-information-to-add-a-new-donor')} {$_(
"please-provide-the-nessecary-information-to-add-a-new-donor"
)}
</p> </p>
</div> </div>
<div class="grid grid-cols-6 gap-6"> <div class="grid grid-cols-6 gap-6">
<div class="col-span-6"> <div class="col-span-6">
<label <label
for="firstname" for="firstname"
class="block text-sm font-medium text-gray-700">{$_('first-name')}</label> class="block text-sm font-medium text-gray-700"
>{$_("first-name")}</label
>
<input <input
use:focus use:focus
autocomplete="off" autocomplete="off"
placeholder={$_('first-name')} placeholder={$_("first-name")}
class:border-red-500={!isFirstnameValid} class:border-red-500={!isFirstnameValid}
class:focus:border-red-500={!isFirstnameValid} class:focus:border-red-500={!isFirstnameValid}
class:focus:ring-red-500={!isFirstnameValid} class:focus:ring-red-500={!isFirstnameValid}
@@ -193,34 +203,41 @@
bind:this={firstname_input} bind:this={firstname_input}
type="text" type="text"
name="firstname" name="firstname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
/>
{#if !isFirstnameValid} {#if !isFirstnameValid}
<span <span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"> class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
{$_('first-name-is-required')} >
{$_("first-name-is-required")}
</span> </span>
{/if} {/if}
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label <label
for="trackname" for="trackname"
class="block text-sm font-medium text-gray-700">{$_('middle-name')}</label> class="block text-sm font-medium text-gray-700"
>{$_("middle-name")}</label
>
<input <input
autocomplete="off" autocomplete="off"
placeholder={$_('middle-name')} placeholder={$_("middle-name")}
bind:value={middlename_input_value} bind:value={middlename_input_value}
bind:this={middlename_input} bind:this={middlename_input}
type="text" type="text"
name="trackname" name="trackname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
/>
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label <label
for="lastname" for="lastname"
class="block text-sm font-medium text-gray-700">{$_('last-name')}</label> class="block text-sm font-medium text-gray-700"
>{$_("last-name")}</label
>
<input <input
autocomplete="off" autocomplete="off"
placeholder="{$_('last-name')}" placeholder={$_("last-name")}
class:border-red-500={!isLastnameValid} class:border-red-500={!isLastnameValid}
class:focus:border-red-500={!isLastnameValid} class:focus:border-red-500={!isLastnameValid}
class:focus:ring-red-500={!isLastnameValid} class:focus:ring-red-500={!isLastnameValid}
@@ -228,21 +245,25 @@
bind:this={lastname_input} bind:this={lastname_input}
type="text" type="text"
name="lastname" name="lastname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
/>
{#if !isLastnameValid} {#if !isLastnameValid}
<span <span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"> class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
{$_('last-name-is-required')} >
{$_("last-name-is-required")}
</span> </span>
{/if} {/if}
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label <label
for="phone" for="phone"
class="block text-sm font-medium text-gray-700">{$_('phone')}</label> class="block text-sm font-medium text-gray-700"
>{$_("phone")}</label
>
<input <input
autocomplete="off" autocomplete="off"
placeholder={$_('phone')} placeholder={$_("phone")}
class:border-red-500={!isPhoneValidOrEmpty} class:border-red-500={!isPhoneValidOrEmpty}
class:focus:border-red-500={!isPhoneValidOrEmpty} class:focus:border-red-500={!isPhoneValidOrEmpty}
class:focus:ring-red-500={!isPhoneValidOrEmpty} class:focus:ring-red-500={!isPhoneValidOrEmpty}
@@ -250,21 +271,27 @@
bind:this={phone_input} bind:this={phone_input}
type="tel" type="tel"
name="phone" name="phone"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
/>
{#if !isPhoneValidOrEmpty} {#if !isPhoneValidOrEmpty}
<span <span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"> class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
{@html $_('the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number')} >
{@html $_(
"the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number"
)}
</span> </span>
{/if} {/if}
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label <label
for="email" for="email"
class="block text-sm font-medium text-gray-700">{$_('e-mail-adress')}</label> class="block text-sm font-medium text-gray-700"
>{$_("e-mail-adress")}</label
>
<input <input
autocomplete="off" autocomplete="off"
placeholder={$_('e-mail-adress')} placeholder={$_("e-mail-adress")}
class:border-red-500={!isEmailValidOrEmpty} class:border-red-500={!isEmailValidOrEmpty}
class:focus:border-red-500={!isEmailValidOrEmpty} class:focus:border-red-500={!isEmailValidOrEmpty}
class:focus:ring-red-500={!isEmailValidOrEmpty} class:focus:ring-red-500={!isEmailValidOrEmpty}
@@ -272,11 +299,13 @@
bind:this={email_input} bind:this={email_input}
type="email" type="email"
name="email" name="email"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
/>
{#if !isEmailValidOrEmpty} {#if !isEmailValidOrEmpty}
<span <span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"> class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
{$_('valid-email-is-required')} >
{$_("valid-email-is-required")}
</span> </span>
{/if} {/if}
</div> </div>
@@ -287,19 +316,22 @@
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>
<div class="ml-3 text-sm"> <div class="ml-3 text-sm">
<label <label for="comments" class="font-medium text-gray-700"
for="comments" >{$_("receipt-needed")}</label
class="font-medium text-gray-700">{$_('receipt-needed')}</label> >
</div> </div>
</div> </div>
{#if address_checked === true} {#if address_checked === true}
<div class="col-span-6"> <div class="col-span-6">
<label <label
for="address1" for="address1"
class="block text-sm font-medium text-gray-700">{$_('address')}</label> class="block text-sm font-medium text-gray-700"
>{$_("address")}</label
>
<input <input
autocomplete="off" autocomplete="off"
placeholder="Address" placeholder="Address"
@@ -310,34 +342,41 @@
bind:this={address_input1} bind:this={address_input1}
type="text" type="text"
name="address1" 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" /> 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} {#if !isAddress1Valid}
<span <span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"> class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
{$_('address-is-required')} >
{$_("address-is-required")}
</span> </span>
{/if} {/if}
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label <label
for="address2" for="address2"
class="block text-sm font-medium text-gray-700">{$_('apartment-suite-etc')}</label> class="block text-sm font-medium text-gray-700"
>{$_("apartment-suite-etc")}</label
>
<input <input
autocomplete="off" autocomplete="off"
placeholder={$_('apartment-suite-etc')} placeholder={$_("apartment-suite-etc")}
bind:value={address_input2_value} bind:value={address_input2_value}
bind:this={address_input2} bind:this={address_input2}
type="text" type="text"
name="address2" 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" /> class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"
/>
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label <label
for="zipcode" for="zipcode"
class="block text-sm font-medium text-gray-700">{$_('zip-postal-code')}</label> class="block text-sm font-medium text-gray-700"
>{$_("zip-postal-code")}</label
>
<input <input
autocomplete="off" autocomplete="off"
placeholder={$_('zip-postal-code')} placeholder={$_("zip-postal-code")}
class:border-red-500={!iszipcodevalid} class:border-red-500={!iszipcodevalid}
class:focus:border-red-500={!iszipcodevalid} class:focus:border-red-500={!iszipcodevalid}
class:focus:ring-red-500={!iszipcodevalid} class:focus:ring-red-500={!iszipcodevalid}
@@ -345,18 +384,22 @@
bind:this={address_zipcode} bind:this={address_zipcode}
type="text" type="text"
name="zipcode" 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" /> 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} {#if !iszipcodevalid}
<span <span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"> class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
{$_('valid-zipcode-postal-code-is-required')} >
{$_("valid-zipcode-postal-code-is-required")}
</span> </span>
{/if} {/if}
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label <label
for="city" for="city"
class="block text-sm font-medium text-gray-700">City</label> class="block text-sm font-medium text-gray-700"
>City</label
>
<input <input
autocomplete="off" autocomplete="off"
placeholder="City" placeholder="City"
@@ -367,11 +410,13 @@
bind:this={address_city} bind:this={address_city}
type="text" type="text"
name="city" 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" /> 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} {#if !iscityvalid}
<span <span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"> class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1"
{$_('valid-city-is-required')} >
{$_("valid-city-is-required")}
</span> </span>
{/if} {/if}
</div> </div>
@@ -386,16 +431,18 @@
class:opacity-50={!createbtnenabled} class:opacity-50={!createbtnenabled}
on:click={submit} on:click={submit}
type="button" type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"> class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"
{$_('create')} >
{$_("create")}
</button> </button>
<button <button
on:click={() => { on:click={() => {
modal_open = false; modal_open = false;
}} }}
type="button" type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"> class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
{$_('cancel')} >
{$_("cancel")}
</button> </button>
</div> </div>
</div> </div>

View File

@@ -1,7 +1,7 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { clickOutside } from "../base/outsideclick"; import { clickOutside } from "../base/outsideclick";
import { DonorService } from "@odit/lfk-client-js"; import { DonorService } from "@odit/lfk-client-js";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
@@ -13,60 +13,61 @@
dispatch("cancelDelete", { id: delete_donor.id }); dispatch("cancelDelete", { id: delete_donor.id });
} }
function deleteDonor() { function deleteDonor() {
DonorService.donorControllerRemove( dispatch("delete", { id: delete_donor.id });
delete_donor.id,
true
)
.then((resp) => {
Toastify({
text: $_('donor-deleted'),
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
location.replace("./");
})
.catch((err) => {});
} }
</script> </script>
{#if modal_open} {#if modal_open}
<div <div
class="fixed z-10 inset-0 overflow-y-auto" class="fixed z-10 inset-0 overflow-y-auto"
use:clickOutside use:clickOutside
on:click_outside={cancelDelete}> on:click_outside={cancelDelete}
>
<div <div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
>
<div class="fixed inset-0 transition-opacity" aria-hidden="true"> <div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div <div
class="absolute inset-0 bg-gray-500 opacity-75" class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop" /> data-id="modal_backdrop"
/>
</div> </div>
<span <span
class="hidden sm:inline-block sm:align-middle sm:h-screen" class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span> aria-hidden="true">&#8203;</span
>
<div <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" 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" role="dialog"
aria-modal="true" aria-modal="true"
aria-labelledby="modal-headline"> aria-labelledby="modal-headline"
>
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4"> <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start"> <div class="sm:flex sm:items-start">
<div <div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"> class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"
<svg 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="M9.33 11.5h2.17A4.5 4.5 0 0116 16H9v1h8v-1a5.58 5.58 0 00-.89-3H19a5 5 0 014.52 2.85A13.15 13.15 0 0113 21c-2.76 0-5.1-.59-7-1.63v-9.3a6.97 6.97 0 013.33 1.43zM5 19a1 1 0 01-1 1H2a1 1 0 01-1-1v-9a1 1 0 011-1h2a1 1 0 011 1v9zM18 5a3 3 0 110 6 3 3 0 010-6zm-7-3a3 3 0 110 6 3 3 0 010-6z"/></svg> >
<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="M9.33 11.5h2.17A4.5 4.5 0 0116 16H9v1h8v-1a5.58 5.58 0 00-.89-3H19a5 5 0 014.52 2.85A13.15 13.15 0 0113 21c-2.76 0-5.1-.59-7-1.63v-9.3a6.97 6.97 0 013.33 1.43zM5 19a1 1 0 01-1 1H2a1 1 0 01-1-1v-9a1 1 0 011-1h2a1 1 0 011 1v9zM18 5a3 3 0 110 6 3 3 0 010-6zm-7-3a3 3 0 110 6 3 3 0 010-6z"
/></svg
>
</div> </div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left"> <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900"> <h3 class="text-lg leading-6 font-medium text-gray-900">
{$_('attention')} {$_("attention")}
</h3> </h3>
<div class="mt-2 mb-6"> <div class="mt-2 mb-6">
<p class="text-sm text-gray-500"> <p class="text-sm text-gray-500">
{$_( {$_(
'do-you-want-to-delete-this-donor-with-all-related-donations' "do-you-want-to-delete-this-donor-with-all-related-donations"
)} )}
<br /> <br />
{$_('all-associated-donations-will-get-deleted-as-well')} {$_("all-associated-donations-will-get-deleted-as-well")}
</p> </p>
</div> </div>
</div> </div>
@@ -76,14 +77,16 @@
<button <button
on:click={deleteDonor} on:click={deleteDonor}
type="button" 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"> 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-donor-with-all-donations')} >
{$_("confirm-delete-donor-with-all-donations")}
</button> </button>
<button <button
on:click={cancelDelete} on:click={cancelDelete}
type="button" type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"> class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
{$_('cancel-keep-donor')} >
{$_("cancel-keep-donor")}
</button> </button>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,14 @@
<script>
import { _ } from "svelte-i18n";
export let address;
</script>
{#if !address || !address.address1}
{$_("no-address")}
{:else}
{address.address1}<br />
<!-- {address.address2 || ''}<br /> -->
{address.postalcode}
{address.city}
{address.country}
{/if}

View File

@@ -0,0 +1,29 @@
<script>
import { _ } from "svelte-i18n";
export let donations;
</script>
{#if !donations || donations.length == 0}
{$_('donor-has-no-associated-donations')}
{:else}
{#each donations as donation}
{#if donation.responseType === "DISTANCEDONATION"}
<a
href="../donations/{donation.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-600 text-white mr-1"
>{donation.runner.firstname}
{donation.runner.middlename || ""}
{donation.runner.lastname}</a
>
{:else}
<a
href="../donations/{d.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-700 text-white mr-1"
>{$_("fixed-donation")}:
{(d.amount / 100)
.toFixed(2)
.toLocaleString("de-DE", { valute: "EUR" })}</a
>
{/if}
{/each}
{/if}

View File

@@ -5,50 +5,73 @@
import DonorsOverview from "./DonorsOverview.svelte"; import DonorsOverview from "./DonorsOverview.svelte";
$: current_donors = []; $: current_donors = [];
export let modal_open = false; export let modal_open = false;
let addDonors;
</script> </script>
<section class="container p-5"> <section class="container p-5">
<span class="mb-1 text-3xl font-extrabold leading-tight"> <span class="mb-1 text-3xl font-extrabold leading-tight">
{$_('donors')} {$_("donors")}
{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:CREATE')} {#if store.state.jwtinfo.userdetails.permissions.includes("DONOR:CREATE")}
<button <button
on:click={() => { on:click={() => {
modal_open = true; modal_open = true;
}} }}
type="button" type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"> class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"
{$_('add-donor')} >
{$_("add-donor")}
</button> </button>
{/if} {/if}
{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')} {#if store.state.jwtinfo.userdetails.permissions.includes("DONOR:GET")}
<button <button
on:click={() => { on:click={() => {
const data = (current_donors.filter(d=>d.receiptNeeded===true)).map(function (d) { const data = current_donors
d.address.address2=d.address.address2===""?"":" "+d.address.address2; .filter((d) => d.receiptNeeded === true)
const address=`${d.address.address1}${d.address.address2}, ${d.address.postalcode} ${d.address.city}, ${d.address.country}`; .map(function (d) {
return [d.firstname,d.middlename,d.lastname,d.paidDonationAmount,address]; d.address.address2 =
}) d.address.address2 === "" ? "" : " " + d.address.address2;
let csv = `${$_('csv_import__firstname')};${$_('csv_import__middlename')};${$_('csv_import__lastname')};${$_('total_donation_amount_in_eur')};${$_('address')}\n`; const address = `${d.address.address1}${d.address.address2}, ${d.address.postalcode} ${d.address.city}, ${d.address.country}`;
data.forEach(function(row) { return [
csv += row.join(';'); 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"; csv += "\n";
}); });
let hiddenElement = document.createElement('a'); let hiddenElement = document.createElement("a");
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv); hiddenElement.href = "data:text/csv;charset=utf-8," + encodeURI(csv);
hiddenElement.target = '_blank'; hiddenElement.target = "_blank";
hiddenElement.download = `${$_('filename_sponsoringquittungsliste')}.csv`; hiddenElement.download = `${$_(
hiddenElement.click(); "filename_sponsoringquittungsliste"
hiddenElement.remove(); )}.csv`;
hiddenElement.click();
hiddenElement.remove();
}} }}
type="button" type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"> class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"
{$_('sponsoring-quittungs-liste_herunterladen')} >
{$_("sponsoring-quittungs-liste_herunterladen")}
</button> </button>
{/if} {/if}
</span> </span>
<DonorsOverview bind:current_donors /> <DonorsOverview bind:current_donors bind:addDonors />
</section> </section>
{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:CREATE')} {#if store.state.jwtinfo.userdetails.permissions.includes("DONOR:CREATE")}
<AddDonorModal bind:current_donors bind:modal_open /> <AddDonorModal
on:created={(event) => {
addDonors(event.detail.donors);
}}
bind:modal_open
/>
{/if} {/if}

View File

@@ -5,214 +5,265 @@
import DonorsEmptyState from "./DonorsEmptyState.svelte"; import DonorsEmptyState from "./DonorsEmptyState.svelte";
import ConfirmDonorDeletion from "./ConfirmDonorDeletion.svelte"; import ConfirmDonorDeletion from "./ConfirmDonorDeletion.svelte";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import TableBottom from "../shared/TableBottom.svelte";
import {
createSvelteTable,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
renderComponent,
} from "@tanstack/svelte-table";
import { writable } from "svelte/store";
import { onMount } from "svelte";
import InputElement from "../shared/InputElement.svelte";
import TableHeader from "../shared/TableHeader.svelte";
import TableActions from "../shared/TableActions.svelte";
import DonorAddress from "./DonorAddress.svelte";
import DonorDonations from "./DonorDonations.svelte";
import { filterAddress, filterName } from "../shared/tablefilters";
$: searchvalue = ""; $: searchvalue = "";
$: active_deletes = []; $: active_deletes = [];
$: current_donations = []; $: current_donations = [];
let modal_open = false; $: selectedDonors =
let delete_donor = {}; $table?.getSelectedRowModel().rows.map((row) => row.original) || [];
$: selected =
$table?.getSelectedRowModel().rows.map((row) => row.index) || [];
$: dataLoaded = false;
export let current_donors = []; export let current_donors = [];
const donors_promise = DonorService.donorControllerGetAll().then((val) => { export const addDonors = (donors) => {
current_donors = val; current_donors = current_donors.concat(...donors);
options.update((options) => ({
...options,
data: current_donors,
}));
};
//Section table
const columns = [
{
accessorKey: "id",
header: () => "id",
filterFn: `equalsString`,
},
{
accessorKey: "name",
header: () => $_("name"),
cell: (info) => {
const d = info.row.original;
if (d.middlename) {
return `${d.firstname} ${d.middlename} ${d.lastname}`;
} else {
return `${d.firstname} ${d.lastname}`;
}
},
filterFn: `name`,
},
{
accessorKey: "address",
header: () => $_("contact-information"),
cell: (info) => {
return renderComponent(DonorAddress, { address: info.getValue() });
},
filterFn: `address`,
},
{
accessorKey: "sponsorings",
header: () => $_("sponsorings"),
cell: (info) => {
const donations = current_donations.filter(
(d) => d?.donor?.id == info.row.original.id
);
return renderComponent(DonorDonations, { donations });
},
enableColumnFilter: false,
},
{
accessorKey: "donationAmount",
header: () => $_("total-donation-amount"),
cell: (info) => {
return `${(info.getValue() / 100)
.toFixed(2)
.toLocaleString("de-DE", { valute: "EUR" })}€`;
},
enableColumnFilter: false,
},
{
accessorKey: "paidDonationAmount",
header: () => $_("total-paid-amount"),
cell: (info) => {
return `${(info.getValue() / 100)
.toFixed(2)
.toLocaleString("de-DE", { valute: "EUR" })}€`;
},
enableColumnFilter: false,
},
{
accessorKey: "actions",
header: () => $_("action"),
cell: (info) => {
return renderComponent(TableActions, {
detailsLink: `./${info.row.original.id}`,
deleteAction: () => {
active_deletes = current_donors.filter(
(r) => r.id == info.row.original.id
);
},
deleteEnabled:
store.state.jwtinfo.userdetails.permissions.includes(
"DONOR:DELETE"
),
});
},
enableColumnFilter: false,
enableSorting: false,
},
];
const options = writable({
data: [],
columns: columns,
initialState: {
pagination: {
pageSize: 50,
},
},
filterFns: {
name: filterName,
address: filterAddress,
},
enableRowSelection: true,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
}); });
const donation_promise = DonationService.donationControllerGetAll().then( const table = createSvelteTable(options);
(val) => {
current_donations = val;
}
);
function should_display_based_on_id(id) { function should_display_based_on_id(id) {
if (searchvalue.toString().slice(-1) === "*") { if (searchvalue.toString().slice(-1) === "*") {
return id.toString().startsWith(searchvalue.replace("*", "")); return id.toString().startsWith(searchvalue.replace("*", ""));
} }
return id.toString() === searchvalue; return id.toString() === searchvalue;
} }
onMount(async () => {
let page = 0;
while (page >= 0) {
const donors = await DonorService.donorControllerGetAll(page, 500);
const donations = await DonationService.donationControllerGetAll(
page,
500
);
if (donors.length == 0 && donations.length == 0) {
page = -2;
}
current_donors = current_donors.concat(...donors);
current_donations = current_donations.concat(...donors);
options.update((options) => ({
...options,
data: current_donors,
}));
dataLoaded = true;
page++;
}
console.log("All donors loaded");
});
</script> </script>
<ConfirmDonorDeletion <ConfirmDonorDeletion
on:cancelDelete={(event) => { on:cancelDelete={(event) => {
modal_open = false; active_deletes = active_deletes.filter((a) => a.id !== event.detail.id);
active_deletes[event.detail.id] = false;
}} }}
bind:modal_open on:delete={async (event) => {
bind:delete_donor /> await DonorService.donorControllerRemove(event.detail.id, true);
{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')} Toastify({
{#await donors_promise && donation_promise} text: $_("donor-deleted"),
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
current_donors = current_donors.filter((d) => d.id !== event.detail.id);
active_deletes = active_deletes.filter((a) => a.id !== event.detail.id);
options.update((options) => ({
...options,
data: current_donors,
}));
}}
modal_open={active_deletes.length > 0}
delete_donor={active_deletes[0]}
/>
{active_deletes.length}
{#if store.state.jwtinfo.userdetails.permissions.includes("DONOR:GET")}
{#if !dataLoaded}
<div <div
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
role="alert"> role="alert"
<p class="font-bold">{$_('donors-are-being-loaded')}</p> >
<p class="text-sm">{$_('this-might-take-a-moment')}</p> <p class="font-bold">{$_("donors-are-being-loaded")}</p>
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
</div> </div>
{:then} {:else if current_donors.length === 0}
{#if current_donors.length === 0} <DonorsEmptyState />
<DonorsEmptyState /> {:else}
{:else} <input
<input type="search"
type="search" bind:value={searchvalue}
bind:value={searchvalue} placeholder={$_("datatable.search")}
placeholder={$_('datatable.search')} aria-label={$_("datatable.search")}
aria-label={$_('datatable.search')} class="mb-4"
class="mb-4" /> />
<div <div
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"> class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"
<table class="divide-y divide-gray-200 w-full"> >
<thead class="bg-gray-50"> <table class="w-full">
<tr> <thead>
<th {#each $table.getHeaderGroups() as headerGroup}
scope="col" <tr class="select-none">
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
{$_('name')} <InputElement
</th> type="checkbox"
<th checked={$table.getIsAllRowsSelected()}
scope="col" indeterminate={$table.getIsSomeRowsSelected()}
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> on:change={() => $table.toggleAllRowsSelected()}
{$_('contact-information')} />
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('donations')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('total-donation-amount')}
</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">
<span class="sr-only">{$_('action')}</span>
</th> </th>
{#each headerGroup.headers as header}
<TableHeader {header} />
{/each}
</tr> </tr>
</thead> {/each}
<tbody class="divide-y divide-gray-200"> </thead>
{#each current_donors as donor} <tbody>
{#if donor.firstname {#each $table.getRowModel().rows as row}
.toLowerCase() <tr>
.includes( <td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
searchvalue.toLowerCase() <InputElement
) || donor.lastname type="checkbox"
.toLowerCase() checked={row.getIsSelected()}
.includes( on:change={() => row.toggleSelected()}
searchvalue.toLowerCase() />
) || should_display_based_on_id(donor.id)} </td>
<tr data-rowid="donor_{donor.id}"> {#each row.getVisibleCells() as cell}
<td class="px-6 py-4 whitespace-nowrap"> <td>
<div class="flex items-center"> <svelte:component
<div class="ml-4"> this={flexRender(
<div class="text-sm font-medium text-gray-900"> cell.column.columnDef.cell,
{donor.firstname} cell.getContext()
{donor.middlename || ''} )}
{donor.lastname} />
</div> </td>
</div> {/each}
</div> </tr>
</td> {/each}
<td class="px-6 py-4 whitespace-nowrap"> </tbody>
{#if donor.email} </table>
<div class="text-sm text-gray-500">{donor.email}</div>
{/if}
{#if donor.phone}
<div class="text-sm text-gray-500">{donor.phone}</div>
{/if}
{#if donor.address.address1 !== null}
{donor.address.address1}<br />
<!-- {donor.address.address2 || ''}<br /> -->
{donor.address.postalcode}
{donor.address.city}
{donor.address.country}
{/if}
</td>
<td class="px-6 py-4 whitespace-nowrap">
{#if current_donations.filter((d) => d.donor.id == donor.id).length > 0}
{#each current_donations.filter((o) => o.donor.id == donor.id) as d}
{#if d.responseType === 'DISTANCEDONATION'}
<a
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}
{d.runner.middlename || ''}
{d.runner.lastname}</a>
{:else}
<a
href="../donations/{d.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-700 text-white mr-1">{$_('fixed-donation')}:
{(d.amount / 100)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })}</a>
{/if}
{/each}
{:else}{$_('donor-has-no-associated-donations')}{/if}
</td>
<td class="px-6 py-4 whitespace-nowrap">
{(donor.donationAmount / 100)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })}
</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}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
on:click={() => {
active_deletes[donor.id] = false;
}}
tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
<button
on:click={() => {
DonorService.donorControllerRemove(donor.id, false)
.then((resp) => {
current_donors = current_donors.filter((obj) => obj.id !== donor.id);
Toastify({
text: 'Donor deleted',
duration: 500,
backgroundColor:
'linear-gradient(to right, #00b09b, #96c93d)',
}).showToast();
})
.catch((err) => {
modal_open = true;
delete_donor = donor;
});
}}
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="./{donor.id}"
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:DELETE')}
<button
on:click={() => {
active_deletes[donor.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> </div>
{/await} <div class="h-2" />
<TableBottom {table} {selected} />
{/if}
{/if} {/if}

View File

@@ -15,17 +15,48 @@ export const groupFilter = (row, columnId, value) => {
}; };
export const runnerFilter = (row, columnId, value) => { export const runnerFilter = (row, columnId, value) => {
const runner = row.getValue(columnId); const runner = row.getValue(columnId);
if(!runner && value == "blanko"){return true} return filterRunner(runner, value)
if(!runner){return false} };
if(value.startsWith("#")){ export const donationRunnerFilter = (row, columnId, value) => {
return runner.id == value.replace("#","") const runner = row.getValue(columnId);
if (!runner) { return false; }
return filterRunner(runner, value)
};
export const donationDonorFilter = (row, columnId, value) => {
const runner = row.getValue(columnId);
return filterRunner(runner, value)
};
function filterRunner(runner, value) {
if (!runner && value == "blanko") { return true }
if (!runner) { return false }
if (value.startsWith("#")) {
return runner.id == value.replace("#", "")
} }
if(runner.middlename){ if (runner.middlename) {
return `${runner.firstname} ${runner.middlename} ${runner.lastname}`.toLowerCase().includes(value.toLowerCase()) return `${runner.firstname} ${runner.middlename} ${runner.lastname}`.toLowerCase().includes(value.toLowerCase())
} }
return `${runner.firstname} ${runner.lastname}`.toLowerCase().includes(value.toLowerCase()) return `${runner.firstname} ${runner.lastname}`.toLowerCase().includes(value.toLowerCase())
}
export const filterName = (row, columnId, value) => {
const obj = row.original;
if (obj.middlename) {
return `${obj.firstname} ${obj.middlename} ${obj.lastname}`.toLowerCase().includes(value.toLowerCase())
}
return `${obj.firstname} ${obj.lastname}`.toLowerCase().includes(value.toLowerCase())
};
export const filterAddress = (row, columnId, value) => {
const obj = row.original.address;
if (obj.address2) {s
return `${obj.address1} ${obj.address2} ${obj.postalcode} ${obj.city} ${obj.country}`.toLowerCase().includes(value.toLowerCase())
}
return `${obj.address1} ${obj.postalcode} ${obj.city} ${obj.country}`.toLowerCase().includes(value.toLowerCase())
}; };
export const statusFilter = (row, columnId, value) => { export const statusFilter = (row, columnId, value) => {

View File

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

View File

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