Compare commits

...

27 Commits
main ... dev

Author SHA1 Message Date
Nicolai Ort c36db2c18f
Pin pnpm
ci/woodpecker/push/build Pipeline was successful Details
2023-11-06 20:27:30 +01:00
Nicolai Ort decc80fcc1
Merge branch 'dev' of git.odit.services:lfk/selfservice into dev
ci/woodpecker/push/build Pipeline failed Details
2023-11-06 20:25:28 +01:00
Nicolai Ort 9a3d307dfa
feat(ci)!: Switch to woodpecker 2023-11-06 20:25:26 +01:00
Philipp Dormann 240f44df60
🚀Bumped version to v0.11.3
continuous-integration/drone/push Build is passing Details
2023-04-07 15:17:49 +02:00
Philipp Dormann 677e65f44a
chore(deps): pnpm@8.1.1 2023-04-07 15:17:27 +02:00
Philipp Dormann 772eca64bb
fix(Footer): darkmode colors in lightmode
continuous-integration/drone/push Build is failing Details
2023-04-07 15:15:26 +02:00
Philipp Dormann 25d25401df
fix: registration code white bg
close #50
2023-04-07 15:13:44 +02:00
Nicolai Ort cac5103d52
switched drone to kaniko with cache
continuous-integration/drone/push Build is passing Details
2023-03-29 20:20:06 +02:00
Nicolai Ort 6aca13f0cb
Pinned pnpm and lockfile 2023-03-29 20:17:33 +02:00
Nicolai Ort 78fea1ea04
Switched dockerfile to pnpm with cache 2023-03-29 20:17:18 +02:00
Nicolai Ort fa51b31fe4
🚀Bumped version to v0.11.2
continuous-integration/drone/push Build is passing Details
2023-03-15 19:27:59 +01:00
Nicolai Ort b9624aa5ad
Added footer to every page 2023-03-15 19:27:40 +01:00
Nicolai Ort 09e48e771f
Accept tos to accept privacy_policy 2023-03-15 19:22:35 +01:00
Philipp Dormann 8364321a7c
🚀Bumped version to v0.11.1
continuous-integration/drone/push Build is passing Details
2023-02-18 17:27:22 +01:00
Philipp Dormann 659fa77dca
Profile: add "---" if no data set
continuous-integration/drone/push Build is passing Details
2023-02-18 17:26:54 +01:00
Philipp Dormann 10c9127256
🚀Bumped version to v0.11.0
continuous-integration/drone/push Build is passing Details
2023-02-03 17:24:42 +01:00
Philipp Dormann a3a1e89aa1
pnpm migration
continuous-integration/drone/push Build is passing Details
2023-02-03 17:24:25 +01:00
Philipp Dormann 5587175534
🚀Bumped version to v0.10.0
continuous-integration/drone/push Build is passing Details
2023-02-03 17:19:08 +01:00
Philipp Dormann 8e2b355466
updated nginx config for cache busting
continuous-integration/drone/push Build is passing Details
2023-02-03 17:18:57 +01:00
Philipp Dormann eccce0795b
text cleanups + footer
continuous-integration/drone/push Build is passing Details
2023-02-03 17:14:01 +01:00
Philipp Dormann 54540be6e1
improved profile page padding + full width registration code for easier scanning
continuous-integration/drone/push Build is passing Details
2023-02-03 17:04:25 +01:00
Philipp Dormann 3392a2e68e
🚀Bumped version to v0.9.0
continuous-integration/drone/push Build is passing Details
2023-02-03 16:52:50 +01:00
Philipp Dormann 8928f841dc
wip: registration confirmation ui
continuous-integration/drone/push Build is passing Details
2023-02-03 16:52:38 +01:00
Philipp Dormann 9ac14e8a5d
wip: error registration ui feedback
continuous-integration/drone/push Build is passing Details
2023-02-03 16:48:14 +01:00
Philipp Dormann 4a5b9d2569
🚀Bumped version to v0.8.3
continuous-integration/drone/push Build is passing Details
2023-02-03 16:44:43 +01:00
Philipp Dormann 123509d0a6
fix: registration code (broke in merge)
continuous-integration/drone/push Build is passing Details
2023-02-03 16:44:10 +01:00
Philipp Dormann 51f8d0fb42
wip: fix registration code
continuous-integration/drone/push Build is passing Details
2023-02-03 16:41:42 +01:00
18 changed files with 1044 additions and 742 deletions

View File

@ -1,117 +0,0 @@
---
kind: secret
name: docker_username
get:
path: odit-registry-builder
name: username
---
kind: secret
name: docker_password
get:
path: odit-registry-builder
name: password
---
kind: secret
name: git_ssh
get:
path: odit-git-bot
name: sshkey
---
kind: pipeline
type: kubernetes
name: build:dev
steps:
- name: build dev
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: registry.odit.services/lfk/selfservice
tags:
- dev
registry: registry.odit.services
mtu: 1000
trigger:
branch:
- dev
event:
- push
---
kind: pipeline
type: kubernetes
name: build:testing
steps:
- name: build testing
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: registry.odit.services/lfk/selfservice
tags:
- testing
registry: registry.odit.services
mtu: 1000
trigger:
branch:
- bugfix/31-env_linking
event:
- push
---
kind: pipeline
type: kubernetes
name: build:latest
steps:
- name: build latest
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: registry.odit.services/lfk/selfservice
tags:
- latest
registry: registry.odit.services
mtu: 1000
trigger:
branch:
- main
event:
- push
---
kind: pipeline
type: kubernetes
name: build:tags
steps:
- name: build $DRONE_TAG
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: registry.odit.services/lfk/selfservice
tags:
- '${DRONE_TAG}'
registry: registry.odit.services
mtu: 1000
trigger:
event:
- tag

