Compare commits

...

5 Commits

6 changed files with 182 additions and 153 deletions

View File

@@ -2,8 +2,14 @@
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.
#### [1.2.4](https://git.odit.services/lfk/selfservice/compare/1.2.3...1.2.4)
- feat: loading screen [`2939911`](https://git.odit.services/lfk/selfservice/commit/2939911c993c3817d841d4cb4660aa940e478cc0)
#### [1.2.3](https://git.odit.services/lfk/selfservice/compare/1.2.2...1.2.3) #### [1.2.3](https://git.odit.services/lfk/selfservice/compare/1.2.2...1.2.3)
> 17 March 2025
- chore(deps): bump [`64bb2d1`](https://git.odit.services/lfk/selfservice/commit/64bb2d157daab257b6e0e7c4e6ed04f4b3772740) - chore(deps): bump [`64bb2d1`](https://git.odit.services/lfk/selfservice/commit/64bb2d157daab257b6e0e7c4e6ed04f4b3772740)
- feat: cleanup profile [`86ec22a`](https://git.odit.services/lfk/selfservice/commit/86ec22aa435d9138ae3cde6387ce7ead14f3c964) - feat: cleanup profile [`86ec22a`](https://git.odit.services/lfk/selfservice/commit/86ec22aa435d9138ae3cde6387ce7ead14f3c964)
- feat: improve profile [`846d10f`](https://git.odit.services/lfk/selfservice/commit/846d10f0b95dad460a068bdaf3ca489d96c0b723) - feat: improve profile [`846d10f`](https://git.odit.services/lfk/selfservice/commit/846d10f0b95dad460a068bdaf3ca489d96c0b723)
@@ -12,6 +18,7 @@ All notable changes to this project will be documented in this file. Dates are d
- i18n [`c94f9e5`](https://git.odit.services/lfk/selfservice/commit/c94f9e550e1cbe4626242423deb6d9ab994eea63) - i18n [`c94f9e5`](https://git.odit.services/lfk/selfservice/commit/c94f9e550e1cbe4626242423deb6d9ab994eea63)
- feat: wip: sponsoring add [`382757a`](https://git.odit.services/lfk/selfservice/commit/382757aa66cd79a6a8081ff4b21f6efe46a3ccfd) - feat: wip: sponsoring add [`382757a`](https://git.odit.services/lfk/selfservice/commit/382757aa66cd79a6a8081ff4b21f6efe46a3ccfd)
- feat: cleanup profile [`0366f95`](https://git.odit.services/lfk/selfservice/commit/0366f95951d1415b300b174699d93e4bf17f3e18) - feat: cleanup profile [`0366f95`](https://git.odit.services/lfk/selfservice/commit/0366f95951d1415b300b174699d93e4bf17f3e18)
- 🚀Bumped version to v1.2.3 [`e7b9c6e`](https://git.odit.services/lfk/selfservice/commit/e7b9c6e2036addd18e109e3ab040e69dee2f658d)
- shareSponsorLink function [`ccea9d6`](https://git.odit.services/lfk/selfservice/commit/ccea9d61975bfa54928d557735cd3ce79d671435) - shareSponsorLink function [`ccea9d6`](https://git.odit.services/lfk/selfservice/commit/ccea9d61975bfa54928d557735cd3ce79d671435)
- no selfservice sponsor add for now [`3641d2a`](https://git.odit.services/lfk/selfservice/commit/3641d2a78341b91a26a9d4cc31c40707096768b1) - no selfservice sponsor add for now [`3641d2a`](https://git.odit.services/lfk/selfservice/commit/3641d2a78341b91a26a9d4cc31c40707096768b1)
- feat: disable darkmode for now, also is better for visibility on day of run... [`0848209`](https://git.odit.services/lfk/selfservice/commit/0848209d49e4445881bf9536d87fe18ea2a6c924) - feat: disable darkmode for now, also is better for visibility on day of run... [`0848209`](https://git.odit.services/lfk/selfservice/commit/0848209d49e4445881bf9536d87fe18ea2a6c924)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-selfservice", "name": "@odit/lfk-selfservice",
"version": "1.2.3", "version": "1.2.4",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -9,6 +9,7 @@
}, },
"dependencies": { "dependencies": {
"@fontsource/athiti": "5.2.5", "@fontsource/athiti": "5.2.5",
"@odit/lfk-client": "^0.0.1",
"@tailwindcss/vite": "4.0.14", "@tailwindcss/vite": "4.0.14",
"bwip-js": "4.5.2", "bwip-js": "4.5.2",
"marked": "15.0.7", "marked": "15.0.7",

15
pnpm-lock.yaml generated
View File

@@ -11,6 +11,9 @@ importers:
'@fontsource/athiti': '@fontsource/athiti':
specifier: 5.2.5 specifier: 5.2.5
version: 5.2.5 version: 5.2.5
'@odit/lfk-client':
specifier: ^0.0.1
version: 0.0.1
'@tailwindcss/vite': '@tailwindcss/vite':
specifier: 4.0.14 specifier: 4.0.14
version: 4.0.14(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)) version: 4.0.14(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))
@@ -368,6 +371,9 @@ packages:
'@fontsource/athiti@5.2.5': '@fontsource/athiti@5.2.5':
resolution: {integrity: sha512-vHoAKBBw+wI4y3bGOkiogOkgcoLH7+SWtNNo/nBQ1XfhvfRPX/91xGtclEdwqUlbOJTCkNzEecdKChJQ5MsDFg==} resolution: {integrity: sha512-vHoAKBBw+wI4y3bGOkiogOkgcoLH7+SWtNNo/nBQ1XfhvfRPX/91xGtclEdwqUlbOJTCkNzEecdKChJQ5MsDFg==}
'@hey-api/client-fetch@0.8.3':
resolution: {integrity: sha512-EBVa8wwUMyBSeQ32PtCz6u5bFQZIMAufvwCT1ZtpjqT3caJQEza4NokbGU50q1ZVrMsM5Ot6GuDNJOF3TMo26Q==}
'@iarna/toml@2.2.5': '@iarna/toml@2.2.5':
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
@@ -586,6 +592,9 @@ packages:
'@octokit/types@13.8.0': '@octokit/types@13.8.0':
resolution: {integrity: sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==} resolution: {integrity: sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==}
'@odit/lfk-client@0.0.1':
resolution: {integrity: sha512-DD3ofUIl/Jv6pznJWYevKAbMWMY9GSecyJeNT06izKfko6jsMyOlZBwGnXrydeh8+Dh274/j/GoFA9rWqPxpbQ==}
'@pnpm/config.env-replace@1.1.0': '@pnpm/config.env-replace@1.1.0':
resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==}
engines: {node: '>=12.22.0'} engines: {node: '>=12.22.0'}
@@ -2433,6 +2442,8 @@ snapshots:
'@fontsource/athiti@5.2.5': {} '@fontsource/athiti@5.2.5': {}
'@hey-api/client-fetch@0.8.3': {}
'@iarna/toml@2.2.5': {} '@iarna/toml@2.2.5': {}
'@inquirer/checkbox@4.1.4(@types/node@18.11.18)': '@inquirer/checkbox@4.1.4(@types/node@18.11.18)':
@@ -2654,6 +2665,10 @@ snapshots:
dependencies: dependencies:
'@octokit/openapi-types': 23.0.1 '@octokit/openapi-types': 23.0.1
'@odit/lfk-client@0.0.1':
dependencies:
'@hey-api/client-fetch': 0.8.3
'@pnpm/config.env-replace@1.1.0': {} '@pnpm/config.env-replace@1.1.0': {}
'@pnpm/network.ca-file@1.0.2': '@pnpm/network.ca-file@1.0.2':

View File

@@ -11,15 +11,18 @@
dark:text-gray-200 dark:text-gray-200
"> ">
<img src="/favicon-lfk.png" class="h-20 mx-auto" /> <img src="/favicon-lfk.png" class="h-20 mx-auto" />
<h1 class="text-3xl font-bold whitespace-nowrap font-[Athiti]" v-text="(state.firstname || '') + <div v-if="loadstate === 'loaded'">
' ' + <h1 class="text-3xl font-bold whitespace-nowrap font-[Athiti]" v-text="(state.firstname || '') +
(state.middlename || '') + ' ' +
' ' + (state.middlename || '') +
(state.lastname || '') ' ' +
"></h1> (state.lastname || '')
<p class="text-md whitespace-nowrap">Team: {{ state.group }}</p> "></h1>
<p class="text-md whitespace-nowrap">Team: {{ state.group }}</p>
</div>
<h1 v-else class="text-3xl font-bold whitespace-nowrap font-[Athiti]">Daten werden geladen...</h1>
</div> </div>
<div class="flex flex-wrap"> <div v-if="loadstate === 'loaded'" class="flex flex-wrap">
<div class="w-full"> <div class="w-full">
<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 justify-center"> <div class="flex lg:flex-wrap flex-row lg:space-x-2 justify-center">
@@ -287,7 +290,8 @@
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-6"> <div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-6">
<div> <div>
<label for="sponsorvorname" <label for="sponsorvorname"
class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{ $t('vorname_des_sponsors') }}</label> class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{
$t('vorname_des_sponsors') }}</label>
<input v-bind="newsponsor_vorname" type="text" name="sponsorvorname" id="sponsorvorname" <input v-bind="newsponsor_vorname" type="text" name="sponsorvorname" id="sponsorvorname"
placeholder="Vorname des Sponsors" placeholder="Vorname des Sponsors"
class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600"> class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
@@ -295,7 +299,8 @@
<div> <div>
<label for="sponsornachname" <label for="sponsornachname"
class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{ $t('nachname_des_sponsors') }}</label> class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{
$t('nachname_des_sponsors') }}</label>
<input v-bind="newsponsor_nachname" type="text" name="sponsornachname" id="sponsornachname" <input v-bind="newsponsor_nachname" type="text" name="sponsornachname" id="sponsornachname"
placeholder="Nachname des Sponsors" placeholder="Nachname des Sponsors"
class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600"> class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
@@ -305,23 +310,23 @@
<!-- End Grid --> <!-- End Grid -->
<div> <div>
<label for="sponsortel" <label for="sponsortel" class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{
class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{ $t('telefonnummer_des_sponsors') }}</label> $t('telefonnummer_des_sponsors') }}</label>
<input v-bind="newsponsor_tel" type="tel" name="sponsortel" id="sponsortel" autocomplete="tel" <input v-bind="newsponsor_tel" type="tel" name="sponsortel" id="sponsortel" autocomplete="tel"
class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600"> class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
</div> </div>
<div> <div>
<label for="sponsormail" <label for="sponsormail" class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{
class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{ $t('e_mail_des_sponsors') }}</label> $t('e_mail_des_sponsors') }}</label>
<input v-bind="newsponsor_mail" type="email" name="sponsormail" id="sponsormail" <input v-bind="newsponsor_mail" type="email" name="sponsormail" id="sponsormail"
class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600"> class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
</div> </div>
</div> </div>
<div> <div>
<label for="eurokilometer" <label for="eurokilometer" class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{
class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{ $t('sponsoring_pro_kilometer_in_eur') }}</label> $t('sponsoring_pro_kilometer_in_eur') }}</label>
<input v-bind="newsponsor_value" type="number" name="eurokilometer" id="eurokilometer" <input v-bind="newsponsor_value" type="number" name="eurokilometer" id="eurokilometer"
placeholder="z.B. 1€ ODER 0,50€" placeholder="z.B. 1€ ODER 0,50€"
class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600"> class="py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg border sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
@@ -337,7 +342,8 @@
class="shrink-0 mt-1.5 border-gray-200 rounded-sm text-blue-600 focus:ring-blue-500 dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-800"> class="shrink-0 mt-1.5 border-gray-200 rounded-sm text-blue-600 focus:ring-blue-500 dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-800">
</div> </div>
<div class="ms-3"> <div class="ms-3">
<label for="sponsor_agree" class="text-sm text-gray-600 dark:text-neutral-400">{{ $t('sponsor_add_agree') }}</label> <label for="sponsor_agree" class="text-sm text-gray-600 dark:text-neutral-400">{{
$t('sponsor_add_agree') }}</label>
</div> </div>
</div> </div>
<!-- End Checkbox --> <!-- End Checkbox -->
@@ -484,13 +490,15 @@
</template> </template>
<script setup> <script setup>
import { reactive, ref } from "vue";
import { TYPE, useToast } from "vue-toastification";
import axios from "redaxios";
import { toCanvas } from "bwip-js";
import Footer from "@/components/Footer.vue"; import Footer from "@/components/Footer.vue";
import { useI18n } from 'vue-i18n' import { runnerSelfServiceControllerGet, runnerSelfServiceControllerGetScans, runnerSelfServiceControllerRemove } from "@odit/lfk-client";
import { toCanvas } from "bwip-js";
import axios from "redaxios";
import { reactive, ref } from "vue";
import { useI18n } from 'vue-i18n';
import { TYPE, useToast } from "vue-toastification";
const { t } = useI18n() const { t } = useI18n()
const loadstate = ref("loading")
const mode = ref("") const mode = ref("")
// //
const newsponsor_check = ref(false) const newsponsor_check = ref(false)
@@ -563,44 +571,42 @@ function getReadableDistance(distance) {
return `${m} m` return `${m} m`
} }
axios runnerSelfServiceControllerGet({ path: { jwt: accesstoken } }).then(({ data }) => {
.get(`${config.baseurl}api/runners/me/${accesstoken}`) loadstate.value = "loaded"
.then(({ data }) => { state.phone = data.phone;
state.phone = data.phone; state.email = data.email;
state.email = data.email; state.firstname = data.firstname;
state.firstname = data.firstname; state.middlename = data.middlename;
state.middlename = data.middlename; state.lastname = data.lastname;
state.lastname = data.lastname; 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(data.id ?? "???");
state.barcode = textToBase64Barcode(data.id ?? "???"); })
})
.catch((error) => { .catch((error) => {
loadstate = "error"
toast.clear(); toast.clear();
toast.error(t('profil_konnte_nicht_geladen_werden')); toast.error(t('profil_konnte_nicht_geladen_werden'));
}); });
axios runnerSelfServiceControllerGetScans({ path: { jwt: accesstoken } }).then(({ data }) => {
.get(`${config.baseurl}api/runners/me/${accesstoken}/scans`) let counter = 0
.then(({ data }) => { data.map(function (s) {
let counter = 0 if (counter === 0) {
data.map(function (s) { s.lapTime_readable = t('first_lap')
if (counter === 0) { } else {
s.lapTime_readable = t('first_lap') s.lapTime_readable =
} else { Math.floor(s.lapTime / 60) +
s.lapTime_readable = "min " +
Math.floor(s.lapTime / 60) + (Math.floor(s.lapTime % 60) + "").padStart(2, "0") +
"min " + "s";
(Math.floor(s.lapTime % 60) + "").padStart(2, "0") + }
"s"; s.distance_readable = getReadableDistance(s.distance);
} counter++;
s.distance_readable = getReadableDistance(s.distance); return s;
counter++; });
return s; data.filter((s) => s.valid === true);
}); state.scans = data;
data.filter((s) => s.valid === true); })
state.scans = data;
})
.catch((error) => { .catch((error) => {
toast.error(t('profil_konnte_nicht_geladen_werden')); toast.error(t('profil_konnte_nicht_geladen_werden'));
}); });
@@ -615,26 +621,20 @@ function addSponsoring() {
"address": {} "address": {}
} }
console.log(postdata); console.log(postdata);
axios // TODO: implement: donationControllerPostDistance({body:{}})
.post(`${config.baseurl}api/donors`, postdata)
.then(({ data }) => {
console.log(data);
})
.catch((error) => {
//
});
} }
function delete_me() { function delete_me() {
toast.clear(); toast.clear();
toast(t('profil_wird_geloescht')); toast(t('profil_wird_geloescht'));
let url = `${config.baseurl}api/runners/me/${accesstoken}?force=true`; runnerSelfServiceControllerRemove({
axios path: {
.delete(url) jwt: accesstoken
.then(() => { }, query: { force: true }
toast.clear(); }).then(() => {
toast(t('alle_daten_geloescht')); toast.clear();
location.replace(`/`); toast(t('alle_daten_geloescht'));
}) location.replace(`/`);
})
.catch((error) => { .catch((error) => {
toast.clear(); toast.clear();
toast.error(t('profil_konnte_nicht_geloescht_werden')); toast.error(t('profil_konnte_nicht_geloescht_werden'));

View File

@@ -59,12 +59,12 @@
</template> </template>
<script setup> <script setup>
import { computed, ref, reactive } from "vue";
import axios from "redaxios";
import isEmail from 'validator/es/lib/isEmail';
import { TYPE, useToast } from "vue-toastification";
import Footer from "@/components/Footer.vue"; import Footer from "@/components/Footer.vue";
import { useI18n } from 'vue-i18n' import { runnerSelfServiceControllerRequestNewToken } from "@odit/lfk-client";
import isEmail from 'validator/es/lib/isEmail';
import { computed, reactive, ref } from "vue";
import { useI18n } from 'vue-i18n';
import { TYPE, useToast } from "vue-toastification";
const { t } = useI18n() const { t } = useI18n()
let user_email = ref(""); let user_email = ref("");
@@ -79,11 +79,10 @@ function resendMail() {
if (isEmail(user_email.value)) { if (isEmail(user_email.value)) {
toast(t('login_link_is_requested')); toast(t('login_link_is_requested'));
const browserlocale = ((navigator.languages && navigator.languages[0]) || '').substr(0, 2); const browserlocale = ((navigator.languages && navigator.languages[0]) || '').substr(0, 2);
axios.post(`${config.baseurl}api/runners/login?mail=${user_email.value}&locale=${browserlocale}`) runnerSelfServiceControllerRequestNewToken({ query: { locale: browserlocale, mail: user_email.value } }).then(({ data }) => {
.then(({ data }) => { console.log(data);
console.log(data); toast(t('login_link_gesendet_an_user_email_value') + user_email.value);
toast(t('login_link_gesendet_an_user_email_value') + user_email.value); })
})
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
toast(t('error_requesting_the_login_link'), { type: TYPE.ERROR }); toast(t('error_requesting_the_login_link'), { type: TYPE.ERROR });

View File

@@ -73,24 +73,6 @@
p-2 p-2
" /> " />
<!-- --> <!-- -->
<label for="middle_name" class="block font-medium">{{
$t("mittelname")
}}</label>
<input v-model="userdetails.middlename" name="middlename" id="middle_name" autocomplete="off"
:placeholder="[[$t('mittelname')]]" type="text" class="
dark:bg-gray-800
mt-1
block
w-full
shadow-sm
sm:text-sm
border-gray-300 border-2
bg-gray-50
text-gray-500
rounded-md
p-2
" />
<!-- -->
<label for="last_name" class="block font-medium"> <label for="last_name" class="block font-medium">
{{ $t("nachname") }} {{ $t("nachname") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
@@ -144,9 +126,9 @@
<input v-model="userdetails.phone" name="phone" id="phone" autocomplete="off" <input v-model="userdetails.phone" name="phone" id="phone" autocomplete="off"
:placeholder="[[$t('phone_number')]]" type="text" :class="{ :placeholder="[[$t('phone_number')]]" type="text" :class="{
'border-red-500': 'border-red-500':
!isMobilePhone(userdetails.phone) && userdetails.phone.trim(), !isPhoneOkay(userdetails.phone),
'border-green-300': 'border-green-300':
isMobilePhone(userdetails.phone) && userdetails.phone.trim(), isPhoneOkay(userdetails.phone),
}" class=" }" class="
dark:bg-gray-800 dark:bg-gray-800
mt-1 mt-1
@@ -160,7 +142,7 @@
rounded-md rounded-md
p-2 p-2
" /> " />
<p v-if="!isMobilePhone(userdetails.phone) && userdetails.phone.trim()" class="text-sm"> <p v-if="!isPhoneOkay(userdetails.phone)" class="text-sm">
{{ $t("this_is_not_a_valid_international_phone_number") }} {{ $t("this_is_not_a_valid_international_phone_number") }}
</p> </p>
<!-- --> <!-- -->
@@ -173,7 +155,7 @@
</div> </div>
<div class="ml-3 text-sm"> <div class="ml-3 text-sm">
<label for="address_activated" class="font-medium text-gray-600 select-none">{{ $t("provide_address") <label for="address_activated" class="font-medium text-gray-600 select-none">{{ $t("provide_address")
}}</label> }}</label>
</div> </div>
</div> </div>
<div v-if="provide_address === true" class="col-span-6"> <div v-if="provide_address === true" class="col-span-6">
@@ -335,27 +317,24 @@
</template> </template>
<script setup> <script setup>
import { computed, ref, reactive } from "vue"; import Footer from "@/components/Footer.vue";
import axios from "redaxios"; import { runnerSelfServiceControllerGetSelfserviceOrg, runnerSelfServiceControllerRegisterOrganizationRunner, runnerSelfServiceControllerRegisterRunner } from "@odit/lfk-client";
import isEmail from "validator/es/lib/isEmail"; import isEmail from "validator/es/lib/isEmail";
import isMobilePhone from "validator/es/lib/isMobilePhone"; import isMobilePhone from "validator/es/lib/isMobilePhone";
import isPostalCode from "validator/es/lib/isPostalCode"; import isPostalCode from "validator/es/lib/isPostalCode";
import { computed, reactive, ref } from "vue";
import { useI18n } from 'vue-i18n';
import { TYPE, useToast } from "vue-toastification"; import { TYPE, useToast } from "vue-toastification";
import Footer from "@/components/Footer.vue";
import { useI18n } from 'vue-i18n'
const { t } = useI18n() const { t } = useI18n()
const props = defineProps({ const props = defineProps({
token: String, token: String,
}); });
if (props.token) { if (props.token) {
axios runnerSelfServiceControllerGetSelfserviceOrg({ path: { token: props.token } }).then(({ data }) => {
.get(`${config.baseurl}api/organizations/selfservice/${props.token}`) state.org_name = data.name;
.then(({ data }) => { state.org_teams = data.teams;
state.org_name = data.name; org_team.value = data.teams[0]?.id;
state.org_teams = data.teams; })
org_team.value = data.teams[0]?.id;
})
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
}); });
@@ -369,6 +348,21 @@ let userdetails = ref({
phone: "", phone: "",
address: { street: "", address2: "", city: "", zipcode: "" }, address: { street: "", address2: "", city: "", zipcode: "" },
}); });
function isPhoneOkay() {
if (userdetails.value.phone === "") {
return true
}
if (userdetails.value.phone.includes(" ")) {
return false
}
if (!userdetails.value.phone.includes("+")) {
return false
}
if (isMobilePhone(userdetails.value.phone)) {
return true
}
return false
}
let provide_address = ref(false); let provide_address = ref(false);
let agb_accepted = ref(false); let agb_accepted = ref(false);
let data_confirmed = ref(false); let data_confirmed = ref(false);
@@ -382,8 +376,7 @@ const state = reactive({
() => () =>
agb_accepted.value === true && agb_accepted.value === true &&
data_confirmed.value === true && data_confirmed.value === true &&
(isMobilePhone(userdetails.value.phone) || isPhoneOkay() &&
!userdetails.value.phone.trim()) &&
isEmail(userdetails.value.mail) && isEmail(userdetails.value.mail) &&
userdetails.value.firstname && userdetails.value.firstname &&
userdetails.value.lastname && userdetails.value.lastname &&
@@ -396,25 +389,25 @@ const state = reactive({
}); });
const toast = useToast(); const toast = useToast();
function login() { function login() {
userdetails = userdetails.value; // userdetails = userdetails.value;
if (userdetails?.phone === "" || isMobilePhone(userdetails.phone)) { if (isPhoneOkay()) {
if (isEmail(userdetails.mail)) { if (isEmail(userdetails.value.mail)) {
let postdata = { let postdata = {
email: userdetails.mail, email: userdetails.value.mail,
firstname: userdetails.firstname, firstname: userdetails.value.firstname,
middlename: userdetails.middlename, middlename: userdetails.value.middlename,
lastname: userdetails.lastname, lastname: userdetails.value.lastname,
address: {}, address: {},
}; };
if (isMobilePhone(userdetails.phone)) { if (userdetails.value.phone !== "") {
postdata.phone = userdetails.phone; postdata.phone = userdetails.value.phone
} }
if (provide_address.value === true) { if (provide_address.value === true) {
postdata.address = { postdata.address = {
address1: userdetails.address.street, address1: userdetails.value.address.street,
address2: userdetails.address.address2 || "", address2: userdetails.value.address.address2 || "",
city: userdetails.address.city, city: userdetails.value.address.city,
postalcode: userdetails.address.zipcode, postalcode: userdetails.value.address.zipcode,
country: "DE", country: "DE",
}; };
} }
@@ -426,28 +419,42 @@ function login() {
(navigator.languages && navigator.languages[0]) || (navigator.languages && navigator.languages[0]) ||
"" ""
).substr(0, 2); ).substr(0, 2);
let url = `${config.baseurl}api/runners/register/?locale=${browserlocale}`;
if (props.token) {
url = `${config.baseurl}api/runners/register/${props.token}/?locale=${browserlocale}`;
}
registrationState.value = "loading"; registrationState.value = "loading";
axios if (props.token) {
.post(url, postdata) runnerSelfServiceControllerRegisterOrganizationRunner({ path: { token: props.token }, body: postdata, query: { locale: browserlocale } })
.then(() => { .then(() => {
registrationState.value = "registered"; registrationState.value = "registered";
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
if (error.data.message === "E-Mail already registered") { if (error.data.message === "E-Mail already registered") {
toast(t('already_registered'), { type: TYPE.ERROR }); toast(t('already_registered'), { type: TYPE.ERROR });
} else if (error.data.message === "Invalid body, check 'errors' property for more info.") { } else if (error.data.message === "Invalid body, check 'errors' property for more info.") {
error.data.errors.forEach(e => { error.data.errors.forEach(e => {
if (e.property === "phone") { if (e.property === "phone") {
toast(t('invalid_input_phone_number_should_be_international_format'), { type: TYPE.ERROR }); toast(t('invalid_input_phone_number_should_be_international_format'), { type: TYPE.ERROR });
} }
}); });
} }
}); });
} else {
runnerSelfServiceControllerRegisterRunner({ body: postdata, query: { locale: browserlocale } })
.then(() => {
registrationState.value = "registered";
})
.catch((error) => {
console.log(error);
if (error.data.message === "E-Mail already registered") {
toast(t('already_registered'), { type: TYPE.ERROR });
} else if (error.data.message === "Invalid body, check 'errors' property for more info.") {
error.data.errors.forEach(e => {
if (e.property === "phone") {
toast(t('invalid_input_phone_number_should_be_international_format'), { type: TYPE.ERROR });
}
});
}
});
}
} }
} }
} }