diff --git a/.vscode/i18n-ally-custom-framework.yml b/.vscode/i18n-ally-custom-framework.yml new file mode 100644 index 00000000..3fe77a20 --- /dev/null +++ b/.vscode/i18n-ally-custom-framework.yml @@ -0,0 +1,7 @@ +languageIds: + - javascript + - svelte + - html +monopoly: false +refactorTemplates: + - "{$_('$1')}" \ No newline at end of file diff --git a/src/App.svelte b/src/App.svelte index c8964a12..6257257b 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -64,6 +64,8 @@ import ContactDetail from "./components/contacts/ContactDetail.svelte"; import Donors from "./components/donors/Donors.svelte"; import DonorDetail from "./components/donors/DonorDetail.svelte"; + import Donations from "./components/donations/Donations.svelte"; + import DonationDetail from "./components/donations/DonationDetail.svelte"; store.init(); registerSW(); @@ -154,6 +156,14 @@ + + + + + + + + diff --git a/src/components/dashboard/Dashboard.svelte b/src/components/dashboard/Dashboard.svelte index a007fe91..b46e0615 100644 --- a/src/components/dashboard/Dashboard.svelte +++ b/src/components/dashboard/Dashboard.svelte @@ -121,6 +121,23 @@ {$_('donors')} {/if} +{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')} + + + + {$_('donations')} + +{/if} {#if store.state.jwtinfo.userdetails.permissions.includes('TRACK:GET')} + import { _ } from "svelte-i18n"; + import { clickOutside } from "../base/outsideclick"; + import { focusTrap } from "svelte-focus-trap"; + import { + DonationService, + DonorService, + RunnerService, + } from "@odit/lfk-client-js"; + import Toastify from "toastify-js"; + export let modal_open; + export let current_donations; + function focus(el) { + el.focus(); + } + $: donor = 0; + $: runner = 0; + $: donors = []; + $: runners = []; + $: is_fixed = false; + DonorService.donorControllerGetAll().then((val) => { + donors = val; + donor = donors[0].id || 0; + }); + RunnerService.runnerControllerGetAll().then((val) => { + runners = val; + runner = runners[0].id || 0; + }); + $: amount_input = 0; + $: processed_last_submit = true; + $: is_amount_valid = amount_input > 0; + $: createbtnenabled = is_amount_valid; + (() => { + document.onkeydown = (e) => { + e = e || window.event; + if (e.key === "Escape") { + modal_open = false; + } + if (e.keyCode === 13) { + if (createbtnenabled === true) { + createbtnenabled = false; + submit(); + } + } + }; + })(); + function submit() { + if (processed_last_submit === true) { + let amount_cent = Math.floor(amount_input * 100); + processed_last_submit = false; + const toast = Toastify({ + text: "adding donation", + duration: -1, + }).showToast(); + if (is_fixed) { + let postdata = { + donor, + amount: amount_cent, + }; + DonationService.donationControllerPostFixed(postdata) + .then((result) => { + donor = donors[0].id || 0; + runner = runners[0].id || 0; + amount_input = 0; + modal_open = false; + // + Toastify({ + text: "donation_added", + duration: 500, + backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", + }).showToast(); + current_donations.push(result); + current_donations = current_donations; + }) + .catch((err) => { + // + }) + .finally(() => { + processed_last_submit = true; + // + toast.hideToast(); + }); + } else { + let postdata = { + donor, + runner, + amountPerDistance: amount_cent, + }; + DonationService.donationControllerPostDistance(postdata) + .then((result) => { + donor = donors[0].id || 0; + runner = runners[0].id || 0; + amount_input = 0; + modal_open = false; + // + Toastify({ + text: "donation_added", + duration: 500, + backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", + }).showToast(); + current_donations.push(result); + current_donations = current_donations; + }) + .catch((err) => { + // + }) + .finally(() => { + processed_last_submit = true; + // + toast.hideToast(); + }); + } + } + } + + + + +{#if modal_open} +
{ + modal_open = false; + }}> +
+ +
+{/if} diff --git a/src/components/donations/DonationDetail.svelte b/src/components/donations/DonationDetail.svelte new file mode 100644 index 00000000..3c770589 --- /dev/null +++ b/src/components/donations/DonationDetail.svelte @@ -0,0 +1,265 @@ + + +{#await donor_promise && runner_promise && promise} + {$_('loading-donation-details')} +{:then} +
+
+
+ +
+
+
+ {original_data.donor.firstname} + {original_data.donor.middlename || ''} + {original_data.donor.lastname} + > + {#if original_data.responseType == 'DISTANCEDONATION'} + {original_data.runner.firstname} + {original_data.runner.middlename || ''} + {original_data.runner.lastname} + {:else} + {$_('fixed-donation')}: + {amount_input.toFixed(2).toLocaleString('de-DE', { valute: 'EUR' })}€ + {/if} + + {#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:DELETE')} + {#if delete_triggered} + + + {/if} + {#if !delete_triggered} + + {/if} + {/if} + {#if !delete_triggered} + + {/if} + +
+ +
+ {$_('total-donation-amount')}: + {(editable.amount / 100) + .toFixed(2) + .toLocaleString('de-DE', { valute: 'EUR' })}€ +
+
+ + +
+ {#if original_data.responseType == 'DISTANCEDONATION'} +
+ + +
+ {/if} +
+ +
+ + +
+ {#if !is_amount_valid} + + {$_('donation-amount-must-be-greater-that-0-00eur')} + + {/if} +
+
+{:catch error} + +{/await} diff --git a/src/components/donations/Donations.svelte b/src/components/donations/Donations.svelte new file mode 100644 index 00000000..629e65c1 --- /dev/null +++ b/src/components/donations/Donations.svelte @@ -0,0 +1,29 @@ + + +
+ + {$_('donations')} + {#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:CREATE')} + + {/if} + + +
+ +{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:CREATE')} + +{/if} diff --git a/src/components/donations/DonationsEmptyState.svelte b/src/components/donations/DonationsEmptyState.svelte new file mode 100644 index 00000000..d19419bd --- /dev/null +++ b/src/components/donations/DonationsEmptyState.svelte @@ -0,0 +1,12 @@ + + +
+

+ + There are no donations yet
+ add your fist donation +

+
diff --git a/src/components/donations/DonationsOverview.svelte b/src/components/donations/DonationsOverview.svelte new file mode 100644 index 00000000..d067c1f6 --- /dev/null +++ b/src/components/donations/DonationsOverview.svelte @@ -0,0 +1,202 @@ + + +{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')} + {#await donations_promise} + + {:then} + {#if current_donations.length === 0} + + {:else} + +
+ + + + + + + + + + + + {#each current_donations as donation} + {#if donation.donor.firstname + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || donation.donor.middlename + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || donation.donor.lastname + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || donation.runner?.firstname + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || donation.runner?.middlename + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || donation.runner?.lastname + .toLowerCase() + .includes( + searchvalue.toLowerCase() + ) || should_display_based_on_id(donation.id)} + + + + + + {#if active_deletes[donation.id] === true} + + {:else} + + {/if} + + {/if} + {/each} + +
+ {$_('donor')} + + {$_('runner')} + + {$_('amount-per-kilometer')} + + {$_('donation-amount')} + + {$_('action')} +
+ + + {#if donation.runner} + + {:else} +
+ {$_('fixed-donation')} +
+ {/if} +
+ {#if donation.amountPerDistance} +
+ {(donation.amountPerDistance / 100) + .toFixed(2) + .toLocaleString('de-DE', { valute: 'EUR' })}€ +
+ {:else} +
+ {$_('fixed-donation')} +
+ {/if} +
+
+ {(donation.amount / 100) + .toFixed(2) + .toLocaleString('de-DE', { valute: 'EUR' })}€ +
+
+ + + + {$_('details')} + {#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:DELETE')} + + {/if} +
+
+ {/if} + {:catch error} +
+ + {$_('general_promise_error')} + {error} + +
+ {/await} +{/if} diff --git a/src/components/donations/donations.svg b/src/components/donations/donations.svg new file mode 100644 index 00000000..13a97190 --- /dev/null +++ b/src/components/donations/donations.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/donors/DonorDetail.svelte b/src/components/donors/DonorDetail.svelte index 2a9aec40..bb88f84a 100644 --- a/src/components/donors/DonorDetail.svelte +++ b/src/components/donors/DonorDetail.svelte @@ -1,18 +1,17 @@ -{#await promise} +{#await promise && donation_promise} {$_('loading-donor-details')} {:then}
@@ -120,8 +121,8 @@ viewBox="0 0 24 24" width="24" height="24"> - +
  • {$_('donors')}{$_('confirm-deletion')} + 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')} + 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')} {/if} {#if !delete_triggered} + 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-donor')} {/if} {/if} {#if !delete_triggered} @@ -181,16 +182,39 @@ class:opacity-50={!save_enabled} type="button" 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')} + 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:">{$_('save-changes')} {/if}
  • -
    - {$_('total-donation-amount')}: - {(editable.donationAmount/100).toFixed(2).toLocaleString("de-DE", {valute: "EUR"})}€ +
    + {$_('total-donation-amount')}: + {(editable.donationAmount / 100) + .toFixed(2) + .toLocaleString('de-DE', { valute: 'EUR' })}€ +
    + {$_('donations')}: + {#if current_donations.filter((d) => d.donor.id == editable.id).length > 0} + {#each current_donations.filter((o) => o.donor.id == editable.id) as d} + {#if d.responseType === 'DISTANCEDONATION'} + {d.runner.firstname} + {d.runner.middlename} + {d.runner.lastname} + {:else} + {$_('fixed-donation')}: + {(d.amount / 100) + .toFixed(2) + .toLocaleString('de-DE', { valute: 'EUR' })}€ + {/if} + {/each} + {:else}{$_('donor-has-no-associated-donations')}{/if}
    -
    +
    @@ -203,7 +227,7 @@ class:focus:ring-red-500={!isFirstnameValid} 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 rounded-md p-2" /> + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> {#if !isFirstnameValid} @@ -211,7 +235,7 @@ {/if}
    -
    +
    @@ -221,9 +245,9 @@ type="text" bind:value={editable.middlename} name="middlename" - class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
    -
    +
    @@ -236,7 +260,7 @@ class:focus:border-red-500={!isLastnameValid} class:focus:ring-red-500={!isLastnameValid} name="lastname" - class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> {#if !isLastnameValid} @@ -244,7 +268,7 @@ {/if}
    -
    +
    @@ -257,7 +281,7 @@ class:focus:border-red-500={!isEmailValid} class:focus:ring-red-500={!isEmailValid} name="email" - class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> {#if !isEmailValid} @@ -265,7 +289,7 @@ {/if}
    -
    +
    + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> {#if !isPhoneValidOrEmpty} @@ -293,7 +317,7 @@ type="checkbox" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
    -
    +
    @@ -303,7 +327,7 @@
    + class="block font-medium text-gray-700">{$_('address')} + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> {#if !isAddress1Valid} @@ -324,19 +348,19 @@
    + class="block font-medium text-gray-700">{$_('apartment-suite-etc')} + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
    + class="block font-medium text-gray-700">{$_('zip-postal-code')} + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> {#if !iszipcodevalid} @@ -357,7 +381,7 @@
    + class="block font-medium text-gray-700">{$_('city')} + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm: border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" /> {#if !iscityvalid} diff --git a/src/components/donors/DonorsOverview.svelte b/src/components/donors/DonorsOverview.svelte index dd43f7ca..86ddf16a 100644 --- a/src/components/donors/DonorsOverview.svelte +++ b/src/components/donors/DonorsOverview.svelte @@ -1,18 +1,24 @@