Compare commits
19
Commits
0.18.4
..
2a64094006
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a64094006 | ||
|
|
e9ce9644ff | ||
|
|
52439aa5bc
|
||
|
|
ccf865687b
|
||
|
|
cac34db1fd
|
||
|
|
faf3893180
|
||
|
|
c33dfcfddd
|
||
|
|
019e14ab1f
|
||
|
|
b5790196c6
|
||
|
|
94a64ca690
|
||
|
|
a6ce04c903 | ||
|
|
165c154233 | ||
|
|
318547db46
|
||
|
|
e60c09e19c
|
||
|
|
4834d1484c
|
||
|
|
4b6342727e
|
||
|
|
cb5fa52cd9
|
||
|
|
947d01cf7f
|
||
|
|
3563394fb3
|
No files matched your search
@@ -2,8 +2,22 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [0.19.0](https://git.odit.services/lfk/frontend/compare/0.18.4...0.19.0)
|
||||
|
||||
- Merge pull request 'feature/173-scanstation_configcodes' (#174) from feature/173-scanstation_configcodes into dev [`165c154`](https://git.odit.services/lfk/frontend/commit/165c1542338c58f2abf42fef2e7b84b40d1e2d9c)
|
||||
- I18n [`e60c09e`](https://git.odit.services/lfk/frontend/commit/e60c09e19c9cc20338906e84f4db4e009d926360)
|
||||
- Implemented config code generation [`4b63427`](https://git.odit.services/lfk/frontend/commit/4b6342727ee0ea38597750d8c99edc301f1ccc2d)
|
||||
- Styling [`4834d14`](https://git.odit.services/lfk/frontend/commit/4834d1484c3fb6ecd4a1b56aa9fbb8125c641a62)
|
||||
- Adjusted size on smaller devices [`318547d`](https://git.odit.services/lfk/frontend/commit/318547db46045e41de64d5688368e85cd6fb8035)
|
||||
- Lockfile [`947d01c`](https://git.odit.services/lfk/frontend/commit/947d01cf7fc7fe2ee88c56e017b0d663f1f3b4f9)
|
||||
- Barcode placeholder [`cb5fa52`](https://git.odit.services/lfk/frontend/commit/cb5fa52cd9a97490b50fb0c02c26615b49650c08)
|
||||
- Added bwip-js for barcode generation [`3563394`](https://git.odit.services/lfk/frontend/commit/3563394fb33d661890327e2ae08c400830b37844)
|
||||
|
||||
#### [0.18.4](https://git.odit.services/lfk/frontend/compare/0.18.3...0.18.4)
|
||||
|
||||
> 15 April 2023
|
||||
|
||||
- 🚀RELEASE v0.18.4 [`269d7a7`](https://git.odit.services/lfk/frontend/commit/269d7a7defdde059ef2bb5103262cf734e9babe9)
|
||||
- Hide address2 in orgs by default [`e95f233`](https://git.odit.services/lfk/frontend/commit/e95f2333b0b958ed00c0e097b43aac2e70ad0d38)
|
||||
|
||||
#### [0.18.3](https://git.odit.services/lfk/frontend/compare/0.18.2...0.18.3)
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.18.4-RELEASE_INFO</span>
|
||||
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.19.0-RELEASE_INFO</span>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<script src="/env.js"></script>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@odit/lfk-frontend",
|
||||
"version": "0.18.4",
|
||||
"version": "0.19.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"i18n-order": "node order.js",
|
||||
@@ -39,9 +39,10 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@odit/lfk-client-js": "0.14.3",
|
||||
"@odit/lfk-client-js": "1.0.1",
|
||||
"@paralleldrive/cuid2": "^2.2.0",
|
||||
"@tanstack/svelte-table": "^8.8.5",
|
||||
"bwip-js": "^3.4.0",
|
||||
"check-password-strength": "2.0.7",
|
||||
"csvtojson": "2.0.10",
|
||||
"gridjs": "3.4.0",
|
||||
|
||||
Generated
+12
-4
@@ -2,14 +2,17 @@ lockfileVersion: '6.0'
|
||||
|
||||
dependencies:
|
||||
'@odit/lfk-client-js':
|
||||
specifier: 0.14.3
|
||||
version: 0.14.3
|
||||
specifier: 1.0.1
|
||||
version: 1.0.1
|
||||
'@paralleldrive/cuid2':
|
||||
specifier: ^2.2.0
|
||||
version: 2.2.0
|
||||
'@tanstack/svelte-table':
|
||||
specifier: ^8.8.5
|
||||
version: 8.8.5(svelte@3.58.0)
|
||||
bwip-js:
|
||||
specifier: ^3.4.0
|
||||
version: 3.4.0
|
||||
check-password-strength:
|
||||
specifier: 2.0.7
|
||||
version: 2.0.7
|
||||
@@ -507,8 +510,8 @@ packages:
|
||||
'@octokit/openapi-types': 16.0.0
|
||||
dev: true
|
||||
|
||||
/@odit/lfk-client-js@0.14.3:
|
||||
resolution: {integrity: sha512-oOZ9jjzqcbMA0Sfwxn4q9+8hHckMU2IhAn7v0OAS54zcnquYQANnY4RMEoNIyXd0oEe1z8QewBjyBvFEDg6BmA==}
|
||||
/@odit/lfk-client-js@1.0.1:
|
||||
resolution: {integrity: sha512-eGwUW1MIh7sCzlLNRBLuBvLGGCHoOzmHovHnPqpMDn+fziIIX+fcmt40mdISucZwJDJqnOff4+eHimsHfSQO8A==}
|
||||
dev: false
|
||||
|
||||
/@odit/license-exporter@0.0.12:
|
||||
@@ -847,6 +850,11 @@ packages:
|
||||
run-applescript: 5.0.0
|
||||
dev: true
|
||||
|
||||
/bwip-js@3.4.0:
|
||||
resolution: {integrity: sha512-Gx9LIBhmEFmNH4FJsS+Rs+bG5hUcs+OBemEEQ2ZTLz8tue0PA/lM692Gf2yuYJ2yUpLGtK9tAexs85tXBPG/ww==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/bytes@3.1.2:
|
||||
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
@@ -1 +1 @@
|
||||
[{"author":"ODIT.Services","repo":{"type":"git","url":"git+https://git.odit.services/lfk/lfk-client-js"},"description":"A lib to interact with https://git.odit.services/lfk/backend. Use this version for native JS applications.","name":"@odit/lfk-client-js","license":"CC-BY-NC-SA-4.0","version":"0.14.3","licensetext":"Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Creative\r\nCommons Corporation (\"Creative Commons\") is not a law firm and does not provide\r\nlegal services or legal advice. Distribution of Creative Commons public licenses\r\ndoes not create a lawyer-client or other relationship. Creative Commons makes\r\nits licenses and related information available on an \"as-is\" basis. Creative\r\nCommons gives no warranties regarding its licenses, any material licensed\r\nunder their terms and conditions, or any related information. Creative Commons\r\ndisclaims all liability for damages resulting from their use to the fullest\r\nextent possible.\r\n\r\nUsing Creative Commons Public Licenses\r\n\r\nCreative Commons public licenses provide a standard set of terms and conditions\r\nthat creators and other rights holders may use to share original works of\r\nauthorship and other material subject to copyright and certain other rights\r\nspecified in the public license below. The following considerations are for\r\ninformational purposes only, are not exhaustive, and do not form part of our\r\nlicenses.\r\n\r\nConsiderations for licensors: Our public licenses are intended for use by\r\nthose authorized to give the public permission to use material in ways otherwise\r\nrestricted by copyright and certain other rights. Our licenses are irrevocable.\r\nLicensors should read and understand the terms and conditions of the license\r\nthey choose before applying it. Licensors should also secure all rights necessary\r\nbefore applying our licenses so that the public can reuse the material as\r\nexpected. Licensors should clearly mark any material not subject to the license.\r\nThis includes other CC-licensed material, or material used under an exception\r\nor limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors\r\n\r\nConsiderations for the public: By using one of our public licenses, a licensor\r\ngrants the public permission to use the licensed material under specified\r\nterms and conditions. If the licensor's permission is not necessary for any\r\nreason–for example, because of any applicable exception or limitation to copyright–then\r\nthat use is not regulated by the license. Our licenses grant only permissions\r\nunder copyright and certain other rights that a licensor has authority to\r\ngrant. Use of the licensed material may still be restricted for other reasons,\r\nincluding because others have copyright or other rights in the material. A\r\nlicensor may make special requests, such as asking that all changes be marked\r\nor described. Although not required by our licenses, you are encouraged to\r\nrespect those requests where reasonable. More considerations for the public\r\n: wiki.creativecommons.org/Considerations_for_licensees\r\n\r\nCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public\r\nLicense\r\n\r\nBy exercising the Licensed Rights (defined below), You accept and agree to\r\nbe bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike\r\n4.0 International Public License (\"Public License\"). To the extent this Public\r\nLicense may be interpreted as a contract, You are granted the Licensed Rights\r\nin consideration of Your acceptance of these terms and conditions, and the\r\nLicensor grants You such rights in consideration of benefits the Licensor\r\nreceives from making the Licensed Material available under these terms and\r\nconditions.\r\n\r\nSection 1 – Definitions.\r\n\r\na. Adapted Material means material subject to Copyright and Similar Rights\r\nthat is derived from or based upon the Licensed Material and in which the\r\nLicensed Material is translated, altered, arranged, transformed, or otherwise\r\nmodified in a manner requiring permission under the Copyright and Similar\r\nRights held by the Licensor. For purposes of this Public License, where the\r\nLicensed Material is a musical work, performance, or sound recording, Adapted\r\nMaterial is always produced where the Licensed Material is synched in timed\r\nrelation with a moving image.\r\n\r\nb. Adapter's License means the license You apply to Your Copyright and Similar\r\nRights in Your contributions to Adapted Material in accordance with the terms\r\nand conditions of this Public License.\r\n\r\nc. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses,\r\napproved by Creative Commons as essentially the equivalent of this Public\r\nLicense.\r\n\r\nd. Copyright and Similar Rights means copyright and/or similar rights closely\r\nrelated to coLine truncated
|
||||
[{"author":"ODIT.Services","repo":{"type":"git","url":"git+https://git.odit.services/lfk/lfk-client-js"},"description":"A lib to interact with https://git.odit.services/lfk/backend. Use this version for native JS applications.","name":"@odit/lfk-client-js","license":"CC-BY-NC-SA-4.0","version":"1.0.1","licensetext":"Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Creative\r\nCommons Corporation (\"Creative Commons\") is not a law firm and does not provide\r\nlegal services or legal advice. Distribution of Creative Commons public licenses\r\ndoes not create a lawyer-client or other relationship. Creative Commons makes\r\nits licenses and related information available on an \"as-is\" basis. Creative\r\nCommons gives no warranties regarding its licenses, any material licensed\r\nunder their terms and conditions, or any related information. Creative Commons\r\ndisclaims all liability for damages resulting from their use to the fullest\r\nextent possible.\r\n\r\nUsing Creative Commons Public Licenses\r\n\r\nCreative Commons public licenses provide a standard set of terms and conditions\r\nthat creators and other rights holders may use to share original works of\r\nauthorship and other material subject to copyright and certain other rights\r\nspecified in the public license below. The following considerations are for\r\ninformational purposes only, are not exhaustive, and do not form part of our\r\nlicenses.\r\n\r\nConsiderations for licensors: Our public licenses are intended for use by\r\nthose authorized to give the public permission to use material in ways otherwise\r\nrestricted by copyright and certain other rights. Our licenses are irrevocable.\r\nLicensors should read and understand the terms and conditions of the license\r\nthey choose before applying it. Licensors should also secure all rights necessary\r\nbefore applying our licenses so that the public can reuse the material as\r\nexpected. Licensors should clearly mark any material not subject to the license.\r\nThis includes other CC-licensed material, or material used under an exception\r\nor limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors\r\n\r\nConsiderations for the public: By using one of our public licenses, a licensor\r\ngrants the public permission to use the licensed material under specified\r\nterms and conditions. If the licensor's permission is not necessary for any\r\nreason–for example, because of any applicable exception or limitation to copyright–then\r\nthat use is not regulated by the license. Our licenses grant only permissions\r\nunder copyright and certain other rights that a licensor has authority to\r\ngrant. Use of the licensed material may still be restricted for other reasons,\r\nincluding because others have copyright or other rights in the material. A\r\nlicensor may make special requests, such as asking that all changes be marked\r\nor described. Although not required by our licenses, you are encouraged to\r\nrespect those requests where reasonable. More considerations for the public\r\n: wiki.creativecommons.org/Considerations_for_licensees\r\n\r\nCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public\r\nLicense\r\n\r\nBy exercising the Licensed Rights (defined below), You accept and agree to\r\nbe bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike\r\n4.0 International Public License (\"Public License\"). To the extent this Public\r\nLicense may be interpreted as a contract, You are granted the Licensed Rights\r\nin consideration of Your acceptance of these terms and conditions, and the\r\nLicensor grants You such rights in consideration of benefits the Licensor\r\nreceives from making the Licensed Material available under these terms and\r\nconditions.\r\n\r\nSection 1 – Definitions.\r\n\r\na. Adapted Material means material subject to Copyright and Similar Rights\r\nthat is derived from or based upon the Licensed Material and in which the\r\nLicensed Material is translated, altered, arranged, transformed, or otherwise\r\nmodified in a manner requiring permission under the Copyright and Similar\r\nRights held by the Licensor. For purposes of this Public License, where the\r\nLicensed Material is a musical work, performance, or sound recording, Adapted\r\nMaterial is always produced where the Licensed Material is synched in timed\r\nrelation with a moving image.\r\n\r\nb. Adapter's License means the license You apply to Your Copyright and Similar\r\nRights in Your contributions to Adapted Material in accordance with the terms\r\nand conditions of this Public License.\r\n\r\nc. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses,\r\napproved by Creative Commons as essentially the equivalent of this Public\r\nLicense.\r\n\r\nd. Copyright and Similar Rights means copyright and/or similar rights closely\r\nrelated to copLine truncated
|
||||
@@ -32,7 +32,7 @@
|
||||
export let original_data = {};
|
||||
export let current_cards = [];
|
||||
export const addCards = (cards) => {
|
||||
console.log(cards)
|
||||
console.log(cards);
|
||||
current_cards = current_cards.concat(...cards);
|
||||
options.update((options) => ({
|
||||
...options,
|
||||
@@ -155,15 +155,27 @@
|
||||
}).showToast();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
RunnerCardService.runnerCardControllerGetAll().then((val) => {
|
||||
current_cards = val;
|
||||
onMount(async () => {
|
||||
let page = 0;
|
||||
while (page >= 0) {
|
||||
const cards = await RunnerCardService.runnerCardControllerGetAll(
|
||||
page,
|
||||
500
|
||||
);
|
||||
if (cards.length == 0) {
|
||||
page = -2;
|
||||
}
|
||||
|
||||
current_cards = current_cards.concat(...cards);
|
||||
options.update((options) => ({
|
||||
...options,
|
||||
data: current_cards,
|
||||
}));
|
||||
|
||||
dataLoaded = true;
|
||||
});
|
||||
page++;
|
||||
}
|
||||
console.log("All cards loaded");
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -229,7 +241,7 @@
|
||||
...options,
|
||||
data: current_cards,
|
||||
}));
|
||||
$table.resetRowSelection()
|
||||
$table.resetRowSelection();
|
||||
}}
|
||||
>
|
||||
{$_("delete-cards")}
|
||||
@@ -249,7 +261,10 @@
|
||||
</svg>
|
||||
</button>
|
||||
{/if}
|
||||
<GenerateRunnerCards cards_show={selected.length>0} bind:generate_cards={selectedCards} />
|
||||
<GenerateRunnerCards
|
||||
cards_show={selected.length > 0}
|
||||
bind:generate_cards={selectedCards}
|
||||
/>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
|
||||
@@ -5,18 +5,16 @@
|
||||
import Toastify from "toastify-js";
|
||||
import DonationsEmptyState from "./DonationsEmptyState.svelte";
|
||||
import AddDonationPaymentModal from "./AddDonationPaymentModal.svelte";
|
||||
import { onMount } from "svelte";
|
||||
$: searchvalue = "";
|
||||
$: active_deletes = [];
|
||||
$: 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;
|
||||
const donations_promise = DonationService.donationControllerGetAll().then(
|
||||
(val) => {
|
||||
current_donations = val;
|
||||
}
|
||||
);
|
||||
|
||||
function should_display_based_on_id(id) {
|
||||
if (searchvalue.toString().slice(-1) === "*") {
|
||||
return id.toString().startsWith(searchvalue.replace("*", ""));
|
||||
@@ -26,210 +24,250 @@
|
||||
function open_payment_modal(donation) {
|
||||
editable = Object.assign({}, donation);
|
||||
original_data = Object.assign({}, donation);
|
||||
paid_amount_input = (donation.paidAmount/100).toFixed(2);
|
||||
paid_amount_input = (donation.paidAmount / 100).toFixed(2);
|
||||
payment_modal_open = true;
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
let page = 0;
|
||||
while (page >= 0) {
|
||||
const donations = await DonationService.donationControllerGetAll(
|
||||
page,
|
||||
500
|
||||
);
|
||||
if (donations.length == 0) {
|
||||
page = -2;
|
||||
}
|
||||
|
||||
current_donations = current_donations.concat(...donations);
|
||||
|
||||
dataLoaded = true;
|
||||
page++;
|
||||
}
|
||||
console.log("All donations loaded");
|
||||
});
|
||||
</script>
|
||||
|
||||
<AddDonationPaymentModal bind:current_donations bind:original_data bind:editable bind:paid_amount_input bind:payment_modal_open />
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')}
|
||||
{#await donations_promise}
|
||||
<AddDonationPaymentModal
|
||||
bind:current_donations
|
||||
bind:original_data
|
||||
bind:editable
|
||||
bind:paid_amount_input
|
||||
bind:payment_modal_open
|
||||
/>
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:GET")}
|
||||
{#if !dataLoaded}
|
||||
<div
|
||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||
role="alert">
|
||||
role="alert"
|
||||
>
|
||||
<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>
|
||||
{:then}
|
||||
{#if current_donations.length === 0}
|
||||
<DonationsEmptyState />
|
||||
{:else}
|
||||
<input
|
||||
type="search"
|
||||
bind:value={searchvalue}
|
||||
placeholder={$_('datatable.search')}
|
||||
aria-label={$_('datatable.search')}
|
||||
class="mb-4" />
|
||||
<div
|
||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
||||
<table class="divide-y divide-gray-200 w-full">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('donor')}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('runner')}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
{$_('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>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
{#each current_donations as donation}
|
||||
{#if donation.donor.firstname
|
||||
{:else if current_donations.length === 0}
|
||||
<DonationsEmptyState />
|
||||
{:else}
|
||||
<input
|
||||
type="search"
|
||||
bind:value={searchvalue}
|
||||
placeholder={$_("datatable.search")}
|
||||
aria-label={$_("datatable.search")}
|
||||
class="mb-4"
|
||||
/>
|
||||
<div
|
||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"
|
||||
>
|
||||
<table class="divide-y divide-gray-200 w-full">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
{$_("donor")}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
{$_("runner")}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
{$_("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>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
{#each current_donations as donation}
|
||||
{#if donation.donor.firstname
|
||||
.toLowerCase()
|
||||
.includes(searchvalue.toLowerCase()) || donation.donor.lastname
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
searchvalue.toLowerCase()
|
||||
) || donation.donor.lastname
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
searchvalue.toLowerCase()
|
||||
) || donation.runner?.firstname
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
searchvalue.toLowerCase()
|
||||
) || donation.runner?.lastname
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
searchvalue.toLowerCase()
|
||||
) || should_display_based_on_id(donation.id)}
|
||||
<tr data-rowid="donation_{donation.id}">
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
.includes(searchvalue.toLowerCase()) || donation.runner?.firstname
|
||||
.toLowerCase()
|
||||
.includes(searchvalue.toLowerCase()) || donation.runner?.lastname
|
||||
.toLowerCase()
|
||||
.includes(searchvalue.toLowerCase()) || should_display_based_on_id(donation.id)}
|
||||
<tr data-rowid="donation_{donation.id}">
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
<a
|
||||
href="../donors/{donation.donor.id}"
|
||||
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 class="px-6 py-4 whitespace-nowrap">
|
||||
{#if donation.runner}
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
<a
|
||||
href="../donors/{donation.donor.id}"
|
||||
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>
|
||||
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>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
{#if donation.runner}
|
||||
<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>
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{$_("fixed-donation")}
|
||||
</div>
|
||||
{/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>
|
||||
</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}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/await}
|
||||
{/if}
|
||||
{/if}
|
||||
@@ -50,7 +50,6 @@
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
//Section table
|
||||
const columns = [
|
||||
{
|
||||
@@ -157,16 +156,7 @@
|
||||
}).showToast();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
RunnerService.runnerControllerGetAll().then((val) => {
|
||||
current_runners = val;
|
||||
dataLoaded = true;
|
||||
|
||||
options.update((options) => ({
|
||||
...options,
|
||||
data: current_runners,
|
||||
}));
|
||||
});
|
||||
onMount(async () => {
|
||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||
teams = val;
|
||||
});
|
||||
@@ -175,6 +165,24 @@
|
||||
orgs = val;
|
||||
}
|
||||
);
|
||||
|
||||
let page = 0;
|
||||
while (page >= 0) {
|
||||
const runners = await RunnerService.runnerControllerGetAll(page, 1000);
|
||||
if (runners.length == 0) {
|
||||
page = -2;
|
||||
}
|
||||
|
||||
current_runners = current_runners.concat(...runners);
|
||||
options.update((options) => ({
|
||||
...options,
|
||||
data: current_runners,
|
||||
}));
|
||||
|
||||
dataLoaded = true;
|
||||
page++;
|
||||
}
|
||||
console.log("All runners loaded");
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
$table?.getSelectedRowModel().rows.map((row) => row.index) || [];
|
||||
|
||||
$: active_delete = undefined;
|
||||
$: dataLoaded = false;
|
||||
export let current_scans = [];
|
||||
export const addScans = (scans) => {
|
||||
current_scans = current_scans.concat(...scans);
|
||||
@@ -39,15 +40,6 @@
|
||||
}));
|
||||
};
|
||||
|
||||
const scans_promise = ScanService.scanControllerGetAll().then((val) => {
|
||||
current_scans = val;
|
||||
// handler.setRows(val);
|
||||
current_scans = val;
|
||||
options.update((options) => ({
|
||||
...options,
|
||||
data: current_scans,
|
||||
}));
|
||||
});
|
||||
let allTracks = [];
|
||||
TrackService.trackControllerGetAll().then((val) => {
|
||||
allTracks = val;
|
||||
@@ -99,7 +91,7 @@
|
||||
accessorKey: "timestamp",
|
||||
header: () => $_("timestamp"),
|
||||
cell: (info) => {
|
||||
return (new Date(parseInt(info.getValue())*1000)).toLocaleString()
|
||||
return new Date(parseInt(info.getValue()) * 1000).toLocaleString();
|
||||
},
|
||||
enableColumnFilter: false,
|
||||
},
|
||||
@@ -183,6 +175,26 @@
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
let page = 0;
|
||||
while (page >= 0) {
|
||||
const scans = await ScanService.scanControllerGetAll(page, 500);
|
||||
if (scans.length == 0) {
|
||||
page = -2;
|
||||
}
|
||||
|
||||
current_scans = current_scans.concat(...scans);
|
||||
options.update((options) => ({
|
||||
...options,
|
||||
data: current_scans,
|
||||
}));
|
||||
|
||||
dataLoaded = true;
|
||||
page++;
|
||||
}
|
||||
console.log("All scans loaded");
|
||||
});
|
||||
</script>
|
||||
|
||||
<DeleteScanModal
|
||||
@@ -193,7 +205,7 @@
|
||||
}}
|
||||
/>
|
||||
{#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:GET")}
|
||||
{#await scans_promise}
|
||||
{#if !dataLoaded}
|
||||
<div
|
||||
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
|
||||
role="alert"
|
||||
@@ -201,105 +213,96 @@
|
||||
<p class="font-bold">{$_("scans-are-being-loaded")}</p>
|
||||
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
|
||||
</div>
|
||||
{:then}
|
||||
{#if current_scans.length === 0}
|
||||
<ScansEmptyState />
|
||||
{:else}
|
||||
{#if selected.length > 0}
|
||||
<button
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex"
|
||||
id="options-menu"
|
||||
on:click={async () => {
|
||||
const prom = [];
|
||||
for (const scan of selectedScans) {
|
||||
prom.push(ScanService.scanControllerRemove(scan.id, true));
|
||||
}
|
||||
await Promise.all(prom);
|
||||
for (const scan of selectedScans) {
|
||||
current_scans = current_scans.filter((r) => r.id !== scan.id);
|
||||
}
|
||||
options.update((options) => ({
|
||||
...options,
|
||||
data: current_scans,
|
||||
}));
|
||||
$table.resetRowSelection();
|
||||
Toastify({
|
||||
text: $_("scan-deleted"),
|
||||
duration: 3500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
}}
|
||||
{:else if current_scans.length === 0}
|
||||
<ScansEmptyState />
|
||||
{:else}
|
||||
{#if selected.length > 0}
|
||||
<button
|
||||
type="button"
|
||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex"
|
||||
id="options-menu"
|
||||
on:click={async () => {
|
||||
const prom = [];
|
||||
for (const scan of selectedScans) {
|
||||
prom.push(ScanService.scanControllerRemove(scan.id, true));
|
||||
}
|
||||
await Promise.all(prom);
|
||||
for (const scan of selectedScans) {
|
||||
current_scans = current_scans.filter((r) => r.id !== scan.id);
|
||||
}
|
||||
options.update((options) => ({
|
||||
...options,
|
||||
data: current_scans,
|
||||
}));
|
||||
$table.resetRowSelection();
|
||||
Toastify({
|
||||
text: $_("scan-deleted"),
|
||||
duration: 3500,
|
||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||
}).showToast();
|
||||
}}
|
||||
>
|
||||
{$_("delete-scans")}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-5 h-5"
|
||||
>
|
||||
{$_("delete-scans")}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-5 h-5"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
{/if}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
{#each $table.getHeaderGroups() as headerGroup}
|
||||
<tr class="select-none">
|
||||
<th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
|
||||
<InputElement
|
||||
type="checkbox"
|
||||
checked={$table.getIsAllRowsSelected()}
|
||||
indeterminate={$table.getIsSomeRowsSelected()}
|
||||
on:change={() => $table.toggleAllRowsSelected()}
|
||||
/>
|
||||
</th>
|
||||
{#each headerGroup.headers as header}
|
||||
<TableHeader {header} />
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each $table.getRowModel().rows as row}
|
||||
<tr>
|
||||
<td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
|
||||
<InputElement
|
||||
type="checkbox"
|
||||
checked={row.getIsSelected()}
|
||||
on:change={() => row.toggleSelected()}
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
{/if}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
{#each $table.getHeaderGroups() as headerGroup}
|
||||
<tr class="select-none">
|
||||
<th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
|
||||
<InputElement
|
||||
type="checkbox"
|
||||
checked={$table.getIsAllRowsSelected()}
|
||||
indeterminate={$table.getIsSomeRowsSelected()}
|
||||
on:change={() => $table.toggleAllRowsSelected()}
|
||||
/>
|
||||
</th>
|
||||
{#each headerGroup.headers as header}
|
||||
<TableHeader {header} />
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each $table.getRowModel().rows as row}
|
||||
<tr>
|
||||
<td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
|
||||
<InputElement
|
||||
type="checkbox"
|
||||
checked={row.getIsSelected()}
|
||||
on:change={() => row.toggleSelected()}
|
||||
/>
|
||||
</td>
|
||||
{#each row.getVisibleCells() as cell}
|
||||
<td>
|
||||
<svelte:component
|
||||
this={flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext()
|
||||
)}
|
||||
/>
|
||||
</td>
|
||||
{#each row.getVisibleCells() as cell}
|
||||
<td>
|
||||
<svelte:component
|
||||
this={flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext()
|
||||
)}
|
||||
/>
|
||||
</td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<TableBottom {table} {selected} />
|
||||
{/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>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/await}
|
||||
<TableBottom {table} {selected} />
|
||||
{/if}
|
||||
{/if}
|
||||
@@ -1,14 +1,18 @@
|
||||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
import Toastify from "toastify-js";
|
||||
import { tick, createEventDispatcher } from "svelte";
|
||||
import bwipjs from "bwip-js";
|
||||
|
||||
export let copy_modal_open;
|
||||
export let new_station;
|
||||
const dispatch = createEventDispatcher();
|
||||
let valueCopy = null;
|
||||
let areaDom;
|
||||
let copied = false;
|
||||
$: is_qrcode = false;
|
||||
$: barcode = textToBase64Barcode(new_station.key, is_qrcode);
|
||||
|
||||
function close() {
|
||||
copy_modal_open = false;
|
||||
}
|
||||
@@ -36,10 +40,30 @@
|
||||
"linear-gradient(90deg, hsla(281, 37%, 45%, 1) 0%, hsla(1, 62%, 48%, 1) 100%)",
|
||||
}).showToast();
|
||||
}
|
||||
|
||||
// we can notifi by event or storage about copy status
|
||||
valueCopy = null;
|
||||
}
|
||||
|
||||
function textToBase64Barcode(text, is_qrcode) {
|
||||
const canvas = document.createElement("canvas");
|
||||
let bcid = "code128";
|
||||
if (is_qrcode) {
|
||||
bcid = "qrcode";
|
||||
}
|
||||
let codeconfig = {
|
||||
bcid,
|
||||
text: `${text}`,
|
||||
scale: 4,
|
||||
includetext: true,
|
||||
textxalign: "center",
|
||||
backgroundcolor: "ffffff",
|
||||
};
|
||||
if (bcid == "code128") {
|
||||
codeconfig.height = 10;
|
||||
}
|
||||
bwipjs.toCanvas(canvas, codeconfig);
|
||||
return canvas.toDataURL("image/png");
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if copy_modal_open}
|
||||
@@ -131,6 +155,44 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-auto text-center items-center">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
{$_("config-codes")}
|
||||
</h2>
|
||||
<span class="flex items-center text-center">
|
||||
<p class="text-md text-gray-900 mr-3">Format:</p>
|
||||
<label for="codeswitch" class="text-md text-gray-900 mr-3"
|
||||
>Code128</label
|
||||
>
|
||||
<input
|
||||
id="codeswitch"
|
||||
type="checkbox"
|
||||
bind:checked={is_qrcode}
|
||||
class="relative shrink-0 w-[3.25rem] h-7 bg-gray-100 checked:bg-none checked:bg-blue-600 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 border border-transparent ring-1 ring-transparent focus:border-blue-600 focus:ring-blue-600 ring-offset-white focus:outline-none appearance-none before:inline-block before:w-6 before:h-6 before:bg-white checked:before:bg-blue-200 before:translate-x-0 checked:before:translate-x-full before:shadow before:rounded-full before:transform before:ring-0 before:transition before:ease-in-out before:duration-200 dark:before:bg-gray-400 dark:checked:before:bg-blue-200"
|
||||
/>
|
||||
<label for="codeswitch" class="text-md text-gray-900 ml-3"
|
||||
>QR-Code</label
|
||||
>
|
||||
</span>
|
||||
<h3 class="leading-6 font-medium text-gray-900">
|
||||
{$_("api-endpoint")}
|
||||
</h3>
|
||||
<img
|
||||
class:w-[50%]={is_qrcode}
|
||||
class:w-full={!is_qrcode}
|
||||
class="md:w-auto mb-2 mx-auto"
|
||||
alt="Registrierungscode"
|
||||
src={textToBase64Barcode(config.baseurl, is_qrcode)}
|
||||
/>
|
||||
<h3 class="leading-6 font-medium text-gray-900">{$_("token")}</h3>
|
||||
<img
|
||||
class:w-[50%]={is_qrcode}
|
||||
class:w-full={!is_qrcode}
|
||||
class="md:w-auto mb-2 mx-auto"
|
||||
alt="Registrierungscode"
|
||||
src={barcode}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
<button
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
"amount": "Anzahl",
|
||||
"amount-per-kilometer": "Betrag pro Kilometer",
|
||||
"apartment-suite-etc": "Apartment, Wohnung, etc.",
|
||||
"api-endpoint": "API-Endpunkt",
|
||||
"application_name": "Lauf für Kaya! - Admin",
|
||||
"applying-changes": "Änderungen anwenden",
|
||||
"attention": "Achtung!",
|
||||
@@ -68,6 +69,7 @@
|
||||
"click-to-copy-token-to-clipboard": "Klicke auf den Token, um ihn in deine Zwischenablage zu kopieren",
|
||||
"close": "Schließen",
|
||||
"code": "Code",
|
||||
"config-codes": "Konfigurations-Codes",
|
||||
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
|
||||
"confirm": "Bestätigen",
|
||||
"confirm-delete": "Löschung Bestätigen",
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
"amount": "Amount",
|
||||
"amount-per-kilometer": "Amount per kilometer",
|
||||
"apartment-suite-etc": "Apartment, suite, etc.",
|
||||
"api-endpoint": "API-Endpoint",
|
||||
"application_name": "Lauf für Kaya! - Admin",
|
||||
"applying-changes": "Applying Changes",
|
||||
"attention": "Attention!",
|
||||
@@ -68,6 +69,7 @@
|
||||
"click-to-copy-token-to-clipboard": "Click to copy the token to your clipboard",
|
||||
"close": "Close",
|
||||
"code": "Code",
|
||||
"config-codes": "Config codes",
|
||||
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
|
||||
"confirm": "Confirm",
|
||||
"confirm-delete": "Confirm Delete",
|
||||
|
||||
Reference in new issue
Block a user