diff --git a/package.json b/package.json index b661e60..95d4371 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "postbuild": "node env_fix.js" }, "dependencies": { + "bwip-js": "^3.2.2", "jsbarcode": "^3.11.5", "marked": "2.0.3", "redaxios": "0.4.1", diff --git a/public/env.sample.js b/public/env.sample.js index c43a129..b9eb22d 100644 --- a/public/env.sample.js +++ b/public/env.sample.js @@ -7,6 +7,8 @@ const config = { baseurl_selfservice: '/selfservice/', // full url (including fqdn) baseurl_documentserver: 'http://localhost:4010/documents', + // optional, will fallback to code128 + code_format: 'ean13', // optional, will fallback to baseurl_selfservice/imprint url_imprint: '', // optional, will fallback to baseurl_selfservice/privacy diff --git a/src/views/Profile.vue b/src/views/Profile.vue index 34ba680..79d5fac 100644 --- a/src/views/Profile.vue +++ b/src/views/Profile.vue @@ -3,19 +3,42 @@

{{ state.group }}

-
+
-
+
@@ -124,68 +184,170 @@
+ > + {{ $t("profile") }} +
+ > + {{ $t("lap_times") }} +
+ > + {{ $t("sponsoring") }} +
-
+
-
{{ $t('registrierungscode') }}
- Registrierungscode -
{{ $t('vorname') }}
+
{{ $t("registrierungscode") }}
+ Registrierungscode +
{{ $t("vorname") }}

-
{{ $t('mittelname') }}
+
{{ $t("mittelname") }}

-
{{ $t('nachname') }}
+
{{ $t("nachname") }}

-
{{ $t('e_mail_adress') }}
+
{{ $t("e_mail_adress") }}

-
{{ $t('phone_number') }}
+
{{ $t("phone_number") }}

@@ -194,7 +356,7 @@
-
+
@@ -204,15 +366,37 @@ class="table-auto w-full text-left whitespace-no-wrap" > {{ $t('distance') }} + class=" + px-4 + py-3 + title-font + tracking-wider + font-medium + " + > + {{ $t("distance") }} + {{ $t('lap_time') }} + class=" + px-4 + py-3 + title-font + tracking-wider + font-medium + " + > + {{ $t("lap_time") }} + @@ -224,20 +408,32 @@ -
+
- {{ $t('no_laps_scans_were_recorded_yet') }} + {{ $t("no_laps_scans_were_recorded_yet") }}
-
+
@@ -247,16 +443,48 @@ class="table-auto w-full text-left whitespace-no-wrap" > - Name {{ $t('amount_per_kilometer_in_eur') }} + class=" + px-4 + py-3 + title-font + tracking-wider + font-medium + " + > + Name + {{ $t('current_total_amount_in_eur') }} + class=" + px-4 + py-3 + title-font + tracking-wider + font-medium + " + > + {{ $t("amount_per_kilometer_in_eur") }} + + + {{ $t("current_total_amount_in_eur") }} + @@ -270,51 +498,86 @@ € + v-text=" + (s.amountPerDistance / 100) + .toFixed(2) + .toLocaleString('de-DE', { valute: 'EUR' }) + " + >€ € + v-text=" + (s.amount / 100) + .toFixed(2) + .toLocaleString('de-DE', { valute: 'EUR' }) + " + >€ - {{ $t('total') }} + {{ $t("total") }} € + v-text=" + ( + state.sponsorings.reduce(function ( + sum, + current + ) { + return sum + current.amountPerDistance; + }, + 0) / 100 + ) + .toFixed(2) + .toLocaleString('de-DE', { valute: 'EUR' }) + " + >€ € + v-text=" + ( + state.sponsorings.reduce(function ( + sum, + current + ) { + return sum + current.amount; + }, + 0) / 100 + ) + .toFixed(2) + .toLocaleString('de-DE', { valute: 'EUR' }) + " + >€ -
+
- {{ $t('no_sponsorings_for_you_were_recorded_yet') }} + {{ $t("no_sponsorings_for_you_were_recorded_yet") }}
@@ -332,11 +595,22 @@ import { reactive } from "vue"; import { TYPE, useToast } from "vue-toastification"; import axios from "redaxios"; import JsBarcode from "jsbarcode"; +import bwipjs from "bwip-js"; -function textToBase64Barcode(text){ +function textToBase64Barcode(text) { var canvas = document.createElement("canvas"); - JsBarcode(canvas, text, {format: "CODE128", displayValue:false}); - return canvas.toDataURL("image/png"); + // bwipjs.toCanvas(canvas, text, {format: config.code_format || "code128", displayValue:false}); + bwipjs.toCanvas(canvas, { + bcid: config.code_format || "code128", + text: `${text}` || "?", + scale: 3, // 3x scaling factor + height: 10, // Bar height, in millimeters + includetext: false, // Show human-readable text + textxalign: "center", // Always good to set this + }); + const base64 = canvas.toDataURL("image/png"); + console.log(base64); + return base64; } const state = reactive({ @@ -351,14 +625,15 @@ const state = reactive({ group: "", activetab: "profile", delete_active: false, - fullobject: {} -}) + fullobject: {}, +}); const toast = useToast(); const props = defineProps({ - token: String -}) + token: String, +}); const accesstoken = atob(props.token); -axios.get(`${config.baseurl}api/runners/me/${accesstoken}`) +axios + .get(`${config.baseurl}api/runners/me/${accesstoken}`) .then(({ data }) => { state.phone = data.phone; state.email = data.email; @@ -368,26 +643,38 @@ axios.get(`${config.baseurl}api/runners/me/${accesstoken}`) state.group = data.group; state.sponsorings = data.distanceDonations; state.fullobject = data; - state.barcode = textToBase64Barcode(state.fullobject.id); - }).catch((error) => { - toast.error("Profil konnte nicht geladen werden..."); + state.barcode = textToBase64Barcode(data.id); }) -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 }) => { - data.map(function(s) { - s.lapTime = 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" + data.map(function (s) { + s.lapTime = + 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; - }) - data.filter(s => s.valid === true); + }); + data.filter((s) => s.valid === true); state.scans = data; - }).catch((error) => { - toast.error("Profil konnte nicht geladen werden..."); }) + .catch((error) => { + toast.error("Profil konnte nicht geladen werden..."); + }); function delete_me() { toast("Profil wird gelöscht..."); - let url = `${config.baseurl}api/runners/me/${accesstoken}?force=true` - axios.delete(url) + let url = `${config.baseurl}api/runners/me/${accesstoken}?force=true`; + axios + .delete(url) .then(() => { toast("Alle Daten gelöscht!"); location.replace(`${config.baseurl_selfservice}`); @@ -398,31 +685,37 @@ function delete_me() { } function get_certificate() { 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 postdata = Object.assign({}, state.fullobject); postdata.group = { - name: postdata.group - } - postdata = [postdata] - axios.post(url, postdata, { - responseType: "blob" - }) + name: postdata.group, + }; + postdata = [postdata]; + axios + .post(url, postdata, { + responseType: "blob", + }) .then((response) => { - console.log(response) + console.log(response); if (response.status != "200") { toast.error("Urkunde konnte nicht generiert werden..."); } else { - var fileURL = window.URL.createObjectURL(new Blob([response.data], { type: 'application/pdf' })); - var fileLink = document.createElement('a'); + var fileURL = window.URL.createObjectURL( + new Blob([response.data], { type: "application/pdf" }) + ); + var fileLink = document.createElement("a"); fileLink.href = fileURL; - fileLink.setAttribute('download', 'Certificate.pdf'); + fileLink.setAttribute("download", "Certificate.pdf"); document.body.appendChild(fileLink); fileLink.click(); fileLink.remove(); - toast("Urkunde generiert!",{type:TYPE.SUCCESS}); + toast("Urkunde generiert!", { type: TYPE.SUCCESS }); } }) .catch((err) => {