User settings feature/103-settings_page #104

Merged
niggl merged 25 commits from feature/103-settings_page into dev 2021-03-20 14:01:33 +00:00
7 changed files with 453 additions and 37 deletions

View File

@ -13,7 +13,7 @@
},
"license": "CC-BY-NC-SA-4.0",
"dependencies": {
"@odit/lfk-client-js": "0.6.3",
"@odit/lfk-client-js": "0.6.4",
"csvtojson": "^2.0.10",
"gridjs": "3.3.0",
"localforage": "1.9.0",

View File

@ -42,7 +42,7 @@
import MainDashContent from "./components/dashboard/MainDashContent.svelte";
import Users from "./components/users/Users.svelte";
import About from "./components/general/About.svelte";
import Settings from "./components/general/Settings.svelte";
import Settings from "./components/settings/Settings.svelte";
import Transition from "./components/base/Transition.svelte";
import Orgs from "./components/orgs/Orgs.svelte";
import Runners from "./components/runners/Runners.svelte";

View File

@ -1,35 +0,0 @@
<script>
import { _ } from "svelte-i18n";
import FormLayout from "../base/FormLayout.svelte";
</script>
<div class="pt-12 px-4 sm:px-6 lg:px-8 lg:pt-20 bg-gray-900 pb-12">
<div class="text-center mb-8">
<h1
class="mt-9 font-display text-4xl leading-none font-semibold text-white sm:text-5xl lg:text-6xl">
🔨<br />{$_('settings')}
</h1>
<p
class="mt-2 max-w-xl mx-auto text-xl lg:max-w-3xl lg:text-2xl text-gray-300">
<span class="text-lg">configure your profile however you want</span>
</p>
</div>
</div>
<div class="pt-0 pb-16 bg-gray-50 overflow-hidden lg:pt-12 lg:py-24">
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<!-- <h2 class="text-4xl font-display font-semibold text-gray-900 md:text-5xl">
General
</h2> -->
<div
class="max-w-3xl mx-auto text-xl leading-8 font-medium text-gray-900 mb-16">
<p class="text-center">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Temporibus et
amet voluptate nulla accusantium vero blanditiis nobis facere veritatis.
Impedit deserunt saepe aliquid unde consequuntur officia consequatur
fugit iusto dolorem?
</p>
</div>
<FormLayout />
</div>
</div>

View File

@ -0,0 +1,90 @@
<script>
import { _ } from "svelte-i18n";
import { clickOutside } from "../base/outsideclick";
import { focusTrap } from "svelte-focus-trap";
import { MeService } from "@odit/lfk-client-js";
import Toastify from "toastify-js";
import { createEventDispatcher } from "svelte";
export let modal_open;
export let delete_triggered;
const dispatch = createEventDispatcher();
function cancelDelete() {
modal_open = false;
delete_triggered = false;
dispatch("cancelDelete");
}
function deleteMe() {
MeService.meControllerRemove(true)
.then((resp) => {
Toastify({
text: "Profile deleted!",
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
location.replace("../");
})
.catch((err) => {});
}
</script>
{#if modal_open}
<div
class="fixed z-10 inset-0 overflow-y-auto"
use:focusTrap
use:clickOutside
on:click_outside={cancelDelete}>
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop" />
</div>
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span>
<div
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
<svg class="h-6 w-6 text-blue-600" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="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 class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900">
{$_('attention')}
</h3>
<div class="mt-2 mb-6">
<p class="text-sm text-gray-500">
{$_('do-you-really-want-to-delete-your-profile')}
<br />
{$_('you-are-going-to-loose-all-permissions-and-access-to-the-runner-system')}
<br>
{$_('after-deletion-we-cant-restore-your-old-profile')}
</p>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button
on:click={deleteMe}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
{$_('confirm-delete-my-user-profile')}
</button>
<button
on:click={cancelDelete}
type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
{$_('cancel-keep-my-profile')}
</button>
</div>
</div>
</div>
</div>
{/if}

View File

@ -0,0 +1,319 @@
<script>
import { _ } from "svelte-i18n";
import isEmail from "validator/es/lib/isEmail";
import { MeService } from "@odit/lfk-client-js";
import Toastify from "toastify-js";
import ConfirmProfileDeletion from "./ConfirmProfileDeletion.svelte";
$: data_loaded = false;
$: delete_triggered = false;
$: original_data = {};
$: editable = {};
$: modal_open = false;
$: password_change = "";
$: password_confirm = "";
$: changes_performed = !(
JSON.stringify(editable) === JSON.stringify(original_data)
);
$: save_enabled = changes_performed && isEmail(editable.email);
$: update_password_enabled =
password_change.length > 0 && password_change === password_confirm;
const user_promise = MeService.meControllerGet().then((data) => {
data_loaded = true;
data.groups = data.groups.map((g) => g.id);
data.permissions = [0];
original_data = Object.assign(original_data, data);
editable = Object.assign(editable, original_data);
});
function submit() {
if (data_loaded === true && save_enabled) {
Toastify({
text: $_("updating-your-profile"),
duration: 2500,
}).showToast();
MeService.meControllerPut(editable)
.then((resp) => {
original_data = Object.assign(original_data, editable);
Toastify({
text: $_("profile-updated"),
duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
})
.catch((err) => {});
}
}
function changePassword() {
if (data_loaded === true && update_password_enabled) {
Toastify({
text: $_('changing-your-password'),
duration: 2500,
}).showToast();
let postdata = Object.assign({}, original_data);
postdata.password = password_confirm;
MeService.meControllerPut(postdata)
.then((resp) => {
password_confirm = "";
password_change = "";
postdata = {};
Toastify({
text: $_('password-changed'),
duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
setTimeout(() => {
location.replace("./");
}, 500);
})
.catch((err) => {});
}
}
</script>
<ConfirmProfileDeletion bind:modal_open bind:delete_triggered />
<div class="pt-12 px-4 sm:px-6 lg:px-8 lg:pt-20 bg-gray-900 pb-12">
<div class="text-center mb-8">
<h1
class="mt-9 font-display text-4xl leading-none font-semibold text-white sm:text-5xl lg:text-6xl">
🔨<br />{$_('settings')}
</h1>
</div>
</div>
<div class="pt-0 pb-16 bg-gray-50 overflow-hidden lg:pt-12 lg:py-24">
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<div>
<div class="md:grid md:grid-cols-3 md:gap-6">
<div class="md:col-span-1">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium leading-6 text-gray-900">
{$_('profile')}
</h3>
<p class="mt-1 text-sm text-gray-600">
{$_('everything-concerning-your-profile')}
</p>
</div>
</div>
{#await user_promise}
{$_('loading-profile-data')}
{:then}
<div class="mt-5 md:mt-0 md:col-span-2">
<div class="shadow sm:rounded-md sm:overflow-hidden">
<div class="px-4 py-5 bg-white space-y-6 sm:p-6">
<div>
<!-- svelte-ignore a11y-label-has-associated-control -->
<label class="block text-sm font-medium text-gray-700">
{$_('profile-picture')}
</label>
<div class="mt-2 flex items-center">
<span
class="inline-block h-20 w-20 rounded-full overflow-hidden bg-gray-100">
<img
alt={$_('profile-picture')}
class="h-20 w-20 rounded-full overflow-hidden bg-gray-100"
src={editable.profilePic || 'https://lauf-fuer-kaya.de/lfk-logo.png'} />
</span>
<!-- <button
type="button"
class="ml-5 bg-white py-2 px-3 border border-gray-300 rounded-md shadow-sm text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Change
</button> -->
</div>
</div>
<div class="text-sm w-full">
<label
for="username"
class="font-medium text-gray-700">{$_('username')}</label>
<input
autocomplete="off"
placeholder={$_('username')}
type="text"
bind:value={editable.username}
name="username"
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 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
<div class="text-sm w-full">
<label
for="email"
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
<input
autocomplete="off"
placeholder={$_('e-mail-adress')}
type="email"
bind:value={editable.email}
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 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
{#if !isEmail(editable.email)}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">{$_('valid-email-is-required')}</span>
{/if}
<div class="text-sm w-full">
<label
for="firstname"
class="font-medium text-gray-700">{$_('first-name')}</label>
<input
autocomplete="off"
placeholder={$_('first-name')}
type="text"
bind:value={editable.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 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
<div class="text-sm w-full">
<label
for="middlename"
class="font-medium text-gray-700">{$_('middle-name')}</label>
<input
autocomplete="off"
placeholder={$_('middle-name')}
type="text"
bind:value={editable.middlename}
name="middlename"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
<div class="text-sm w-full">
<label
for="lastname"
class="font-medium text-gray-700">{$_('last-name')}</label>
<input
autocomplete="off"
placeholder={$_('last-name')}
type="text"
bind:value={editable.lastname}
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 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
</div>
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<button
type="submit"
disabled={!save_enabled}
class:opacity-50={!save_enabled}
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
{$_('save-changes')}
</button>
</div>
</div>
</div>
{/await}
</div>
</div>
</div>
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<div>
<div class="md:grid md:grid-cols-3 md:gap-6">
<div class="md:col-span-1">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium leading-6 text-gray-900">
{$_('password')}
</h3>
<p class="mt-1 text-sm text-gray-600">
{$_('change-your-password-here')}
</p>
</div>
</div>
{#await user_promise}
{$_('loading-profile-data')}
{:then}
<div class="mt-5 md:mt-0 md:col-span-2">
<div class="shadow sm:rounded-md sm:overflow-hidden">
<div class="px-4 py-3 bg-gray-50 text-left sm:px-6">
<label
for="new_password"
class="font-medium text-gray-700">{$_('new-password')}</label>
<div class="-mt-px relative">
<input
aria-label={$_('password')}
type="password"
required=""
bind:value={password_change}
class="border-gray-300 placeholder-gray-500 appearance-none rounded-md relative block w-full px-3 py-2 border focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
placeholder={$_('password')} />
</div>
<label
for="new_password"
class="font-medium text-gray-700">{$_('confirm-the-new-password')}</label>
<div class="-mt-px relative">
<input
aria-label={$_('password')}
type="password"
required=""
bind:value={password_confirm}
class="border-gray-300 placeholder-gray-500 appearance-none rounded-md relative block w-full px-3 py-2 border focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
placeholder={$_('password')} />
</div>
{#if password_change != password_confirm && password_change.length > 0}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">{$_('passwords-dont-match')}</span>
{/if}
</div>
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<button
type="submit"
disabled={!update_password_enabled}
class:opacity-50={!update_password_enabled}
on:click={changePassword}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
{$_('update-password')}
</button>
{#if update_password_enabled}
<p>
{$_('after-the-update-youll-get-logged-out-please-login-with-your-new-password-after-that')}
</p>
{/if}
</div>
</div>
</div>
{/await}
</div>
</div>
</div>
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<div>
<div class="md:grid md:grid-cols-3 md:gap-6">
<div class="md:col-span-1">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium leading-6 text-gray-900">
{$_('danger-zone')}
</h3>
<p class="mt-1 text-sm text-gray-600">
{$_('stuff-that-could-harm-your-profile')}
</p>
</div>
</div>
{#await user_promise}
{$_('loading-profile-data')}
{:then}
<div class="mt-5 md:mt-0 md:col-span-2">
<div class="shadow sm:rounded-md sm:overflow-hidden">
<div class="px-4 py-3 bg-gray-50 text-left sm:px-6">
<span data-id="donor_actions_${editable.id}">
{#if delete_triggered}
<button
on:click={() => {
modal_open = true;
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:">{$_('confirm-deletion')}</button>
<button
on:click={() => {
delete_triggered = !delete_triggered;
}}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:">{$_('cancel')}</button>
{/if}
{#if !delete_triggered}
<button
on:click={() => {
delete_triggered = true;
}}
type="button"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:">{$_('delete-profile')}</button>
{/if}
</span>
</div>
</div>
</div>
{/await}
</div>
</div>
</div>
</div>

View File

@ -20,6 +20,8 @@
"adding-scan": "Scan wird hinzugefügt",
"address": "Adresse",
"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-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-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-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!",
@ -34,18 +36,23 @@
"cancel": "Abbrechen",
"cancel-delete": "Löschen abbrechen",
"cancel-keep-donor": "Abbrechen, Sponsor:in behalten",
"cancel-keep-my-profile": "Abbrechen, mein Profil behalten",
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
"cancel-keep-team": "Abbrechen, Team 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.",
"change-your-password-here": "Hier kannst du dein Passwort ändern",
"changing-your-password": "Passwort wird geändert",
"city": "Stadt",
"close": "Schließen",
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
"confirm": "Bestätigen",
"confirm-delete": "Löschung Bestätigen",
"confirm-delete-donor-with-all-donations": "Bestätigen, Sponsor:in mit allen Sponsorings löschen",
"confirm-delete-my-user-profile": "Bestätigung, mein Benutzerprofil 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-deletion": "Löschung Bestätigen",
"confirm-the-new-password": "Neues Passwort bestätigen",
"contact": "Kontakt",
"contact-deleted": "Kontakt gelöscht",
"contact-information": "Kontaktinformation",
@ -79,6 +86,7 @@
"csv_import__lastname": "Nachname",
"csv_import__middlename": "Mittelname",
"csv_import__team": "Team",
"danger-zone": "Gefahrenzone",
"dashboard-greeting": "Moin",
"dashboard-title": "Dashboard",
"datatable": {
@ -102,6 +110,7 @@
"delete-donor": "Sponsor:in löschen",
"delete-group": "Gruppe löschen",
"delete-organization": "Organisation löschen",
"delete-profile": "Profil löschen",
"delete-runner": "Läufer:in löschen",
"delete-scan": "Scan löschen",
"delete-station": "Station löschen",
@ -117,6 +126,7 @@
"distance-donation": "Sponsoring",
"distance-in-km": "Distanz (in KM)",
"distance-track": "Distanz (+Track)",
"do-you-really-want-to-delete-your-profile": "Möchtest du dein Profil wirklich löschen?",
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} 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?",
@ -141,6 +151,7 @@
"english": "Englisch",
"error_on_login": "😢Fehler beim Login",
"erteilte": "Direkt erteilte",
"everything-concerning-your-profile": "Alles zu deinem Profil",
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃‍♂️🏃‍♀️🏃‍♂️",
"faq": "FAQ",
"filter-by-organization-team": "Filtern nach Organisation / Team",
@ -192,6 +203,7 @@
"loading-donation-details": "Lade Sponsoringdetails",
"loading-donor-details": "Lade Details",
"loading-group-detail": "Lade Gruppendetails...",
"loading-profile-data": "Lade Profildaten",
"loading-runners": "Läufer:innen werden geladen...",
"loading-station-details": "Lade Scanstation-Details ...",
"log_in": "Anmelden",
@ -227,11 +239,13 @@
"orgs": "Organisationen",
"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": "Passwort",
"password-changed": "Passwort wurde aktualisiert!",
"password-is-required": "Passwort muss angegeben werden",
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
"password-reset-in-progress": "Passwort wird zurückgesetzt...",
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
"passwords-dont-match": "Die Passwörter stimmen nicht überein.",
"pdf-generation-failed": "PDF Generierung fehlgeschlagen!",
"pdf-successfully-generated": "PDF wurde erfolgreich generiert!",
"pdfs-successfully-generated": "Alle PDFs wurden generiert!",
@ -254,7 +268,9 @@
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
"privacy": "Datenschutz",
"privacy-loading": "Datenschutzerklärung lädt...",
"profile": "Profil",
"profile-picture": "Profilbild",
"profile-updated": "Profil wurde aktualisiert!",
"read-license": "Lizenz-Text lesen",
"receipt-needed": "Spendenquittung benötigt",
"repo_link": "Link",
@ -290,9 +306,11 @@
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
"set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen",
"settings": "Einstellungen",
"settings-for-your-profile": "Die Einstellungen deines Accounts",
"something-about-the-group": "Infos zur Gruppe",
"stats-are-being-loaded": "Die Statistiken werden geladen...",
"status": "Status",
"stuff-that-could-harm-your-profile": "Einstellungen, die deinem Profil nachhaltig schaden können",
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
"team": "Team",
"team-detail-is-being-loaded": "Team wird geladen...",
@ -325,6 +343,7 @@
"track-name": "Trackname",
"track-name-must-not-be-empty": "Der Name muss angegeben werden",
"tracks": "Tracks",
"update-password": "Passwort ändern",
"updated-contact": "Kontakt aktualisiert!",
"updated-donor": "Sponsor:in wurde aktualisiert",
"updated-organization": "Organisation wurde aktualisiert",
@ -334,6 +353,7 @@
"updating-permissions": "Berechtigungen werden aktualisiert...",
"updating-runner": "Läufer:in wird aktualisiert.",
"updating-user": "Benutzer:in wird aktualisiert...",
"updating-your-profile": "Profil wird aktualisiert...",
"user-added": "Benutzer hinzugefügt",
"user-groups": "Benutzergruppen",
"user-is-being-added": "Benutzer wird hinzugefügt ...",
@ -348,6 +368,7 @@
"verfuegbare": "Verfügbar",
"welcome_wavinghand": "Willkommen 👋",
"yes-i-copied-the-token": "Ja, ich habe den Token kopiert",
"you-are-going-to-loose-all-permissions-and-access-to-the-runner-system": "Du wirst all deine Berechtigungen und den Zugriff aufs Läufersystem verlieren!",
"you-can-now-use-your-new-password-to-log-in-to-your-account": "Du kannst dich jetzt mit deinem neuen Passwort anmelden! 🎉",
"you-have-to-provide-an-organization": "Du musst eine Organisation angeben",
"zip-postal-code": "Postleitzahl"

View File

@ -20,6 +20,8 @@
"adding-scan": "Adding Scan",
"address": "Address",
"address-is-required": "Address is required",
"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.",
"all-associated-donations-will-get-deleted-as-well": "All associated donations will get deleted as well",
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!",
@ -34,18 +36,23 @@
"cancel": "Cancel",
"cancel-delete": "Cancel Delete",
"cancel-keep-donor": "Cancel, keep donor",
"cancel-keep-my-profile": "Cancel, keep my profile",
"cancel-keep-organization": "Cancel, keep organization",
"cancel-keep-team": "Cancel, keep team",
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
"change-your-password-here": "Change your password here",
"changing-your-password": "Changing your password",
"city": "City",
"close": "Close",
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
"confirm": "Confirm",
"confirm-delete": "Confirm Delete",
"confirm-delete-donor-with-all-donations": "Confirm, delete donor with all donations",
"confirm-delete-my-user-profile": "Confirm, delete my user profile",
"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-deletion": "Confirm Deletion",
"confirm-the-new-password": "Confirm the new password",
"contact": "Contact",
"contact-deleted": "Contact deleted",
"contact-information": "Contact Information",
@ -79,6 +86,7 @@
"csv_import__lastname": "Lastname",
"csv_import__middlename": "Middlename",
"csv_import__team": "Team",
"danger-zone": "Danger zone",
"dashboard-greeting": "hello there",
"dashboard-title": "Dashboard",
"datatable": {
@ -102,6 +110,7 @@
"delete-donor": "Delete donor",
"delete-group": "Delete Group",
"delete-organization": "Delete Organization",
"delete-profile": "Delete Profile",
"delete-runner": "Delete Runner",
"delete-scan": "Delete scan",
"delete-station": "Delete station",
@ -117,6 +126,7 @@
"distance-donation": "distance donation",
"distance-in-km": "Distance in km",
"distance-track": "Distance (+Track)",
"do-you-really-want-to-delete-your-profile": "Do you really want to delete your profile?",
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
"do-you-want-to-delete-this-donor-with-all-related-donations": "Do you want to delete this donor with all related donations",
@ -141,6 +151,7 @@
"english": "English",
"error_on_login": "Error on login",
"erteilte": "Directly granted",
"everything-concerning-your-profile": "Everything concerning your profile",
"everything-is-more-fun-together": "everything is more fun together 🏃‍♂️🏃‍♀️🏃‍♂️",
"faq": "FAQ",
"filter-by-organization-team": "Filter by Organization/ Team",
@ -192,6 +203,7 @@
"loading-donation-details": "Loading donation details",
"loading-donor-details": "Loading donor details",
"loading-group-detail": "Loading group detail...",
"loading-profile-data": "Loading profile data",
"loading-runners": "loading runners...",
"loading-station-details": "Loading station details",
"log_in": "Log in",
@ -227,11 +239,13 @@
"orgs": "Organizations",
"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": "Password",
"password-changed": "Password changed!",
"password-is-required": "Password is required",
"password-reset-failed": "Password reset failed!",
"password-reset-in-progress": "Password Reset in Progress...",
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
"password-reset-successful": "Password Reset successful!",
"passwords-dont-match": "Passwords don't match",
"pdf-generation-failed": "PDF generation failed!",
"pdf-successfully-generated": "PDF successfully generated!",
"pdfs-successfully-generated": "PDFs successfully generated!",
@ -254,7 +268,9 @@
"please-request-a-new-reset-mail": "Please request a new reset mail...",
"privacy": "Privacy",
"privacy-loading": "Privacy loading...",
"profile": "Profile",
"profile-picture": "Profile Picture",
"profile-updated": "Profile updated!",
"read-license": "Read License",
"receipt-needed": "Receipt needed",
"repo_link": "Link",
@ -290,9 +306,11 @@
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
"set-the-user-active-inactive": "set the user active/ inactive",
"settings": "Settings",
"settings-for-your-profile": "Settings for your profile",
"something-about-the-group": "Something about the group...",
"stats-are-being-loaded": "stats are being loaded...",
"status": "Status",
"stuff-that-could-harm-your-profile": "Stuff that could harm your profile",
"successful-password-reset": "Successful password reset!",
"team": "Team",
"team-detail-is-being-loaded": "team detail is being loaded...",
@ -325,6 +343,7 @@
"track-name": "Track name",
"track-name-must-not-be-empty": "Track name must not be empty",
"tracks": "Tracks",
"update-password": "Update password",
"updated-contact": "Updated contact!",
"updated-donor": "updated donor",
"updated-organization": "updated organization",
@ -334,6 +353,7 @@
"updating-permissions": "updating permissions...",
"updating-runner": "Updating runner...",
"updating-user": "updating user...",
"updating-your-profile": "Updating your profile...",
"user-added": "User added",
"user-groups": "User Groups",
"user-is-being-added": "User is being added...",
@ -348,6 +368,7 @@
"verfuegbare": "availdable",
"welcome_wavinghand": "Welcome 👋",
"yes-i-copied-the-token": "Yes, I copied the token",
"you-are-going-to-loose-all-permissions-and-access-to-the-runner-system": "You are going to loose all permissions and access to the runner system!",
"you-can-now-use-your-new-password-to-log-in-to-your-account": "You can now use your new password to log in to your account! 🎉",
"you-have-to-provide-an-organization": "You have to provide an organization",
"zip-postal-code": "ZIP/ postal code"