Merge branch 'dev' of git.odit.services:lfk/selfservice into dev
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Nicolai Ort 2023-02-01 17:48:52 +01:00
commit 20c6a420e9
Signed by: niggl
GPG Key ID: 13AFA55AF62F269F
4 changed files with 403 additions and 267 deletions

View File

@ -2,9 +2,18 @@
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.
#### [0.7.9](https://git.odit.services/lfk/selfservice/compare/0.7.8...0.7.9)
- migrate to bwip-js [`8cfddb5`](https://git.odit.services/lfk/selfservice/commit/8cfddb502964be7edf45cdc524344ea2f7f20142)
- fix codeconfig.height [`9b261bf`](https://git.odit.services/lfk/selfservice/commit/9b261bf20023561a7c9691dff33c9a6d2b5c0cac)
- drop jsbarcode [`713dd15`](https://git.odit.services/lfk/selfservice/commit/713dd153126851e8cf1045bf5ba3ca702a39c738)
#### [0.7.8](https://git.odit.services/lfk/selfservice/compare/0.7.7...0.7.8) #### [0.7.8](https://git.odit.services/lfk/selfservice/compare/0.7.7...0.7.8)
> 1 February 2023
- add barcode to profile [`851190e`](https://git.odit.services/lfk/selfservice/commit/851190e6a7f8b9cccbf05e60f9b50b96c196959c) - add barcode to profile [`851190e`](https://git.odit.services/lfk/selfservice/commit/851190e6a7f8b9cccbf05e60f9b50b96c196959c)
- 🚀Bumped version to v0.7.8 [`e5a01bc`](https://git.odit.services/lfk/selfservice/commit/e5a01bcd7629164655cacd10dd1f014260c67c4b)
- certificate generation: success toast styling [`1603a09`](https://git.odit.services/lfk/selfservice/commit/1603a097f71ed85c901baf8da04cb06b86474649) - certificate generation: success toast styling [`1603a09`](https://git.odit.services/lfk/selfservice/commit/1603a097f71ed85c901baf8da04cb06b86474649)
#### [0.7.7](https://git.odit.services/lfk/selfservice/compare/0.7.6...0.7.7) #### [0.7.7](https://git.odit.services/lfk/selfservice/compare/0.7.6...0.7.7)

View File

@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-selfservice", "name": "@odit/lfk-selfservice",
"version": "0.7.8", "version": "0.7.9",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
@ -13,22 +13,22 @@
"redaxios": "0.4.1", "redaxios": "0.4.1",
"toastify-js": "1.10.0", "toastify-js": "1.10.0",
"validator": "13.5.2", "validator": "13.5.2",
"vue": "3.0.9",
"vue-i18n": "9.1.4", "vue-i18n": "9.1.4",
"vue-router": "4.0.5", "vue-toastification": "2.0.0-rc.1",
"vue-toastification": "2.0.0-rc.1" "vue": "3.0.9",
"vue-router": "4.0.5"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/jit": "0.1.18",
"@tailwindcss/aspect-ratio": "0.2.0", "@tailwindcss/aspect-ratio": "0.2.0",
"@tailwindcss/forms": "0.3.2", "@tailwindcss/forms": "0.3.2",
"@tailwindcss/jit": "0.1.18",
"@tailwindcss/line-clamp": "0.2.0", "@tailwindcss/line-clamp": "0.2.0",
"@tailwindcss/typography": "0.4.0", "@tailwindcss/typography": "0.4.0",
"@vitejs/plugin-vue": "1.2.1", "@vitejs/plugin-vue": "1.2.1",
"@vue/compiler-sfc": "3.0.11", "@vue/compiler-sfc": "3.0.11",
"autoprefixer": "10.2.5", "autoprefixer": "10.2.5",
"release-it": "14.6.1",
"tailwindcss": "2.1.1", "tailwindcss": "2.1.1",
"release-it": "14.6.1",
"vite": "2.1.5" "vite": "2.1.5"
}, },
"release-it": { "release-it": {

View File

@ -7,6 +7,8 @@ const config = {
baseurl_selfservice: '/selfservice/', baseurl_selfservice: '/selfservice/',
// full url (including fqdn) // full url (including fqdn)
baseurl_documentserver: 'http://localhost:4010/documents', baseurl_documentserver: 'http://localhost:4010/documents',
// optional, will fallback to code128
code_format: 'ean13',
// optional, will fallback to baseurl_selfservice/imprint // optional, will fallback to baseurl_selfservice/imprint
url_imprint: '', url_imprint: '',
// optional, will fallback to baseurl_selfservice/privacy // optional, will fallback to baseurl_selfservice/privacy

View File

@ -2,141 +2,115 @@
<div class="min-h-screen w-full p-4"> <div class="min-h-screen w-full p-4">
<section class="text-white body-font"> <section class="text-white body-font">
<div class="container mx-auto flex items-center md:flex-row flex-col"> <div class="container mx-auto flex items-center md:flex-row flex-col">
<div <div class="
class="flex flex-col md:pr-10 md:mb-0 mb-6 pr-0 w-full md:w-auto md:text-left text-center text-black dark:text-gray-200" flex flex-col
> md:pr-10 md:mb-0
<p mb-6
class="text-3xl font-bold whitespace-nowrap" pr-0
v-text="(state.firstname || '') + ' ' + (state.middlename || '') + ' ' + (state.lastname || '')" w-full
></p> md:w-auto md:text-left
text-center text-black
dark:text-gray-200
">
<p class="text-3xl font-bold whitespace-nowrap" v-text="
(state.firstname || '') +
' ' +
(state.middlename || '') +
' ' +
(state.lastname || '')
"></p>
<p class="text-md whitespace-nowrap">{{ state.group }}</p> <p class="text-md whitespace-nowrap">{{ state.group }}</p>
</div> </div>
<div class="inline-flex md:ml-auto md:mr-0 mx-auto items-center"> <div class="inline-flex md:ml-auto md:mr-0 mx-auto items-center">
<div v-if="(state.delete_active === false)"> <div v-if="state.delete_active === false">
<button <button type="button"
type="button"
class="focus:border-black focus:ring-2 focus:ring-black text-white text-sm py-2.5 px-5 rounded-md bg-blue-500 hover:bg-blue-600 hover:shadow-lg" class="focus:border-black focus:ring-2 focus:ring-black text-white text-sm py-2.5 px-5 rounded-md bg-blue-500 hover:bg-blue-600 hover:shadow-lg"
@click="get_registration" @click="get_registration">
> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
<svg stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
xmlns="http://www.w3.org/2000/svg" class="feather feather-download" style="display: inline;height: 1rem;vertical-align: sub;">
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-download"
style="display: inline;height: 1rem;vertical-align: sub;"
>
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /> <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
<polyline points="7 10 12 15 17 10" /> <polyline points="7 10 12 15 17 10" />
<line x1="12" y1="15" x2="12" y2="3" /> <line x1="12" y1="15" x2="12" y2="3" />
</svg> </svg>
{{ $t('download registrationcode') }} {{ $t('download registrationcode') }}
</button> </button>
<button <button type="button"
type="button"
class="focus:border-black focus:ring-2 focus:ring-black text-white text-sm py-2.5 px-5 rounded-md bg-blue-500 hover:bg-blue-600 hover:shadow-lg" class="focus:border-black focus:ring-2 focus:ring-black text-white text-sm py-2.5 px-5 rounded-md bg-blue-500 hover:bg-blue-600 hover:shadow-lg"
@click="get_certificate" @click="get_certificate">
> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
<svg stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
xmlns="http://www.w3.org/2000/svg" class="feather feather-download" style="display: inline; height: 1rem; vertical-align: sub">
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-download"
style="display: inline;height: 1rem;vertical-align: sub;"
>
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /> <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
<polyline points="7 10 12 15 17 10" /> <polyline points="7 10 12 15 17 10" />
<line x1="12" y1="15" x2="12" y2="3" /> <line x1="12" y1="15" x2="12" y2="3" />
</svg> </svg>
{{ $t('download_certificate') }} {{ $t("download_certificate") }}
</button> </button>
<button <button type="button" class="
type="button" focus:border-black focus:ring-2 focus:ring-black
class="focus:border-black focus:ring-2 focus:ring-black text-white text-sm py-2.5 px-5 rounded-md bg-red-600 hover:bg-red-700 hover:shadow-lg ml-1" text-white text-sm
@click="() => { state.delete_active = true }" py-2.5
> px-5
<svg rounded-md
xmlns="http://www.w3.org/2000/svg" bg-red-600
width="24" hover:bg-red-700 hover:shadow-lg
height="24" ml-1
viewBox="0 0 24 24" " @click="
fill="none" () => {
stroke="none" state.delete_active = true;
stroke-width="2" }
stroke-linecap="round" ">
stroke-linejoin="round" <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
class="feather feather-download" stroke="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
style="display: inline;height: 1rem;vertical-align: sub;" class="feather feather-download" style="display: inline; height: 1rem; vertical-align: sub">
>
<path d="M0 0h24v24H0z" /> <path d="M0 0h24v24H0z" />
<path <path fill="currentColor"
fill="currentColor" d="M17 6h5v2h-2v13a1 1 0 01-1 1H5a1 1 0 01-1-1V8H2V6h5V3a1 1 0 011-1h8a1 1 0 011 1v3zm1 2H6v12h12V8zm-5 6l2 2-1 1-2-2-2 2-1-1 2-2-2-2 1-1 2 2 2-2 1 1-2 2zM9 4v2h6V4H9z" />
d="M17 6h5v2h-2v13a1 1 0 01-1 1H5a1 1 0 01-1-1V8H2V6h5V3a1 1 0 011-1h8a1 1 0 011 1v3zm1 2H6v12h12V8zm-5 6l2 2-1 1-2-2-2 2-1-1 2-2-2-2 1-1 2 2 2-2 1 1-2 2zM9 4v2h6V4H9z"
/>
</svg> </svg>
{{ $t('delete_my_data') }} {{ $t("delete_my_data") }}
</button> </button>
</div> </div>
<div v-if="(state.delete_active === true)"> <div v-if="state.delete_active === true">
<button <button type="button" class="
type="button" focus:border-black focus:ring-2 focus:ring-black
class="focus:border-black focus:ring-2 focus:ring-black text-white text-sm py-2.5 px-5 rounded-md bg-blue-500 hover:bg-blue-600 hover:shadow-lg" text-white text-sm
@click="() => { state.delete_active = false }" py-2.5
> px-5
<svg rounded-md
xmlns="http://www.w3.org/2000/svg" bg-blue-500
width="24" hover:bg-blue-600 hover:shadow-lg
height="24" " @click="
viewBox="0 0 24 24" () => {
fill="none" state.delete_active = false;
stroke="none" }
stroke-width="2" ">
stroke-linecap="round" <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke-linejoin="round" stroke="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-download" class="feather feather-download" style="display: inline; height: 1rem; vertical-align: sub">
style="display: inline;height: 1rem;vertical-align: sub;"
>
<path fill="none" d="M0 0h24v24H0z" /> <path fill="none" d="M0 0h24v24H0z" />
<path fill="currentColor" d="M12 11l5-5 1 1-5 5 5 5-1 1-5-5-5 5-1-1 5-5-5-5 1-1z" /> <path fill="currentColor" d="M12 11l5-5 1 1-5 5 5 5-1 1-5-5-5 5-1-1 5-5-5-5 1-1z" />
</svg> </svg>
{{ $t('cancel_keep_my_data') }} {{ $t("cancel_keep_my_data") }}
</button> </button>
<button <button type="button" class="
type="button" focus:border-black focus:ring-2 focus:ring-black
class="focus:border-black focus:ring-2 focus:ring-black text-white text-sm py-2.5 px-5 rounded-md bg-red-600 hover:bg-red-700 hover:shadow-lg ml-1" text-white text-sm
@click="delete_me" py-2.5
> px-5
<svg rounded-md
xmlns="http://www.w3.org/2000/svg" bg-red-600
width="24" hover:bg-red-700 hover:shadow-lg
height="24" ml-1
viewBox="0 0 24 24" " @click="delete_me">
fill="none" <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="none" stroke="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" class="feather feather-download" style="display: inline; height: 1rem; vertical-align: sub">
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-download"
style="display: inline;height: 1rem;vertical-align: sub;"
>
<path d="M0 0h24v24H0z" /> <path d="M0 0h24v24H0z" />
<path <path fill="currentColor"
fill="currentColor" d="M17 6h5v2h-2v13a1 1 0 01-1 1H5a1 1 0 01-1-1V8H2V6h5V3a1 1 0 011-1h8a1 1 0 011 1v3zm1 2H6v12h12V8zm-5 6l2 2-1 1-2-2-2 2-1-1 2-2-2-2 1-1 2 2 2-2 1 1-2 2zM9 4v2h6V4H9z" />
d="M17 6h5v2h-2v13a1 1 0 01-1 1H5a1 1 0 01-1-1V8H2V6h5V3a1 1 0 011-1h8a1 1 0 011 1v3zm1 2H6v12h12V8zm-5 6l2 2-1 1-2-2-2 2-1-1 2-2-2-2 1-1 2 2 2-2 1 1-2 2zM9 4v2h6V4H9z"
/>
</svg> </svg>
{{ $t('confirm_delete_all_of_my_data') }} {{ $t("confirm_delete_all_of_my_data") }}
</button> </button>
</div> </div>
</div> </div>
@ -147,96 +121,181 @@
<div class="flex flex-wrap flex-col w-full tabs"> <div class="flex flex-wrap flex-col w-full tabs">
<div class="flex lg:flex-wrap flex-row lg:space-x-2"> <div class="flex lg:flex-wrap flex-row lg:space-x-2">
<div class="flex-none"> <div class="flex-none">
<button <button @click="
@click="() => { state.activetab = 'profile' }" () => {
:class="{ 'tab-active border-b-2 font-medium border-blue-500': (state.activetab === 'profile') }" state.activetab = 'profile';
class="tab tab-underline py-4 px-6 block" }
type="button" " :class="{
>{{ $t('profile') }}</button> 'tab-active border-b-2 font-medium border-blue-500':
state.activetab === 'profile',
}" class="tab tab-underline py-4 px-6 block" type="button">
{{ $t("profile") }}
</button>
</div> </div>
<div class="flex-none"> <div class="flex-none">
<button <button @click="
@click="() => { state.activetab = 'laptimes' }" () => {
:class="{ 'tab-active border-b-2 font-medium border-blue-500': (state.activetab === 'laptimes') }" state.activetab = 'laptimes';
class="tab tab-underline py-4 px-6 block" }
type="button" " :class="{
>{{ $t('lap_times') }}</button> 'tab-active border-b-2 font-medium border-blue-500':
state.activetab === 'laptimes',
}" class="tab tab-underline py-4 px-6 block" type="button">
{{ $t("lap_times") }}
</button>
</div> </div>
<div class="flex-none"> <div class="flex-none">
<button <button @click="
@click="() => { state.activetab = 'sponsorings' }" () => {
:class="{ 'tab-active border-b-2 font-medium border-blue-500': (state.activetab === 'sponsorings') }" state.activetab = 'sponsorings';
class="tab tab-underline py-4 px-6 block" }
type="button" " :class="{
>{{ $t('sponsoring') }}</button> 'tab-active border-b-2 font-medium border-blue-500':
state.activetab === 'sponsorings',
}" class="tab tab-underline py-4 px-6 block" type="button">
{{ $t("sponsoring") }}
</button>
</div> </div>
</div> </div>
<div v-if="(state.activetab === 'profile')" class="tab-content block"> <div v-if="state.activetab === 'profile'" class="tab-content block">
<div class="py-4 w-full"> <div class="py-4 w-full">
<div class="flex flex-col"> <div class="flex flex-col">
<form class="form flex flex-wrap w-full"> <form class="form flex flex-wrap w-full">
<div class="w-full"> <div class="w-full">
<div class="form-element"> <div class="form-element">
<div class="text-lg">{{ $t('registrierungscode') }}</div> <div class="text-lg">{{ $t("registrierungscode") }}</div>
<img alt="Registrierungscode" :src="state.barcode"> <img alt="Registrierungscode" :src="state.barcode" />
<div class="text-lg">{{ $t('vorname') }}</div> <div class="text-lg">{{ $t("vorname") }}</div>
<p <p class="
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" h-10
v-text="state.firstname" w-full
/> dark:bg-gray-800
rounded
text-base
outline-none
dark:text-gray-100
text-gray-600
py-1
px-3
leading-8
transition-colors
duration-200
ease-in-out
" v-text="state.firstname" />
</div> </div>
<div class="form-element"> <div class="form-element">
<div class="text-lg">{{ $t('mittelname') }}</div> <div class="text-lg">{{ $t("mittelname") }}</div>
<p <p class="
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" h-10
v-text="state.middlename" w-full
/> dark:bg-gray-800
rounded
text-base
outline-none
dark:text-gray-100
text-gray-600
py-1
px-3
leading-8
transition-colors
duration-200
ease-in-out
" v-text="state.middlename" />
</div> </div>
<div class="form-element"> <div class="form-element">
<div class="text-lg">{{ $t('nachname') }}</div> <div class="text-lg">{{ $t("nachname") }}</div>
<p <p class="
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" h-10
v-text="state.lastname" w-full
/> dark:bg-gray-800
rounded
text-base
outline-none
dark:text-gray-100
text-gray-600
py-1
px-3
leading-8
transition-colors
duration-200
ease-in-out
" v-text="state.lastname" />
</div> </div>
<div class="form-element"> <div class="form-element">
<div class="text-lg">{{ $t('e_mail_adress') }}</div> <div class="text-lg">{{ $t("e_mail_adress") }}</div>
<p <p class="
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" h-10
v-text="state.email" w-full
/> dark:bg-gray-800
rounded
text-base
outline-none
dark:text-gray-100
text-gray-600
py-1
px-3
leading-8
transition-colors
duration-200
ease-in-out
" v-text="state.email" />
</div> </div>
<div class="form-element"> <div class="form-element">
<div class="text-lg">{{ $t('phone_number') }}</div> <div class="text-lg">{{ $t("phone_number") }}</div>
<p <p class="
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" h-10
v-text="state.phone" w-full
/> dark:bg-gray-800
rounded
text-base
outline-none
dark:text-gray-100
text-gray-600
py-1
px-3
leading-8
transition-colors
duration-200
ease-in-out
" v-text="state.phone" />
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
<div v-if="(state.activetab === 'laptimes')" class="tab-content block"> <div v-if="state.activetab === 'laptimes'" class="tab-content block">
<div class="py-4 w-full"> <div class="py-4 w-full">
<section class="text-gray-400 dark:bg-gray-900 body-font"> <section class="text-gray-400 dark:bg-gray-900 body-font">
<div class="container mx-auto"> <div class="container mx-auto">
<div class="lg:w-2/3 w-full mx-auto overflow-auto"> <div class="lg:w-2/3 w-full mx-auto overflow-auto">
<table <table v-if="state.scans.length > 0" class="table-auto w-full text-left whitespace-no-wrap">
v-if="state.scans.length > 0" <thead class="
class="table-auto w-full text-left whitespace-no-wrap" text-black
> bg-gray-300
<thead dark:text-white
class="text-black bg-gray-300 dark:text-white text-sm dark:bg-gray-800" text-sm
> dark:bg-gray-800
">
<tr> <tr>
<th <th class="
class="px-4 py-3 title-font tracking-wider font-medium" px-4
>{{ $t('distance') }}</th> py-3
<th title-font
class="px-4 py-3 title-font tracking-wider font-medium" tracking-wider
>{{ $t('lap_time') }}</th> font-medium
">
{{ $t("distance") }}
</th>
<th class="
px-4
py-3
title-font
tracking-wider
font-medium
">
{{ $t("lap_time") }}
</th>
</tr> </tr>
</thead> </thead>
<tbody class="text-gray-900 dark:text-gray-50"> <tbody class="text-gray-900 dark:text-gray-50">
@ -248,39 +307,63 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div v-else class="text-center font-bold text-black dark:text-white text-2xl"> <div v-else class="
<img text-center
src="../assets/empty_laps.svg" font-bold
style="height:25rem; margin:0 auto;" text-black
:alt="[[$t('no_laps_scans_were_recorded_yet')]]" dark:text-white
/> text-2xl
{{ $t('no_laps_scans_were_recorded_yet') }} ">
<img src="../assets/empty_laps.svg" style="height: 25rem; margin: 0 auto"
:alt="[[$t('no_laps_scans_were_recorded_yet')]]" />
{{ $t("no_laps_scans_were_recorded_yet") }}
</div> </div>
</div> </div>
</div> </div>
</section> </section>
</div> </div>
</div> </div>
<div v-if="(state.activetab === 'sponsorings')" class="tab-content block"> <div v-if="state.activetab === 'sponsorings'" class="tab-content block">
<div class="py-4 w-full"> <div class="py-4 w-full">
<section class="text-gray-400 dark:bg-gray-900 body-font"> <section class="text-gray-400 dark:bg-gray-900 body-font">
<div class="container mx-auto"> <div class="container mx-auto">
<div class="lg:w-2/3 w-full mx-auto overflow-auto"> <div class="lg:w-2/3 w-full mx-auto overflow-auto">
<table <table v-if="state.sponsorings.length > 0" class="table-auto w-full text-left whitespace-no-wrap">
v-if="state.sponsorings.length > 0" <thead class="
class="table-auto w-full text-left whitespace-no-wrap" text-black
> bg-gray-300
<thead dark:text-white
class="text-black bg-gray-300 dark:text-white text-sm dark:bg-gray-800" text-sm
> dark:bg-gray-800
">
<tr> <tr>
<th class="px-4 py-3 title-font tracking-wider font-medium">Name</th> <th class="
<th px-4
class="px-4 py-3 title-font tracking-wider font-medium" py-3
>{{ $t('amount_per_kilometer_in_eur') }}</th> title-font
<th tracking-wider
class="px-4 py-3 title-font tracking-wider font-medium" font-medium
>{{ $t('current_total_amount_in_eur') }}</th> ">
Name
</th>
<th class="
px-4
py-3
title-font
tracking-wider
font-medium
">
{{ $t("amount_per_kilometer_in_eur") }}
</th>
<th class="
px-4
py-3
title-font
tracking-wider
font-medium
">
{{ $t("current_total_amount_in_eur") }}
</th>
</tr> </tr>
</thead> </thead>
<tbody class="text-gray-900 dark:text-gray-50"> <tbody class="text-gray-900 dark:text-gray-50">
@ -293,52 +376,68 @@
<span v-text="s.donor.lastname"></span> <span v-text="s.donor.lastname"></span>
</td> </td>
<td class="px-4 py-3"> <td class="px-4 py-3">
<span <span v-text="
v-text="(s.amountPerDistance / 100) (s.amountPerDistance / 100)
.toFixed(2) .toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })" .toLocaleString('de-DE', { valute: 'EUR' })
></span> "></span>
</td> </td>
<td class="px-4 py-3"> <td class="px-4 py-3">
<span <span v-text="
v-text="(s.amount / 100) (s.amount / 100)
.toFixed(2) .toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })" .toLocaleString('de-DE', { valute: 'EUR' })
></span> "></span>
</td> </td>
</tr> </tr>
</tbody> </tbody>
<tfoot class="text-gray-900 dark:text-gray-50"> <tfoot class="text-gray-900 dark:text-gray-50">
<tr> <tr>
<td class="px-4 py-3">{{ $t('total') }}</td> <td class="px-4 py-3">{{ $t("total") }}</td>
<td class="px-4 py-3"> <td class="px-4 py-3">
<span <span v-text="
v-text="(state.sponsorings.reduce(function(sum, current) { (
return sum + current.amountPerDistance; state.sponsorings.reduce(function (
}, 0) / 100) sum,
.toFixed(2) current
.toLocaleString('de-DE', { valute: 'EUR' })" ) {
></span> return sum + current.amountPerDistance;
},
0) / 100
)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })
"></span>
</td> </td>
<td class="px-4 py-3"> <td class="px-4 py-3">
<span <span v-text="
v-text="(state.sponsorings.reduce(function(sum, current) { (
return sum + current.amount; state.sponsorings.reduce(function (
}, 0) / 100) sum,
.toFixed(2) current
.toLocaleString('de-DE', { valute: 'EUR' })" ) {
></span> return sum + current.amount;
},
0) / 100
)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })
"></span>
</td> </td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
<div v-else class="text-center font-bold text-black dark:text-white text-2xl"> <div v-else class="
<img text-center
src="../assets/empty_laps.svg" font-bold
style="height:25rem; margin:0 auto;" text-black
:alt="[[$t('no_sponsorings_for_you_were_recorded_yet')]]" dark:text-white
/> text-2xl
{{ $t('no_sponsorings_for_you_were_recorded_yet') }} ">
<img src="../assets/empty_laps.svg" style="height: 25rem; margin: 0 auto" :alt="[
[$t('no_sponsorings_for_you_were_recorded_yet')],
]" />
{{ $t("no_sponsorings_for_you_were_recorded_yet") }}
</div> </div>
</div> </div>
</div> </div>
@ -357,18 +456,18 @@ import { TYPE, useToast } from "vue-toastification";
import axios from "redaxios"; import axios from "redaxios";
import bwipjs from "bwip-js"; import bwipjs from "bwip-js";
function textToBase64Barcode(text){ function textToBase64Barcode(text) {
var canvas = document.createElement("canvas"); var canvas = document.createElement("canvas");
bwipjs.toCanvas(canvas, bwipjs.toCanvas(canvas,
{ {
bcid: config.codeformat, bcid: config.codeformat || 'code39',
text: text, text: text,
scale: 4, scale: 3,
height: 10, height: 10,
// width: 10, // width: 10,
includetext: true, includetext: true,
textxalign: 'center', textxalign: 'center',
backgroundcolor: 'ffffff' backgroundcolor: 'ffffff'
} }
) )
return canvas.toDataURL("image/png"); return canvas.toDataURL("image/png");
@ -388,13 +487,13 @@ const state = reactive({
delete_active: false, delete_active: false,
fullobject: {} fullobject: {}
}) })
state.barcode = textToBase64Barcode("12345");
const toast = useToast(); const toast = useToast();
const props = defineProps({ const props = defineProps({
token: String token: String,
}) });
const accesstoken = atob(props.token); const accesstoken = atob(props.token);
axios.get(`${config.baseurl}api/runners/me/${accesstoken}`) axios
.get(`${config.baseurl}api/runners/me/${accesstoken}`)
.then(({ data }) => { .then(({ data }) => {
state.phone = data.phone; state.phone = data.phone;
state.email = data.email; state.email = data.email;
@ -404,26 +503,38 @@ axios.get(`${config.baseurl}api/runners/me/${accesstoken}`)
state.group = data.group; state.group = data.group;
state.sponsorings = data.distanceDonations; state.sponsorings = data.distanceDonations;
state.fullobject = data; state.fullobject = data;
state.barcode = textToBase64Barcode(state.fullobject.id); state.barcode = textToBase64Barcode(data.id);
}).catch((error) => {
toast.error("Profil konnte nicht geladen werden...");
}) })
axios.get(`${config.baseurl}api/runners/me/${accesstoken}/scans`) .catch((error) => {
toast.error("Profil konnte nicht geladen werden...");
});
axios
.get(`${config.baseurl}api/runners/me/${accesstoken}/scans`)
.then(({ data }) => { .then(({ data }) => {
data.map(function(s) { data.map(function (s) {
s.lapTime = Math.floor(s.lapTime / 60) + 'min ' + (Math.floor(s.lapTime % 60) + "").padStart(2, "0") + "s" s.lapTime =
s.distance = Math.floor(s.distance / 1000) + 'km ' + (Math.floor(s.distance % 1000) + "").padStart(3, "0") + "m" Math.floor(s.lapTime / 60) +
"min " +
(Math.floor(s.lapTime % 60) + "").padStart(2, "0") +
"s";
s.distance =
Math.floor(s.distance / 1000) +
"km " +
(Math.floor(s.distance % 1000) + "").padStart(3, "0") +
"m";
return s; return s;
}) });
data.filter(s => s.valid === true); data.filter((s) => s.valid === true);
state.scans = data; state.scans = data;
}).catch((error) => {
toast.error("Profil konnte nicht geladen werden...");
}) })
.catch((error) => {
toast.error("Profil konnte nicht geladen werden...");
});
function delete_me() { function delete_me() {
toast("Profil wird gelöscht..."); toast("Profil wird gelöscht...");
let url = `${config.baseurl}api/runners/me/${accesstoken}?force=true` let url = `${config.baseurl}api/runners/me/${accesstoken}?force=true`;
axios.delete(url) axios
.delete(url)
.then(() => { .then(() => {
toast("Alle Daten gelöscht!"); toast("Alle Daten gelöscht!");
location.replace(`${config.baseurl_selfservice}`); location.replace(`${config.baseurl_selfservice}`);
@ -434,31 +545,37 @@ function delete_me() {
} }
function get_certificate() { function get_certificate() {
toast("Urkunde wird generiert..."); toast("Urkunde wird generiert...");
const browserlocale = ((navigator.languages && navigator.languages[0]) || '').substr(0, 2); const browserlocale = (
(navigator.languages && navigator.languages[0]) ||
""
).substr(0, 2);
let url = `${config.baseurl_documentserver}certificates?locale=${browserlocale}&download=true&key=${config.documentserver_key}`; let url = `${config.baseurl_documentserver}certificates?locale=${browserlocale}&download=true&key=${config.documentserver_key}`;
let postdata = Object.assign({}, state.fullobject); let postdata = Object.assign({}, state.fullobject);
postdata.group = { postdata.group = {
name: postdata.group name: postdata.group,
} };
postdata = [postdata] postdata = [postdata];
axios.post(url, postdata, { axios
responseType: "blob" .post(url, postdata, {
}) responseType: "blob",
})
.then((response) => { .then((response) => {
console.log(response) console.log(response);
if (response.status != "200") { if (response.status != "200") {
toast.error("Urkunde konnte nicht generiert werden..."); toast.error("Urkunde konnte nicht generiert werden...");
} else { } else {
var fileURL = window.URL.createObjectURL(new Blob([response.data], { type: 'application/pdf' })); var fileURL = window.URL.createObjectURL(
var fileLink = document.createElement('a'); new Blob([response.data], { type: "application/pdf" })
);
var fileLink = document.createElement("a");
fileLink.href = fileURL; fileLink.href = fileURL;
fileLink.setAttribute('download', 'Certificate.pdf'); fileLink.setAttribute("download", "Certificate.pdf");
document.body.appendChild(fileLink); document.body.appendChild(fileLink);
fileLink.click(); fileLink.click();
fileLink.remove(); fileLink.remove();
toast("Urkunde generiert!",{type:TYPE.SUCCESS}); toast("Urkunde generiert!", { type: TYPE.SUCCESS });
} }
}) })
.catch((err) => { .catch((err) => {
@ -466,4 +583,12 @@ function get_certificate() {
toast.error("An error occured while generating your certificate"); toast.error("An error occured while generating your certificate");
}); });
} }
function get_registration() {
toast("Registrierungscode wird generiert...");
var a = document.createElement("a");
a.href = state.barcode;
a.download = "LfK23_Registrierungscode.png";
a.click();
toast("Registrierungscode generiert!", { type: TYPE.SUCCESS });
}
</script> </script>