39
.woodpecker/build.yml Normal file
View File

@ -0,0 +1,39 @@
steps:
- name: build latest
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/selfservice
tags:
- latest
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/selfservice:latest
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
secrets:
- source: odit-npm-cache-url
target: NPM_REGISTRY_URL
when:
branch: main
- name: build dev
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/selfservice
tags:
- dev
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/selfservice:dev
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
secrets:
- source: odit-npm-cache-url
target: NPM_REGISTRY_URL
when:
branch: dev
when:
event: push

20
.woodpecker/release.yml Normal file
View File

@ -0,0 +1,20 @@
steps:
- name: build tag
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/selfservice
tags:
- "${CI_COMMIT_TAG}"
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/selfservice:latest
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
secrets:
- source: odit-npm-cache-url
target: NPM_REGISTRY_URL
when:
event: tag

View File

@ -2,9 +2,68 @@
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.11.3](https://git.odit.services/lfk/selfservice/compare/0.11.2...0.11.3)
- fix: registration code white bg [`#50`](https://git.odit.services/lfk/selfservice/issues/50)
- Pinned pnpm and lockfile [`6aca13f`](https://git.odit.services/lfk/selfservice/commit/6aca13f0cb1bc8fa43f0f09c554cec0758acd7a1)
- switched drone to kaniko with cache [`cac5103`](https://git.odit.services/lfk/selfservice/commit/cac5103d52427e777e4c3624ebb253ad7bd393d6)
- Switched dockerfile to pnpm with cache [`78fea1e`](https://git.odit.services/lfk/selfservice/commit/78fea1ea045a7281fe0a2841fc4d5f1505dcb3cf)
- chore(deps): pnpm@8.1.1 [`677e65f`](https://git.odit.services/lfk/selfservice/commit/677e65f44ae4bcc6f9af4732d813f337da0c51d2)
- fix(Footer): darkmode colors in lightmode [`772eca6`](https://git.odit.services/lfk/selfservice/commit/772eca64bb38ce1cf1ea1b58859dd744588a88e1)
#### [0.11.2](https://git.odit.services/lfk/selfservice/compare/0.11.1...0.11.2)
> 15 March 2023
- Added footer to every page [`b9624aa`](https://git.odit.services/lfk/selfservice/commit/b9624aa5ad57002852c84081fc710c2e977251bd)
- 🚀Bumped version to v0.11.2 [`fa51b31`](https://git.odit.services/lfk/selfservice/commit/fa51b31fe41d41b3ec9becad07ddab4cf73be051)
- Accept tos to accept privacy_policy [`09e48e7`](https://git.odit.services/lfk/selfservice/commit/09e48e771f4c0db4a7dbb898b05b347f1aad2292)
#### [0.11.1](https://git.odit.services/lfk/selfservice/compare/0.11.0...0.11.1)
> 18 February 2023
- Profile: add "---" if no data set [`659fa77`](https://git.odit.services/lfk/selfservice/commit/659fa77dca3b527d896d752386e91a167a1b8f4f)
- 🚀Bumped version to v0.11.1 [`8364321`](https://git.odit.services/lfk/selfservice/commit/8364321a7cb6a0037ee0c5055b028c4cf883fb10)
#### [0.11.0](https://git.odit.services/lfk/selfservice/compare/0.10.0...0.11.0)
> 3 February 2023
- pnpm migration [`a3a1e89`](https://git.odit.services/lfk/selfservice/commit/a3a1e89aa14798e1d180697f91809e282a229f23)
- 🚀Bumped version to v0.11.0 [`10c9127`](https://git.odit.services/lfk/selfservice/commit/10c9127256edf2cbad1dc6690d5f4e87c32f6396)
#### [0.10.0](https://git.odit.services/lfk/selfservice/compare/0.9.0...0.10.0)
> 3 February 2023
- text cleanups + footer [`eccce07`](https://git.odit.services/lfk/selfservice/commit/eccce0795b6960aa3a2e9368de5ae4bdf80997d7)
- updated nginx config for cache busting [`8e2b355`](https://git.odit.services/lfk/selfservice/commit/8e2b355466e9a37510be8bf03311d6b28e1a0d9f)
- improved profile page padding + full width registration code for easier scanning [`54540be`](https://git.odit.services/lfk/selfservice/commit/54540be6e12ed85afc96061b8548cd4ec6700eec)
- 🚀Bumped version to v0.10.0 [`5587175`](https://git.odit.services/lfk/selfservice/commit/5587175534188e05ab43d0eed9745484e01edb63)
#### [0.9.0](https://git.odit.services/lfk/selfservice/compare/0.8.3...0.9.0)
> 3 February 2023
- wip: error registration ui feedback [`9ac14e8`](https://git.odit.services/lfk/selfservice/commit/9ac14e8a5d740fb4cd87645e69b2cfde73e4acc7)
- wip: registration confirmation ui [`8928f84`](https://git.odit.services/lfk/selfservice/commit/8928f841dcd370daf28416adbf1adbe16fa4d76f)
- 🚀Bumped version to v0.9.0 [`3392a2e`](https://git.odit.services/lfk/selfservice/commit/3392a2e68edb8fcf2aa6dd4b962abbf6ac27a414)
#### [0.8.3](https://git.odit.services/lfk/selfservice/compare/0.8.2...0.8.3)
> 3 February 2023
- fix: registration code (broke in merge) [`123509d`](https://git.odit.services/lfk/selfservice/commit/123509d0a6d15fe254e28f7a316bd6c260fe7bd2)
- 🚀Bumped version to v0.8.3 [`4a5b9d2`](https://git.odit.services/lfk/selfservice/commit/4a5b9d25698931158a602b2159b4e6c4fa129e8e)
- wip: fix registration code [`51f8d0f`](https://git.odit.services/lfk/selfservice/commit/51f8d0fb42d0dbba268799eb9385686d22fd2284)
#### [0.8.2](https://git.odit.services/lfk/selfservice/compare/0.8.1...0.8.2) #### [0.8.2](https://git.odit.services/lfk/selfservice/compare/0.8.1...0.8.2)
> 3 February 2023
- move /registered/ to props [`c35f943`](https://git.odit.services/lfk/selfservice/commit/c35f943957e5ba84361a437c1d945331248746d1) - move /registered/ to props [`c35f943`](https://git.odit.services/lfk/selfservice/commit/c35f943957e5ba84361a437c1d945331248746d1)
- 🚀Bumped version to v0.8.2 [`f4d1c7b`](https://git.odit.services/lfk/selfservice/commit/f4d1c7b053d1e7210911772bde1b2d80a30ab225)
- /profile/ text cleanups [`64e6ef8`](https://git.odit.services/lfk/selfservice/commit/64e6ef8cec38a8193c4fb28c5f1b26ee0e4d5063) - /profile/ text cleanups [`64e6ef8`](https://git.odit.services/lfk/selfservice/commit/64e6ef8cec38a8193c4fb28c5f1b26ee0e4d5063)
- /profile/ move from anchor tag to button [`ac75828`](https://git.odit.services/lfk/selfservice/commit/ac75828309043532c6ab8aad63e0c40edf450459) - /profile/ move from anchor tag to button [`ac75828`](https://git.odit.services/lfk/selfservice/commit/ac75828309043532c6ab8aad63e0c40edf450459)
- /profile/ toast styles [`c7f3a89`](https://git.odit.services/lfk/selfservice/commit/c7f3a893af8705af12f2e7ae7e40197ca4c28666) - /profile/ toast styles [`c7f3a89`](https://git.odit.services/lfk/selfservice/commit/c7f3a893af8705af12f2e7ae7e40197ca4c28666)

View File

@ -1,10 +1,12 @@
FROM registry.odit.services/hub/library/node:15.9.0-alpine3.13 FROM registry.odit.services/hub/library/node:19.5.0-alpine3.17 as build
ARG NPM_REGISTRY_URL=https://registry.npmjs.org
WORKDIR /app WORKDIR /app
COPY . . COPY . .
RUN yarn RUN npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8.1.1
RUN yarn build RUN pnpm i && pnpm build && pnpm postbuild
RUN yarn postbuild
# final image # final image
FROM registry.odit.services/library/nginx-brotli:3.15 FROM registry.odit.services/library/nginx-brotli:3.15 as final
COPY --from=0 /app/dist /usr/share/nginx/html COPY --from=build /app/dist /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf COPY ./nginx.conf /etc/nginx/nginx.conf

View File

@ -7,15 +7,21 @@ http {
error_page 404 /index.html; error_page 404 /index.html;
root /usr/share/nginx/html; root /usr/share/nginx/html;
location / { location / {
rewrite /register/(.*) /$1 break; rewrite /register/(.*) /$1 break;
rewrite /profile/(.*) /$1 break; rewrite /profile/(.*) /$1 break;
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
} }
location ~* \.(?:ico|css|gif|jpe?g|png)$ { location ~* \.(?:ico|css|gif|jpe?g|png)$ {
rewrite /register/(.*) /$1 break; rewrite /register/(.*) /$1 break;
rewrite /profile/(.*) /$1 break; rewrite /profile/(.*) /$1 break;
expires 1y; expires 1y;
add_header Pragma public; add_header Pragma public;
@ -35,24 +41,24 @@ http {
gzip_buffers 16 8k; gzip_buffers 16 8k;
gzip_http_version 1.1; gzip_http_version 1.1;
gzip_types application/javascript gzip_types application/javascript
application/rss+xml application/rss+xml
application/vnd.ms-fontobject application/vnd.ms-fontobject
application/x-font application/x-font
application/x-font-opentype application/x-font-opentype
application/x-font-otf application/x-font-otf
application/x-font-truetype application/x-font-truetype
application/x-font-ttf application/x-font-ttf
application/x-javascript application/x-javascript
application/xhtml+xml application/xhtml+xml
application/xml application/xml
font/opentype font/opentype
font/otf font/otf
font/ttf font/ttf
image/svg+xml image/svg+xml
image/x-icon image/x-icon
text/css text/css
text/javascript text/javascript
text/plain text/plain
text/xml; text/xml;
} }
} }

View File

@ -1,12 +1,15 @@
{ {
"name": "@odit/lfk-selfservice", "name": "@odit/lfk-selfservice",
"version": "0.8.2", "version": "0.11.3",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"release": "release-it", "release": "release-it",
"postbuild": "node env_fix.js" "postbuild": "node env_fix.js"
}, },
"engines": {
"pnpm": "8.1.1"
},
"dependencies": { "dependencies": {
"bwip-js": "3.2.2", "bwip-js": "3.2.2",
"marked": "2.0.3", "marked": "2.0.3",

File diff suppressed because it is too large Load Diff

View File

@ -13,5 +13,4 @@ const config = {
url_imprint: '', url_imprint: '',
// optional, will fallback to baseurl_selfservice/privacy // optional, will fallback to baseurl_selfservice/privacy
url_privacy: '', url_privacy: '',
codeformat: 'code39'
}; };

View File

@ -1,5 +1,5 @@
<template> <template>
<footer class="text-gray-400 bg-gray-900 body-font"> <footer>
<div class="container px-5 py-8 mx-auto flex items-center sm:flex-row flex-col"> <div class="container px-5 py-8 mx-auto flex items-center sm:flex-row flex-col">
<p class="text-sm text-gray-400 sm:ml-4 sm:pl-4 sm:py-2 sm:mt-0 mt-4"> <p class="text-sm text-gray-400 sm:ml-4 sm:pl-4 sm:py-2 sm:mt-0 mt-4">
Lauf für Kaya! Selfservice - Copyright © 2023 + proudly powered by Lauf für Kaya! Selfservice - Copyright © 2023 + proudly powered by

View File

@ -5,7 +5,7 @@
"apartment_suite_etc": "Addresszeile 2", "apartment_suite_etc": "Addresszeile 2",
"cancel_keep_my_data": "Abbrechen, meine Daten behalten", "cancel_keep_my_data": "Abbrechen, meine Daten behalten",
"configuration_error": "Konfigurationsfehler", "configuration_error": "Konfigurationsfehler",
"confirm_delete_all_of_my_data": "Bestätigung, meine gesamten Daten löschen", "confirm_delete_all_of_my_data": "Bestätigen, meine Daten löschen",
"confirm_personal_data": "Hiermit bestätige ich die Vollständigkeit und Richtigkeit der oben genannten Angaben", "confirm_personal_data": "Hiermit bestätige ich die Vollständigkeit und Richtigkeit der oben genannten Angaben",
"current_total_amount_in_eur": "Aktueller Gesamtbetrag (in €)", "current_total_amount_in_eur": "Aktueller Gesamtbetrag (in €)",
"delete_all_of_my_data": "Meine gesamten Daten löschen", "delete_all_of_my_data": "Meine gesamten Daten löschen",

View File

@ -3,7 +3,6 @@ import Home from './views/Home.vue';
import Imprint from './views/Imprint.vue'; import Imprint from './views/Imprint.vue';
import Privacy from './views/Privacy.vue'; import Privacy from './views/Privacy.vue';
import Register from './views/Register.vue'; import Register from './views/Register.vue';
import Registered from './views/Registered.vue';
import Profile from './views/Profile.vue'; import Profile from './views/Profile.vue';
import ProfileNone from './views/ProfileNone.vue'; import ProfileNone from './views/ProfileNone.vue';
@ -18,7 +17,6 @@ export const routes = [
{ path: config.baseurl_selfservice + 'privacy/', component: Privacy }, { path: config.baseurl_selfservice + 'privacy/', component: Privacy },
{ path: config.baseurl_selfservice + 'register', component: Register }, { path: config.baseurl_selfservice + 'register', component: Register },
{ path: config.baseurl_selfservice + 'register/', component: Register }, { path: config.baseurl_selfservice + 'register/', component: Register },
{ path: config.baseurl_selfservice + 'registered/:mail', component: Registered, props: true },
{ path: config.baseurl_selfservice + 'register/:token', component: Register, props: true }, { path: config.baseurl_selfservice + 'register/:token', component: Register, props: true },
{ path: config.baseurl_selfservice + 'profile', component: Profile }, { path: config.baseurl_selfservice + 'profile', component: Profile },
{ path: config.baseurl_selfservice + 'profile/', component: ProfileNone }, { path: config.baseurl_selfservice + 'profile/', component: ProfileNone },

View File

@ -9,15 +9,18 @@
<div class="mx-auto prose" v-html="content"></div> <div class="mx-auto prose" v-html="content"></div>
</div> </div>
</section> </section>
<Footer></Footer>
</template> </template>
<style src="../simple.css"> <style src="../simple.css">
</style> </style>
<script> <script>
import marked from "marked"; import marked from "marked";
import Footer from "@/components/Footer.vue";
export default { export default {
components: {Footer},
data() { data() {
return { return {
content: "" content: "",
} }
}, },
async beforeMount() { async beforeMount() {

View File

@ -9,12 +9,15 @@
<div class="mx-auto prose" v-html="content"></div> <div class="mx-auto prose" v-html="content"></div>
</div> </div>
</section> </section>
<Footer></Footer>
</template> </template>
<style src="../simple.css"> <style src="../simple.css">
</style> </style>
<script> <script>
import marked from "marked"; import marked from "marked";
import Footer from "@/components/Footer.vue";
export default { export default {
components: {Footer},
data() { data() {
return { return {
content: "" content: ""

View File

@ -150,6 +150,10 @@
py-2.5 py-2.5
px-5 px-5
rounded-md rounded-md
mb-1
md:mb-auto
w-full
md:w-auto
bg-blue-500 bg-blue-500
hover:bg-blue-600 hover:shadow-lg hover:bg-blue-600 hover:shadow-lg
" "
@ -188,9 +192,11 @@
py-2.5 py-2.5
px-5 px-5
rounded-md rounded-md
w-full
md:w-auto
bg-red-600 bg-red-600
hover:bg-red-700 hover:shadow-lg hover:bg-red-700 hover:shadow-lg
ml-1 md:ml-1
" "
@click="delete_me" @click="delete_me"
> >
@ -220,7 +226,7 @@
</div> </div>
</section> </section>
<div class="flex flex-wrap"> <div class="flex flex-wrap">
<div class="w-full p-4"> <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"> <div class="flex lg:flex-wrap flex-row lg:space-x-2">
<div class="flex-none"> <div class="flex-none">
@ -282,7 +288,11 @@
<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
class="w-full md:w-auto mb-2 bg-white p-2"
alt="Registrierungscode"
:src="state.barcode"
/>
<div class="text-lg">{{ $t("vorname") }}</div> <div class="text-lg">{{ $t("vorname") }}</div>
<p <p
class=" class="
@ -301,7 +311,7 @@
duration-200 duration-200
ease-in-out ease-in-out
" "
v-text="state.firstname" v-text="state.firstname || '---'"
/> />
</div> </div>
<div class="form-element"> <div class="form-element">
@ -323,7 +333,7 @@
duration-200 duration-200
ease-in-out ease-in-out
" "
v-text="state.middlename" v-text="state.middlename || '---'"
/> />
</div> </div>
<div class="form-element"> <div class="form-element">
@ -345,7 +355,7 @@
duration-200 duration-200
ease-in-out ease-in-out
" "
v-text="state.lastname" v-text="state.lastname || '---'"
/> />
</div> </div>
<div class="form-element"> <div class="form-element">
@ -367,7 +377,7 @@
duration-200 duration-200
ease-in-out ease-in-out
" "
v-text="state.email" v-text="state.email || '---'"
/> />
</div> </div>
<div class="form-element"> <div class="form-element">
@ -389,7 +399,7 @@
duration-200 duration-200
ease-in-out ease-in-out
" "
v-text="state.phone" v-text="state.phone || '---'"
/> />
</div> </div>
</div> </div>
@ -628,6 +638,8 @@
</div> </div>
</div> </div>
</div> </div>
<!-- -->
<Footer></Footer>
</div> </div>
</template> </template>
@ -636,19 +648,26 @@ import { reactive } from "vue";
import { TYPE, useToast } from "vue-toastification"; import { TYPE, useToast } from "vue-toastification";
import axios from "redaxios"; import axios from "redaxios";
import bwipjs from "bwip-js"; import bwipjs from "bwip-js";
import Footer from "@/components/Footer.vue";
function textToBase64Barcode(text) { function textToBase64Barcode(text) {
var canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
bwipjs.toCanvas(canvas, { let codeconfig = {
bcid: config.codeformat || "code39", bcid: config.code_format || "code39",
text: text, text: `${text}`,
scale: 3, scale: 3,
height: 10, includetext: false,
// width: 10,
includetext: true,
textxalign: "center", textxalign: "center",
backgroundcolor: "ffffff", backgroundcolor: "ffffff",
}); };
if (
codeconfig.bcid === "code39" ||
codeconfig.bcid === "code128" ||
codeconfig.bcid === "ean13"
) {
codeconfig.height = 10;
}
bwipjs.toCanvas(canvas, codeconfig);
return canvas.toDataURL("image/png"); return canvas.toDataURL("image/png");
} }
@ -749,13 +768,13 @@ function get_certificate() {
} else { } else {
var fileURL = window.URL.createObjectURL( var fileURL = window.URL.createObjectURL(
new Blob([response.data], { type: "application/pdf" }) new Blob([response.data], { type: "application/pdf" })
); );
var fileLink = document.createElement("a"); 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.clear(); toast.clear();

View File

@ -68,6 +68,7 @@
</div> </div>
</div> </div>
</div> </div>
<Footer></Footer>
</template> </template>
<script setup> <script setup>
@ -77,6 +78,7 @@ 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 { TYPE, useToast } from "vue-toastification"; import { TYPE, useToast } from "vue-toastification";
import Footer from "@/components/Footer.vue";
let user_email = ref(""); let user_email = ref("");
// //

View File

@ -1,33 +1,73 @@
<template> <template>
<div class="min-h-screen flex items-center justify-center"> <div
class="min-h-screen flex items-center justify-center"
v-if="registrationState === 'registered'"
>
<div class="max-w-md w-full py-12 px-6"> <div class="max-w-md w-full py-12 px-6">
<img class="mx-auto h-24 w-auto" src="/favicon.png" alt /> <img class="mx-auto h-24 w-auto" src="/favicon.png" alt />
<h1 <h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-center">
class="sm:text-3xl text-2xl font-medium title-font mb-4 text-center" Lauf für Kaya! - Registriert
>Lauf für Kaya! - {{ $t('registrieren') }}</h1> </h1>
<p class="mx-auto leading-relaxed text-base text-center">{{ $t('register.register_now') }}</p> <p class="mx-auto leading-relaxed text-base text-center">
Bitte klicken Sie zum Fortfahren auf den Link, den wir an
<b class="font-bold">{{ userdetails.mail }}</b> geschickt haben.
</p>
</div>
</div>
<div class="min-h-screen flex items-center justify-center" v-else>
<div class="max-w-md w-full py-12 px-6">
<img class="mx-auto h-24 w-auto" src="/favicon.png" alt />
<h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-center">
Lauf für Kaya! - {{ $t("registrieren") }}
</h1>
<p class="mx-auto leading-relaxed text-base text-center">
{{ $t("register.register_now") }}
</p>
<p <p
v-if="state.org_name !== ''" v-if="state.org_name !== ''"
class="mx-auto leading-relaxed text-base text-center" class="mx-auto leading-relaxed text-base text-center"
>{{ $t('organization') }}: {{ state.org_name }}</p> >
{{ $t("organization") }}: {{ state.org_name }}
</p>
<p <p
v-if="state.org_name !== '' && state.org_teams.length > 0" v-if="state.org_name !== '' && state.org_teams.length > 0"
class="mx-auto leading-relaxed text-base text-center" class="mx-auto leading-relaxed text-base text-center"
>Team:</p> >
Team:
</p>
<select <select
v-model="org_team" v-model="org_team"
v-if="state.org_name !== '' && state.org_teams.length > 0" v-if="state.org_name !== '' && state.org_teams.length > 0"
class="w-full border bg-white rounded px-3 py-2 outline-none block mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-select focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray" class="
w-full
border
bg-white
rounded
px-3
py-2
outline-none
block
mt-1
text-sm
dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700
form-select
focus:border-purple-400 focus:outline-none focus:shadow-outline-purple
dark:focus:shadow-outline-gray
"
> >
<option v-for="t in state.org_teams" :key="t.id" :value="t.id">{{ t.name }}</option> <option v-for="t in state.org_teams" :key="t.id" :value="t.id">
{{ t.name }}
</option>
</select> </select>
<p <p
v-if="state.org_name === ''" v-if="state.org_name === ''"
class="mx-auto leading-relaxed text-base text-center" class="mx-auto leading-relaxed text-base text-center"
>Bürgerlauf</p> >
Bürgerlauf
</p>
<div class="mt-4"> <div class="mt-4">
<label for="first_name" class="block font-medium"> <label for="first_name" class="block font-medium">
{{ $t('vorname') }} {{ $t("vorname") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
<input <input
@ -37,11 +77,28 @@
autocomplete="off" autocomplete="off"
:placeholder="[[$t('vorname')]]" :placeholder="[[$t('vorname')]]"
type="text" type="text"
:class="{ 'border-red-500': (!userdetails.firstname.trim()), 'border-green-300': (userdetails.firstname.trim()) }" :class="{
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" 'border-red-500': !userdetails.firstname.trim(),
'border-green-300': userdetails.firstname.trim(),
}"
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="middle_name" class="block font-medium">{{ $t('mittelname') }}</label> <label for="middle_name" class="block font-medium">{{
$t("mittelname")
}}</label>
<input <input
v-model="userdetails.middlename" v-model="userdetails.middlename"
name="middlename" name="middlename"
@ -49,11 +106,23 @@
autocomplete="off" autocomplete="off"
:placeholder="[[$t('mittelname')]]" :placeholder="[[$t('mittelname')]]"
type="text" 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" 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>
</label> </label>
<input <input
@ -63,12 +132,27 @@
autocomplete="off" autocomplete="off"
:placeholder="[[$t('nachname')]]" :placeholder="[[$t('nachname')]]"
type="text" type="text"
:class="{ 'border-red-500': (!userdetails.lastname.trim()), 'border-green-300': (userdetails.lastname.trim()) }" :class="{
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" 'border-red-500': !userdetails.lastname.trim(),
'border-green-300': userdetails.lastname.trim(),
}"
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="email_address" class="block font-medium"> <label for="email_address" class="block font-medium">
{{ $t('e_mail_adress') }} {{ $t("e_mail_adress") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
<input <input
@ -78,12 +162,31 @@
autocomplete="off" autocomplete="off"
:placeholder="[[$t('e_mail_adress')]]" :placeholder="[[$t('e_mail_adress')]]"
type="email" type="email"
:class="{ 'border-red-500': (!isEmail(userdetails.mail)), 'border-green-300': (isEmail(userdetails.mail)) }" :class="{
class="dark:bg-gray-800 mt-1 block w-full shadow-sm sm:text-sm border-2 bg-gray-50 text-gray-500 rounded-md p-2" 'border-red-500': !isEmail(userdetails.mail),
'border-green-300': isEmail(userdetails.mail),
}"
class="
dark:bg-gray-800
mt-1
block
w-full
shadow-sm
sm:text-sm
border-2
bg-gray-50
text-gray-500
rounded-md
p-2
"
/> />
<p v-if="!isEmail(userdetails.mail)" class="text-sm">{{ $t('please_provide_valid_mail') }}</p> <p v-if="!isEmail(userdetails.mail)" class="text-sm">
{{ $t("please_provide_valid_mail") }}
</p>
<!-- --> <!-- -->
<label for="phone" class="select-none block font-medium">{{ $t('phone_number') }}</label> <label for="phone" class="select-none block font-medium">{{
$t("phone_number")
}}</label>
<input <input
v-model="userdetails.phone" v-model="userdetails.phone"
name="phone" name="phone"
@ -91,13 +194,32 @@
autocomplete="off" autocomplete="off"
:placeholder="[[$t('phone_number')]]" :placeholder="[[$t('phone_number')]]"
type="text" type="text"
:class="{ 'border-red-500': (!isMobilePhone(userdetails.phone) && userdetails.phone.trim()), 'border-green-300': (isMobilePhone(userdetails.phone) && userdetails.phone.trim()) }" :class="{
class="dark:bg-gray-800 mt-1 block w-full shadow-sm sm:text-sm border-2 bg-gray-50 text-gray-500 rounded-md p-2" 'border-red-500':
!isMobilePhone(userdetails.phone) && userdetails.phone.trim(),
'border-green-300':
isMobilePhone(userdetails.phone) && userdetails.phone.trim(),
}"
class="
dark:bg-gray-800
mt-1
block
w-full
shadow-sm
sm:text-sm
border-2
bg-gray-50
text-gray-500
rounded-md
p-2
"
/> />
<p <p
v-if="(!isMobilePhone(userdetails.phone) && userdetails.phone.trim())" v-if="!isMobilePhone(userdetails.phone) && userdetails.phone.trim()"
class="text-sm" class="text-sm"
>{{ $t('this_is_not_a_valid_international_phone_number') }}</p> >
{{ $t("this_is_not_a_valid_international_phone_number") }}
</p>
<!-- --> <!-- -->
<div class="grid grid-cols-6 mt-6"> <div class="grid grid-cols-6 mt-6">
<div class="col-span-6"></div> <div class="col-span-6"></div>
@ -115,13 +237,14 @@
<label <label
for="address_activated" for="address_activated"
class="font-medium text-gray-400 select-none" class="font-medium text-gray-400 select-none"
>{{ $t('provide_address') }}</label> >{{ $t("provide_address") }}</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">
<div class="col-span-6"> <div class="col-span-6">
<label for="street" class="block font-medium"> <label for="street" class="block font-medium">
{{ $t('strasse') }} {{ $t("strasse") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
<input <input
@ -131,12 +254,29 @@
:placeholder="[[$t('strasse')]]" :placeholder="[[$t('strasse')]]"
id="street" id="street"
autocomplete="street-address" autocomplete="street-address"
:class="{ 'border-red-500': (!userdetails.address.street.trim()), 'border-green-300': (userdetails.address.street.trim()) }" :class="{
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" 'border-red-500': !userdetails.address.street.trim(),
'border-green-300': userdetails.address.street.trim(),
}"
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
"
/> />
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label for="address2" class="block font-medium">{{ $t('apartment_suite_etc') }}</label> <label for="address2" class="block font-medium">{{
$t("apartment_suite_etc")
}}</label>
<input <input
v-model="userdetails.address.address2" v-model="userdetails.address.address2"
type="text" type="text"
@ -144,12 +284,24 @@
:placeholder="[[$t('apartment_suite_etc')]]" :placeholder="[[$t('apartment_suite_etc')]]"
id="address2" id="address2"
autocomplete="street-address" autocomplete="street-address"
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" 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
"
/> />
</div> </div>
<div class="col-span-6 sm:col-span-6 lg:col-span-2"> <div class="col-span-6 sm:col-span-6 lg:col-span-2">
<label for="city" class="block font-medium"> <label for="city" class="block font-medium">
{{ $t('ort') }} {{ $t("ort") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
<input <input
@ -158,13 +310,28 @@
name="city" name="city"
:placeholder="[[$t('ort')]]" :placeholder="[[$t('ort')]]"
id="city" id="city"
:class="{ 'border-red-500': (!userdetails.address.city.trim()), 'border-green-300': (userdetails.address.city.trim()) }" :class="{
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" 'border-red-500': !userdetails.address.city.trim(),
'border-green-300': userdetails.address.city.trim(),
}"
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
"
/> />
</div> </div>
<div class="col-span-6 sm:col-span-3 lg:col-span-2"> <div class="col-span-6 sm:col-span-3 lg:col-span-2">
<label for="postal_code" class="block font-medium"> <label for="postal_code" class="block font-medium">
{{ $t('plz') }} {{ $t("plz") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
<input <input
@ -174,14 +341,37 @@
:placeholder="[[$t('plz')]]" :placeholder="[[$t('plz')]]"
id="postal_code" id="postal_code"
autocomplete="postal-code" autocomplete="postal-code"
:class="{ 'border-red-500': (!isPostalCode(userdetails.address.zipcode, 'DE')), 'border-green-300': (isPostalCode(userdetails.address.zipcode, 'DE')) }" :class="{
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" 'border-red-500': !isPostalCode(
userdetails.address.zipcode,
'DE'
),
'border-green-300': isPostalCode(
userdetails.address.zipcode,
'DE'
),
}"
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
"
/> />
</div> </div>
<p <p
v-if="!isPostalCode(userdetails.address.zipcode, 'DE')" v-if="!isPostalCode(userdetails.address.zipcode, 'DE')"
class="text-sm" class="text-sm"
>{{ $t('please_provide_a_valid_zipcode') }}</p> >
{{ $t("please_provide_a_valid_zipcode") }}
</p>
</div> </div>
</div> </div>
<div class="flex items-start mt-6"> <div class="flex items-start mt-6">
@ -195,15 +385,19 @@
/> />
</div> </div>
<div class="ml-3 text-sm"> <div class="ml-3 text-sm">
<label for="agb_accepted" class="font-medium text-gray-400 select-none"> <label
{{ $t('i_accept', { tos: $t('tos') }) }} for="agb_accepted"
class="font-medium text-gray-400 select-none"
>
{{ $t("i_accept", { tos: $t("privacy_policy") }) }}
<a <a
target="_blank" target="_blank"
rel="noreferrer,noopener" rel="noreferrer,noopener"
href="https://lauf-fuer-kaya.de/datenschutz/" href="https://lauf-fuer-kaya.de/datenschutz/"
class="underline" class="underline"
>{{ $t('tos') }}</a> >{{ $t("privacy_policy") }}</a
{{ $t('i_accept_end') }} >
{{ $t("i_accept_end") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
</div> </div>
@ -219,8 +413,11 @@
/> />
</div> </div>
<div class="ml-3 text-sm"> <div class="ml-3 text-sm">
<label for="data_confirmed" class="font-medium text-gray-400 select-none"> <label
{{ $t('confirm_personal_data') }} for="data_confirmed"
class="font-medium text-gray-400 select-none"
>
{{ $t("confirm_personal_data") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
</div> </div>
@ -228,29 +425,52 @@
<div class="mt-6"> <div class="mt-6">
<button <button
@click="login" @click="login"
:disabled="(!state.submit_enabled)" :disabled="!state.submit_enabled"
:class="{ 'opacity-50': (!state.submit_enabled), 'cursor-not-allowed': (!state.submit_enabled) }" :class="{
class="text-white block w-full text-center py-2 px-3 border-2 border-gray-300 rounded-md p-1 bg-blue-800 font-medium hover:border-gray-400 focus:outline-none focus:border-gray-400 sm:text-sm" 'opacity-50': !state.submit_enabled,
>{{ $t('registrieren') }}</button> 'cursor-not-allowed': !state.submit_enabled,
}"
class="
text-white
block
w-full
text-center
py-2
px-3
border-2 border-gray-300
rounded-md
p-1
bg-blue-800
font-medium
hover:border-gray-400
focus:outline-none focus:border-gray-400
sm:text-sm
"
>
{{ $t("registrieren") }}
</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<Footer></Footer>
</template> </template>
<script setup> <script setup>
import { computed, ref, reactive, defineProps } from "vue"; import { computed, ref, reactive, defineProps } from "vue";
import axios from "redaxios"; import axios from "redaxios";
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 { useToast } from "vue-toastification"; import { TYPE, useToast } from "vue-toastification";
import Footer from "@/components/Footer.vue";
const props = defineProps({ const props = defineProps({
token: String token: String,
}) });
if (props.token) { if (props.token) {
axios.get(`${config.baseurl}api/organizations/selfservice/${props.token}`) axios
.get(`${config.baseurl}api/organizations/selfservice/${props.token}`)
.then(({ data }) => { .then(({ data }) => {
state.org_name = data.name; state.org_name = data.name;
state.org_teams = data.teams; state.org_teams = data.teams;
@ -261,31 +481,51 @@ if (props.token) {
}); });
} }
let userdetails = ref({ firstname: "", lastname: "", middlename: "", mail: "", phone: "", address: { street: "", address2: "", city: "", zipcode: "" } }); let userdetails = ref({
firstname: "",
lastname: "",
middlename: "",
mail: "",
phone: "",
address: { street: "", address2: "", city: "", zipcode: "" },
});
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);
let org_team = ref(""); let org_team = ref("");
// let registrationState = ref("pending");
//
const state = reactive({ const state = reactive({
org_name: "", org_name: "",
org_teams: [], org_teams: [],
submit_enabled: computed(() => agb_accepted.value === true && data_confirmed.value === true && (isMobilePhone(userdetails.value.phone) || !userdetails.value.phone.trim()) && isEmail(userdetails.value.mail) submit_enabled: computed(
&& userdetails.value.firstname () =>
&& userdetails.value.lastname && (provide_address.value === false || provide_address.value === true && (userdetails.value.address.street.trim() && userdetails.value.address.city.trim() && isPostalCode(userdetails.value.address.zipcode, "DE")))) agb_accepted.value === true &&
}) data_confirmed.value === true &&
(isMobilePhone(userdetails.value.phone) ||
!userdetails.value.phone.trim()) &&
isEmail(userdetails.value.mail) &&
userdetails.value.firstname &&
userdetails.value.lastname &&
(provide_address.value === false ||
(provide_address.value === true &&
userdetails.value.address.street.trim() &&
userdetails.value.address.city.trim() &&
isPostalCode(userdetails.value.address.zipcode, "DE")))
),
});
const toast = useToast(); const toast = useToast();
function login() { function login() {
userdetails = userdetails.value; userdetails = userdetails.value;
if (userdetails?.phone === "" || isMobilePhone(userdetails.phone)) { if (userdetails?.phone === "" || isMobilePhone(userdetails.phone)) {
if (isEmail(userdetails.mail)) { if (isEmail(userdetails.mail)) {
let postdata = { let postdata = {
"email": userdetails.mail, email: userdetails.mail,
"firstname": userdetails.firstname, firstname: userdetails.firstname,
"middlename": userdetails.middlename, middlename: userdetails.middlename,
"lastname": userdetails.lastname, lastname: userdetails.lastname,
"address": {} address: {},
} };
if (isMobilePhone(userdetails.phone)) { if (isMobilePhone(userdetails.phone)) {
postdata.phone = userdetails.phone; postdata.phone = userdetails.phone;
} }
@ -296,23 +536,31 @@ function login() {
city: userdetails.address.city, city: userdetails.address.city,
postalcode: userdetails.address.zipcode, postalcode: userdetails.address.zipcode,
country: "DE", country: "DE",
} };
} }
if (state.org_name !== '' && state.org_teams.length > 0) { if (state.org_name !== "" && state.org_teams.length > 0) {
postdata.team = org_team.value; postdata.team = org_team.value;
} }
toast("Registrierung läuft..."); toast("Registrierung läuft...");
const browserlocale = ((navigator.languages && navigator.languages[0]) || '').substr(0, 2); const browserlocale = (
(navigator.languages && navigator.languages[0]) ||
""
).substr(0, 2);
let url = `${config.baseurl}api/runners/register/?locale=${browserlocale}`; let url = `${config.baseurl}api/runners/register/?locale=${browserlocale}`;
if (props.token) { if (props.token) {
url = `${config.baseurl}api/runners/register/${props.token}/?locale=${browserlocale}` url = `${config.baseurl}api/runners/register/${props.token}/?locale=${browserlocale}`;
} }
axios.post(url, postdata) registrationState.value = "loading";
axios
.post(url, postdata)
.then(() => { .then(() => {
location.replace(`${config.baseurl_selfservice}registered/?mail=${encodeURIComponent(postdata.email)}`); registrationState.value = "registered";
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
if (error.data.message === "E-Mail already registered") {
toast("bereits registriert...", { type: TYPE.ERROR });
}
}); });
} }
} }

View File

@ -11,9 +11,11 @@
</p> </p>
</div> </div>
</div> </div>
<Footer></Footer>
</template> </template>
<script setup> <script setup>
import Footer from "@/components/Footer.vue";
const props = defineProps({ const props = defineProps({
mail: String, mail: String,
}); });