Compare commits

..

20 Commits
1.2.7 ... 1.4.2

Author SHA1 Message Date
68c2c681f2 chore(release): 1.4.2
All checks were successful
Build release images / build-container (push) Successful in 48s
2025-05-26 19:01:03 +02:00
480fe3e0e5 fix(profile): Format total distance 2025-05-26 18:58:43 +02:00
59cb42c336 feat(Profile/sponsoring): show note for on-day cash donations 2025-05-21 20:23:35 +02:00
2d761ccd6d refactor(Profile): drop sponsor selfservice create from this branch 2025-05-21 20:19:05 +02:00
128c6abd73 chore(release): 1.4.1
All checks were successful
Build release images / build-container (push) Successful in 49s
2025-04-25 15:41:19 +02:00
094e731947 fix(laptimes): Filter out invalid scans 2025-04-25 15:40:47 +02:00
8d6f290fd5 fix(certificate): Provide selfservice url on certificate 2025-04-25 15:38:31 +02:00
57600fad7f chore(release): 1.4.0
All checks were successful
Build release images / build-container (push) Successful in 45s
2025-03-28 22:36:34 +01:00
421dedcb8d ci: update release commit message 2025-03-28 22:36:21 +01:00
00c5181855 chore(deps): bump 2025-03-28 22:35:53 +01:00
6f5c5b4833 chore(deps): bump 2025-03-28 22:31:43 +01:00
347cfe0304 ci: only tagged for now 2025-03-28 22:30:26 +01:00
6afe3207fa feat(register): org/team as badge ui
All checks were successful
Build Latest image / build-container (push) Successful in 47s
2025-03-28 22:30:06 +01:00
4ccac8a0b8 feat: improved registration ui 2025-03-28 22:21:44 +01:00
3a9cd95830 🚀Bumped version to v1.3.1
All checks were successful
Build release images / build-container (push) Successful in 1m3s
Build Latest image / build-container (push) Successful in 1m14s
2025-03-28 19:00:04 +01:00
65dc27add1 feat: footer cleanup
Some checks failed
Build Latest image / build-container (push) Has been cancelled
2025-03-28 18:59:53 +01:00
c9e3b613e1 🚀Bumped version to v1.3.0
All checks were successful
Build release images / build-container (push) Successful in 51s
Build Latest image / build-container (push) Successful in 1m4s
2025-03-28 18:33:01 +01:00
f0c668c1c3 feat: only show international phone number thing if + is missing
All checks were successful
Build Latest image / build-container (push) Successful in 45s
2025-03-28 18:29:29 +01:00
e418d2a2b7 feat: improved Register UI
All checks were successful
Build Latest image / build-container (push) Successful in 45s
2025-03-28 17:47:12 +01:00
e14a6d6329 feat: improve phone number registration 2025-03-28 17:38:13 +01:00
13 changed files with 659 additions and 698 deletions

View File

@@ -1,27 +0,0 @@
name: Build Latest image
on:
push:
branches:
- dev
jobs:
build-container:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login to registry
uses: docker/login-action@v3
with:
registry: registry.odit.services
username: ${{ vars.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: |
${{ vars.REGISTRY }}/lfk/selfservice:dev
platforms: linux/amd64,linux/arm64

View File

@@ -1,27 +0,0 @@
name: Build Latest image
on:
push:
branches:
- main
jobs:
build-container:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login to registry
uses: docker/login-action@v3
with:
registry: registry.odit.services
username: ${{ vars.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: |
${{ vars.REGISTRY }}/lfk/selfservice:latest
platforms: linux/amd64,linux/arm64

View File

@@ -2,9 +2,54 @@
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.4.2](https://git.odit.services/lfk/selfservice/compare/1.4.1...1.4.2)
- refactor(Profile): drop sponsor selfservice create from this branch [`2d761cc`](https://git.odit.services/lfk/selfservice/commit/2d761ccd6da7d9515fc0c2b65dc2ca0cff61e3bd)
- feat(Profile/sponsoring): show note for on-day cash donations [`59cb42c`](https://git.odit.services/lfk/selfservice/commit/59cb42c3364777f7b8aed1e90f48f5da015db118)
- fix(profile): Format total distance [`480fe3e`](https://git.odit.services/lfk/selfservice/commit/480fe3e0e568939507e5cc21c48e98634614d4e6)
#### [1.4.1](https://git.odit.services/lfk/selfservice/compare/1.4.0...1.4.1)
> 25 April 2025
- chore(release): 1.4.1 [`128c6ab`](https://git.odit.services/lfk/selfservice/commit/128c6abd737654087100cfca8e72af9b14dd770c)
- fix(laptimes): Filter out invalid scans [`094e731`](https://git.odit.services/lfk/selfservice/commit/094e7319476bc571949a70b6f4c27539616f3634)
- fix(certificate): Provide selfservice url on certificate [`8d6f290`](https://git.odit.services/lfk/selfservice/commit/8d6f290fd5bad54094ba1228fa6d854ad77a561d)
#### [1.4.0](https://git.odit.services/lfk/selfservice/compare/1.3.1...1.4.0)
> 28 March 2025
- chore(deps): bump [`00c5181`](https://git.odit.services/lfk/selfservice/commit/00c5181855433893681351b53b1204b56990c3b3)
- feat: improved registration ui [`4ccac8a`](https://git.odit.services/lfk/selfservice/commit/4ccac8a0b89396a9faf7066f096f6b9e66aa8894)
- ci: only tagged for now [`347cfe0`](https://git.odit.services/lfk/selfservice/commit/347cfe03046bd2ed46720c60b0a893fc57c6c646)
- feat(register): org/team as badge ui [`6afe320`](https://git.odit.services/lfk/selfservice/commit/6afe3207fa0db631b5f079cf815584f4b8f963b2)
- chore(release): 1.4.0 [`57600fa`](https://git.odit.services/lfk/selfservice/commit/57600fad7f3974a1ea8e8ffcb4bfbbd6ab77809a)
- ci: update release commit message [`421dedc`](https://git.odit.services/lfk/selfservice/commit/421dedcb8d6f03072c94786d1f543e0a85950e82)
- chore(deps): bump [`6f5c5b4`](https://git.odit.services/lfk/selfservice/commit/6f5c5b4833d963169003923e2cf011c41cc92393)
#### [1.3.1](https://git.odit.services/lfk/selfservice/compare/1.3.0...1.3.1)
> 28 March 2025
- feat: footer cleanup [`65dc27a`](https://git.odit.services/lfk/selfservice/commit/65dc27add1760c6ebe11f415c49238f82cdb5b48)
- 🚀Bumped version to v1.3.1 [`3a9cd95`](https://git.odit.services/lfk/selfservice/commit/3a9cd95830cc99685f78728f1b19502b523e5e7c)
#### [1.3.0](https://git.odit.services/lfk/selfservice/compare/1.2.7...1.3.0)
> 28 March 2025
- feat: improve phone number registration [`e14a6d6`](https://git.odit.services/lfk/selfservice/commit/e14a6d6329d547d3086abe59d00f0d054688b6f4)
- feat: improved Register UI [`e418d2a`](https://git.odit.services/lfk/selfservice/commit/e418d2a2b74553f614520ac8c0f0377d141daa8d)
- 🚀Bumped version to v1.3.0 [`c9e3b61`](https://git.odit.services/lfk/selfservice/commit/c9e3b613e1d08f6217ae58b8aa42a47749f0ac94)
- feat: only show international phone number thing if + is missing [`f0c668c`](https://git.odit.services/lfk/selfservice/commit/f0c668c1c3d1a5c27d78617e5ca34ca68603ce14)
#### [1.2.7](https://git.odit.services/lfk/selfservice/compare/1.2.6...1.2.7) #### [1.2.7](https://git.odit.services/lfk/selfservice/compare/1.2.6...1.2.7)
> 23 March 2025
- refactor(ci): Switch to actions [`a862593`](https://git.odit.services/lfk/selfservice/commit/a862593c5315043577699d1a6fd50854dd1bca00) - refactor(ci): Switch to actions [`a862593`](https://git.odit.services/lfk/selfservice/commit/a862593c5315043577699d1a6fd50854dd1bca00)
- 🚀Bumped version to v1.2.7 [`e1a87ed`](https://git.odit.services/lfk/selfservice/commit/e1a87eda4a0c9b9be47bcfe4ddb0e93696d037f4)
- footer: cleanup imprint & privacy url [`0e557ef`](https://git.odit.services/lfk/selfservice/commit/0e557ef4080e997b06adcbbadf3e82f12152281b) - footer: cleanup imprint & privacy url [`0e557ef`](https://git.odit.services/lfk/selfservice/commit/0e557ef4080e997b06adcbbadf3e82f12152281b)
- fix: footer [`422df7c`](https://git.odit.services/lfk/selfservice/commit/422df7c3f832dc29721e783dc4a86ee55e9d8ccc) - fix: footer [`422df7c`](https://git.odit.services/lfk/selfservice/commit/422df7c3f832dc29721e783dc4a86ee55e9d8ccc)
- footer padding [`0af7352`](https://git.odit.services/lfk/selfservice/commit/0af73525bc154ba730351d7a4970e9737edaa4db) - footer padding [`0af7352`](https://git.odit.services/lfk/selfservice/commit/0af73525bc154ba730351d7a4970e9737edaa4db)

View File

@@ -1,10 +1,9 @@
FROM node:23.4.0-alpine3.20 AS build FROM node:23.10.0-alpine3.21 AS build
# FROM registry.odit.services/hub/library/node:23.3.0-alpine3.20 AS build
# ARG NPM_REGISTRY_URL=https://registry.npmjs.org # ARG NPM_REGISTRY_URL=https://registry.npmjs.org
WORKDIR /app WORKDIR /app
COPY . . COPY . .
# RUN npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@9 # RUN npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@9
RUN npm i -g pnpm@9 RUN npm i -g pnpm@10.7
RUN pnpm i --frozen-lockfile RUN pnpm i --frozen-lockfile
RUN pnpm build RUN pnpm build

View File

@@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-selfservice", "name": "@odit/lfk-selfservice",
"version": "1.2.7", "version": "1.4.2",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -10,13 +10,13 @@
"dependencies": { "dependencies": {
"@fontsource/athiti": "5.2.5", "@fontsource/athiti": "5.2.5",
"@odit/lfk-client": "^0.0.1", "@odit/lfk-client": "^0.0.1",
"@tailwindcss/vite": "4.0.14", "@tailwindcss/vite": "4.0.17",
"bwip-js": "4.5.2", "bwip-js": "4.5.3",
"marked": "15.0.7", "marked": "15.0.7",
"redaxios": "0.5.1", "redaxios": "0.5.1",
"tailwindcss": "4.0.14", "tailwindcss": "4.0.17",
"toastify-js": "1.12.0", "toastify-js": "1.12.0",
"validator": "13.12.0", "validator": "13.15.0",
"vue": "3.5.13", "vue": "3.5.13",
"vue-i18n": "10.0.5", "vue-i18n": "10.0.5",
"vue-router": "4.5.0", "vue-router": "4.5.0",
@@ -26,19 +26,19 @@
"@vitejs/plugin-vue": "5.2.3", "@vitejs/plugin-vue": "5.2.3",
"autoprefixer": "10.4.21", "autoprefixer": "10.4.21",
"release-it": "18.1.2", "release-it": "18.1.2",
"vite": "6.2.2", "vite": "6.2.3",
"vite-plugin-vue-devtools": "7.7.2" "vite-plugin-vue-devtools": "7.7.2"
}, },
"release-it": { "release-it": {
"git": { "git": {
"commit": true, "commit": true,
"requireCleanWorkingDir": false, "requireCleanWorkingDir": false,
"commitMessage": "🚀Bumped version to v${version}", "commitMessage": "chore(release): ${version}",
"requireBranch": "dev", "requireBranch": "dev",
"push": true, "push": true,
"tag": true, "tag": true,
"tagName": null, "tagName": "${version}",
"tagAnnotation": "v${version}" "tagAnnotation": "${version}"
}, },
"npm": { "npm": {
"publish": false "publish": false

386
pnpm-lock.yaml generated
View File

@@ -15,11 +15,11 @@ importers:
specifier: ^0.0.1 specifier: ^0.0.1
version: 0.0.1 version: 0.0.1
'@tailwindcss/vite': '@tailwindcss/vite':
specifier: 4.0.14 specifier: 4.0.17
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.17(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))
bwip-js: bwip-js:
specifier: 4.5.2 specifier: 4.5.3
version: 4.5.2 version: 4.5.3
marked: marked:
specifier: 15.0.7 specifier: 15.0.7
version: 15.0.7 version: 15.0.7
@@ -27,14 +27,14 @@ importers:
specifier: 0.5.1 specifier: 0.5.1
version: 0.5.1 version: 0.5.1
tailwindcss: tailwindcss:
specifier: 4.0.14 specifier: 4.0.17
version: 4.0.14 version: 4.0.17
toastify-js: toastify-js:
specifier: 1.12.0 specifier: 1.12.0
version: 1.12.0 version: 1.12.0
validator: validator:
specifier: 13.12.0 specifier: 13.15.0
version: 13.12.0 version: 13.15.0
vue: vue:
specifier: 3.5.13 specifier: 3.5.13
version: 3.5.13 version: 3.5.13
@@ -50,7 +50,7 @@ importers:
devDependencies: devDependencies:
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: 5.2.3 specifier: 5.2.3
version: 5.2.3(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13) version: 5.2.3(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13)
autoprefixer: autoprefixer:
specifier: 10.4.21 specifier: 10.4.21
version: 10.4.21(postcss@8.5.3) version: 10.4.21(postcss@8.5.3)
@@ -58,11 +58,11 @@ importers:
specifier: 18.1.2 specifier: 18.1.2
version: 18.1.2(@types/node@18.11.18) version: 18.1.2(@types/node@18.11.18)
vite: vite:
specifier: 6.2.2 specifier: 6.2.3
version: 6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1) version: 6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)
vite-plugin-vue-devtools: vite-plugin-vue-devtools:
specifier: 7.7.2 specifier: 7.7.2
version: 7.7.2(rollup@4.36.0)(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13) version: 7.7.2(rollup@4.37.0)(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13)
packages: packages:
@@ -619,98 +619,103 @@ packages:
rollup: rollup:
optional: true optional: true
'@rollup/rollup-android-arm-eabi@4.36.0': '@rollup/rollup-android-arm-eabi@4.37.0':
resolution: {integrity: sha512-jgrXjjcEwN6XpZXL0HUeOVGfjXhPyxAbbhD0BlXUB+abTOpbPiN5Wb3kOT7yb+uEtATNYF5x5gIfwutmuBA26w==} resolution: {integrity: sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==}
cpu: [arm] cpu: [arm]
os: [android] os: [android]
'@rollup/rollup-android-arm64@4.36.0': '@rollup/rollup-android-arm64@4.37.0':
resolution: {integrity: sha512-NyfuLvdPdNUfUNeYKUwPwKsE5SXa2J6bCt2LdB/N+AxShnkpiczi3tcLJrm5mA+eqpy0HmaIY9F6XCa32N5yzg==} resolution: {integrity: sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@rollup/rollup-darwin-arm64@4.36.0': '@rollup/rollup-darwin-arm64@4.37.0':
resolution: {integrity: sha512-JQ1Jk5G4bGrD4pWJQzWsD8I1n1mgPXq33+/vP4sk8j/z/C2siRuxZtaUA7yMTf71TCZTZl/4e1bfzwUmFb3+rw==} resolution: {integrity: sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@rollup/rollup-darwin-x64@4.36.0': '@rollup/rollup-darwin-x64@4.37.0':
resolution: {integrity: sha512-6c6wMZa1lrtiRsbDziCmjE53YbTkxMYhhnWnSW8R/yqsM7a6mSJ3uAVT0t8Y/DGt7gxUWYuFM4bwWk9XCJrFKA==} resolution: {integrity: sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@rollup/rollup-freebsd-arm64@4.36.0': '@rollup/rollup-freebsd-arm64@4.37.0':
resolution: {integrity: sha512-KXVsijKeJXOl8QzXTsA+sHVDsFOmMCdBRgFmBb+mfEb/7geR7+C8ypAml4fquUt14ZyVXaw2o1FWhqAfOvA4sg==} resolution: {integrity: sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==}
cpu: [arm64] cpu: [arm64]
os: [freebsd] os: [freebsd]
'@rollup/rollup-freebsd-x64@4.36.0': '@rollup/rollup-freebsd-x64@4.37.0':
resolution: {integrity: sha512-dVeWq1ebbvByI+ndz4IJcD4a09RJgRYmLccwlQ8bPd4olz3Y213uf1iwvc7ZaxNn2ab7bjc08PrtBgMu6nb4pQ==} resolution: {integrity: sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@rollup/rollup-linux-arm-gnueabihf@4.36.0': '@rollup/rollup-linux-arm-gnueabihf@4.37.0':
resolution: {integrity: sha512-bvXVU42mOVcF4le6XSjscdXjqx8okv4n5vmwgzcmtvFdifQ5U4dXFYaCB87namDRKlUL9ybVtLQ9ztnawaSzvg==} resolution: {integrity: sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@rollup/rollup-linux-arm-musleabihf@4.36.0': '@rollup/rollup-linux-arm-musleabihf@4.37.0':
resolution: {integrity: sha512-JFIQrDJYrxOnyDQGYkqnNBtjDwTgbasdbUiQvcU8JmGDfValfH1lNpng+4FWlhaVIR4KPkeddYjsVVbmJYvDcg==} resolution: {integrity: sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@rollup/rollup-linux-arm64-gnu@4.36.0': '@rollup/rollup-linux-arm64-gnu@4.37.0':
resolution: {integrity: sha512-KqjYVh3oM1bj//5X7k79PSCZ6CvaVzb7Qs7VMWS+SlWB5M8p3FqufLP9VNp4CazJ0CsPDLwVD9r3vX7Ci4J56A==} resolution: {integrity: sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@rollup/rollup-linux-arm64-musl@4.36.0': '@rollup/rollup-linux-arm64-musl@4.37.0':
resolution: {integrity: sha512-QiGnhScND+mAAtfHqeT+cB1S9yFnNQ/EwCg5yE3MzoaZZnIV0RV9O5alJAoJKX/sBONVKeZdMfO8QSaWEygMhw==} resolution: {integrity: sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@rollup/rollup-linux-loongarch64-gnu@4.36.0': '@rollup/rollup-linux-loongarch64-gnu@4.37.0':
resolution: {integrity: sha512-1ZPyEDWF8phd4FQtTzMh8FQwqzvIjLsl6/84gzUxnMNFBtExBtpL51H67mV9xipuxl1AEAerRBgBwFNpkw8+Lg==} resolution: {integrity: sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
'@rollup/rollup-linux-powerpc64le-gnu@4.36.0': '@rollup/rollup-linux-powerpc64le-gnu@4.37.0':
resolution: {integrity: sha512-VMPMEIUpPFKpPI9GZMhJrtu8rxnp6mJR3ZzQPykq4xc2GmdHj3Q4cA+7avMyegXy4n1v+Qynr9fR88BmyO74tg==} resolution: {integrity: sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
'@rollup/rollup-linux-riscv64-gnu@4.36.0': '@rollup/rollup-linux-riscv64-gnu@4.37.0':
resolution: {integrity: sha512-ttE6ayb/kHwNRJGYLpuAvB7SMtOeQnVXEIpMtAvx3kepFQeowVED0n1K9nAdraHUPJ5hydEMxBpIR7o4nrm8uA==} resolution: {integrity: sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
'@rollup/rollup-linux-s390x-gnu@4.36.0': '@rollup/rollup-linux-riscv64-musl@4.37.0':
resolution: {integrity: sha512-4a5gf2jpS0AIe7uBjxDeUMNcFmaRTbNv7NxI5xOCs4lhzsVyGR/0qBXduPnoWf6dGC365saTiwag8hP1imTgag==} resolution: {integrity: sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-s390x-gnu@4.37.0':
resolution: {integrity: sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
'@rollup/rollup-linux-x64-gnu@4.36.0': '@rollup/rollup-linux-x64-gnu@4.37.0':
resolution: {integrity: sha512-5KtoW8UWmwFKQ96aQL3LlRXX16IMwyzMq/jSSVIIyAANiE1doaQsx/KRyhAvpHlPjPiSU/AYX/8m+lQ9VToxFQ==} resolution: {integrity: sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@rollup/rollup-linux-x64-musl@4.36.0': '@rollup/rollup-linux-x64-musl@4.37.0':
resolution: {integrity: sha512-sycrYZPrv2ag4OCvaN5js+f01eoZ2U+RmT5as8vhxiFz+kxwlHrsxOwKPSA8WyS+Wc6Epid9QeI/IkQ9NkgYyQ==} resolution: {integrity: sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@rollup/rollup-win32-arm64-msvc@4.36.0': '@rollup/rollup-win32-arm64-msvc@4.37.0':
resolution: {integrity: sha512-qbqt4N7tokFwwSVlWDsjfoHgviS3n/vZ8LK0h1uLG9TYIRuUTJC88E1xb3LM2iqZ/WTqNQjYrtmtGmrmmawB6A==} resolution: {integrity: sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@rollup/rollup-win32-ia32-msvc@4.36.0': '@rollup/rollup-win32-ia32-msvc@4.37.0':
resolution: {integrity: sha512-t+RY0JuRamIocMuQcfwYSOkmdX9dtkr1PbhKW42AMvaDQa+jOdpUYysroTF/nuPpAaQMWp7ye+ndlmmthieJrQ==} resolution: {integrity: sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
'@rollup/rollup-win32-x64-msvc@4.36.0': '@rollup/rollup-win32-x64-msvc@4.37.0':
resolution: {integrity: sha512-aRXd7tRZkWLqGbChgcMMDEHjOKudo1kChb1Jt1IfR8cY/KIpgNviLeJy5FUb9IpSuQj8dU2fAYNMPW/hLKOSTw==} resolution: {integrity: sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@@ -725,81 +730,81 @@ packages:
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
'@tailwindcss/node@4.0.14': '@tailwindcss/node@4.0.17':
resolution: {integrity: sha512-Ux9NbFkKWYE4rfUFz6M5JFLs/GEYP6ysxT8uSyPn6aTbh2K3xDE1zz++eVK4Vwx799fzMF8CID9sdHn4j/Ab8w==} resolution: {integrity: sha512-LIdNwcqyY7578VpofXyqjH6f+3fP4nrz7FBLki5HpzqjYfXdF2m/eW18ZfoKePtDGg90Bvvfpov9d2gy5XVCbg==}
'@tailwindcss/oxide-android-arm64@4.0.14': '@tailwindcss/oxide-android-arm64@4.0.17':
resolution: {integrity: sha512-VBFKC2rFyfJ5J8lRwjy6ub3rgpY186kAcYgiUr8ArR8BAZzMruyeKJ6mlsD22Zp5ZLcPW/FXMasJiJBx0WsdQg==} resolution: {integrity: sha512-3RfO0ZK64WAhop+EbHeyxGThyDr/fYhxPzDbEQjD2+v7ZhKTb2svTWy+KK+J1PHATus2/CQGAGp7pHY/8M8ugg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@tailwindcss/oxide-darwin-arm64@4.0.14': '@tailwindcss/oxide-darwin-arm64@4.0.17':
resolution: {integrity: sha512-U3XOwLrefGr2YQZ9DXasDSNWGPZBCh8F62+AExBEDMLDfvLLgI/HDzY8Oq8p/JtqkAY38sWPOaNnRwEGKU5Zmg==} resolution: {integrity: sha512-e1uayxFQCCDuzTk9s8q7MC5jFN42IY7nzcr5n0Mw/AcUHwD6JaBkXnATkD924ZsHyPDvddnusIEvkgLd2CiREg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@tailwindcss/oxide-darwin-x64@4.0.14': '@tailwindcss/oxide-darwin-x64@4.0.17':
resolution: {integrity: sha512-V5AjFuc3ndWGnOi1d379UsODb0TzAS2DYIP/lwEbfvafUaD2aNZIcbwJtYu2DQqO2+s/XBvDVA+w4yUyaewRwg==} resolution: {integrity: sha512-d6z7HSdOKfXQ0HPlVx1jduUf/YtBuCCtEDIEFeBCzgRRtDsUuRtofPqxIVaSCUTOk5+OfRLonje6n9dF6AH8wQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@tailwindcss/oxide-freebsd-x64@4.0.14': '@tailwindcss/oxide-freebsd-x64@4.0.17':
resolution: {integrity: sha512-tXvtxbaZfcPfqBwW3f53lTcyH6EDT+1eT7yabwcfcxTs+8yTPqxsDUhrqe9MrnEzpNkd+R/QAjJapfd4tjWdLg==} resolution: {integrity: sha512-EjrVa6lx3wzXz3l5MsdOGtYIsRjgs5Mru6lDv4RuiXpguWeOb3UzGJ7vw7PEzcFadKNvNslEQqoAABeMezprxQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@tailwindcss/oxide-linux-arm-gnueabihf@4.0.14': '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.17':
resolution: {integrity: sha512-cSeLNWWqIWeSTmBntQvyY2/2gcLX8rkPFfDDTQVF8qbRcRMVPLxBvFVJyfSAYRNch6ZyVH2GI6dtgALOBDpdNA==} resolution: {integrity: sha512-65zXfCOdi8wuaY0Ye6qMR5LAXokHYtrGvo9t/NmxvSZtCCitXV/gzJ/WP5ksXPhff1SV5rov0S+ZIZU+/4eyCQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-arm64-gnu@4.0.14': '@tailwindcss/oxide-linux-arm64-gnu@4.0.17':
resolution: {integrity: sha512-bwDWLBalXFMDItcSXzFk6y7QKvj6oFlaY9vM+agTlwFL1n1OhDHYLZkSjaYsh6KCeG0VB0r7H8PUJVOM1LRZyg==} resolution: {integrity: sha512-+aaq6hJ8ioTdbJV5IA1WjWgLmun4T7eYLTvJIToiXLHy5JzUERRbIZjAcjgK9qXMwnvuu7rqpxzej+hGoEcG5g==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-arm64-musl@4.0.14': '@tailwindcss/oxide-linux-arm64-musl@4.0.17':
resolution: {integrity: sha512-gVkJdnR/L6iIcGYXx64HGJRmlme2FGr/aZH0W6u4A3RgPMAb+6ELRLi+UBiH83RXBm9vwCfkIC/q8T51h8vUJQ==} resolution: {integrity: sha512-/FhWgZCdUGAeYHYnZKekiOC0aXFiBIoNCA0bwzkICiMYS5Rtx2KxFfMUXQVnl4uZRblG5ypt5vpPhVaXgGk80w==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-x64-gnu@4.0.14': '@tailwindcss/oxide-linux-x64-gnu@4.0.17':
resolution: {integrity: sha512-EE+EQ+c6tTpzsg+LGO1uuusjXxYx0Q00JE5ubcIGfsogSKth8n8i2BcS2wYTQe4jXGs+BQs35l78BIPzgwLddw==} resolution: {integrity: sha512-gELJzOHK6GDoIpm/539Golvk+QWZjxQcbkKq9eB2kzNkOvrP0xc5UPgO9bIMNt1M48mO8ZeNenCMGt6tfkvVBg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-x64-musl@4.0.14': '@tailwindcss/oxide-linux-x64-musl@4.0.17':
resolution: {integrity: sha512-KCCOzo+L6XPT0oUp2Jwh233ETRQ/F6cwUnMnR0FvMUCbkDAzHbcyOgpfuAtRa5HD0WbTbH4pVD+S0pn1EhNfbw==} resolution: {integrity: sha512-68NwxcJrZn94IOW4TysMIbYv5AlM6So1luTlbYUDIGnKma1yTFGBRNEJ+SacJ3PZE2rgcTBNRHX1TB4EQ/XEHw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@tailwindcss/oxide-win32-arm64-msvc@4.0.14': '@tailwindcss/oxide-win32-arm64-msvc@4.0.17':
resolution: {integrity: sha512-AHObFiFL9lNYcm3tZSPqa/cHGpM5wOrNmM2uOMoKppp+0Hom5uuyRh0QkOp7jftsHZdrZUpmoz0Mp6vhh2XtUg==} resolution: {integrity: sha512-AkBO8efP2/7wkEXkNlXzRD4f/7WerqKHlc6PWb5v0jGbbm22DFBLbIM19IJQ3b+tNewQZa+WnPOaGm0SmwMNjw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@tailwindcss/oxide-win32-x64-msvc@4.0.14': '@tailwindcss/oxide-win32-x64-msvc@4.0.17':
resolution: {integrity: sha512-rNXXMDJfCJLw/ZaFTOLOHoGULxyXfh2iXTGiChFiYTSgKBKQHIGEpV0yn5N25WGzJJ+VBnRjHzlmDqRV+d//oQ==} resolution: {integrity: sha512-7/DTEvXcoWlqX0dAlcN0zlmcEu9xSermuo7VNGX9tJ3nYMdo735SHvbrHDln1+LYfF6NhJ3hjbpbjkMOAGmkDg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@tailwindcss/oxide@4.0.14': '@tailwindcss/oxide@4.0.17':
resolution: {integrity: sha512-M8VCNyO/NBi5vJ2cRcI9u8w7Si+i76a7o1vveoGtbbjpEYJZYiyc7f2VGps/DqawO56l3tImIbq2OT/533jcrA==} resolution: {integrity: sha512-B4OaUIRD2uVrULpAD1Yksx2+wNarQr2rQh65nXqaqbLY1jCd8fO+3KLh/+TH4Hzh2NTHQvgxVbPdUDOtLk7vAw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
'@tailwindcss/vite@4.0.14': '@tailwindcss/vite@4.0.17':
resolution: {integrity: sha512-y69ztPTRFy+13EPS/7dEFVl7q2Goh1pQueVO8IfGeyqSpcx/joNJXFk0lLhMgUbF0VFJotwRSb9ZY7Xoq3r26Q==} resolution: {integrity: sha512-HJbBYDlDVg5cvYZzECb6xwc1IDCEM3uJi3hEZp3BjZGCNGJcTsnCpan+z+VMW0zo6gR0U6O6ElqU1OoZ74Dhww==}
peerDependencies: peerDependencies:
vite: ^5.2.0 || ^6 vite: ^5.2.0 || ^6
@@ -961,8 +966,8 @@ packages:
resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
engines: {node: '>=18'} engines: {node: '>=18'}
bwip-js@4.5.2: bwip-js@4.5.3:
resolution: {integrity: sha512-RObBQLA1Ncy0cvpLoUGiX7PWupfRiRTemQXf+9wobBKjgHb6rXwO2f2YCAVJjVlCRoTRRiL18++ZF2946Ys4QA==} resolution: {integrity: sha512-RzODtC4xyl7mCyyfModA+EFyE4ZBlaMRAGX9LDGqjeskmIrzUqTyF++WxHr8ccX/9la4Ii5K9LCn60yv1lYwDA==}
hasBin: true hasBin: true
callsites@3.1.0: callsites@3.1.0:
@@ -1599,13 +1604,8 @@ packages:
resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==}
engines: {node: ^18.17.0 || >=20.5.0} engines: {node: ^18.17.0 || >=20.5.0}
nanoid@3.3.10: nanoid@3.3.11:
resolution: {integrity: sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==} resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
nanoid@3.3.8:
resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
@@ -1814,8 +1814,8 @@ packages:
rfdc@1.4.1: rfdc@1.4.1:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
rollup@4.36.0: rollup@4.37.0:
resolution: {integrity: sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q==} resolution: {integrity: sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'} engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true hasBin: true
@@ -1940,8 +1940,8 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
tailwindcss@4.0.14: tailwindcss@4.0.17:
resolution: {integrity: sha512-92YT2dpt671tFiHH/e1ok9D987N9fHD5VWoly1CdPD/Cd1HMglvZwP3nx2yTj2lbXDAHt8QssZkxTLCCTNL+xw==} resolution: {integrity: sha512-OErSiGzRa6rLiOvaipsDZvLMSpsBZ4ysB4f0VKGXUrjw2jfkJRd6kjRKV2+ZmTCNvwtvgdDam5D7w6WXsdLJZw==}
tapable@2.2.1: tapable@2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
@@ -2010,8 +2010,8 @@ packages:
resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==} resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
validator@13.12.0: validator@13.15.0:
resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} resolution: {integrity: sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==}
engines: {node: '>= 0.10'} engines: {node: '>= 0.10'}
vite-hot-client@0.2.4: vite-hot-client@0.2.4:
@@ -2040,8 +2040,8 @@ packages:
peerDependencies: peerDependencies:
vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0
vite@6.2.2: vite@6.2.3:
resolution: {integrity: sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==} resolution: {integrity: sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@@ -2683,69 +2683,72 @@ snapshots:
'@polka/url@1.0.0-next.28': {} '@polka/url@1.0.0-next.28': {}
'@rollup/pluginutils@5.1.4(rollup@4.36.0)': '@rollup/pluginutils@5.1.4(rollup@4.37.0)':
dependencies: dependencies:
'@types/estree': 1.0.6 '@types/estree': 1.0.6
estree-walker: 2.0.2 estree-walker: 2.0.2
picomatch: 4.0.2 picomatch: 4.0.2
optionalDependencies: optionalDependencies:
rollup: 4.36.0 rollup: 4.37.0
'@rollup/rollup-android-arm-eabi@4.36.0': '@rollup/rollup-android-arm-eabi@4.37.0':
optional: true optional: true
'@rollup/rollup-android-arm64@4.36.0': '@rollup/rollup-android-arm64@4.37.0':
optional: true optional: true
'@rollup/rollup-darwin-arm64@4.36.0': '@rollup/rollup-darwin-arm64@4.37.0':
optional: true optional: true
'@rollup/rollup-darwin-x64@4.36.0': '@rollup/rollup-darwin-x64@4.37.0':
optional: true optional: true
'@rollup/rollup-freebsd-arm64@4.36.0': '@rollup/rollup-freebsd-arm64@4.37.0':
optional: true optional: true
'@rollup/rollup-freebsd-x64@4.36.0': '@rollup/rollup-freebsd-x64@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-arm-gnueabihf@4.36.0': '@rollup/rollup-linux-arm-gnueabihf@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-arm-musleabihf@4.36.0': '@rollup/rollup-linux-arm-musleabihf@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-arm64-gnu@4.36.0': '@rollup/rollup-linux-arm64-gnu@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-arm64-musl@4.36.0': '@rollup/rollup-linux-arm64-musl@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-loongarch64-gnu@4.36.0': '@rollup/rollup-linux-loongarch64-gnu@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-powerpc64le-gnu@4.36.0': '@rollup/rollup-linux-powerpc64le-gnu@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-riscv64-gnu@4.36.0': '@rollup/rollup-linux-riscv64-gnu@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-s390x-gnu@4.36.0': '@rollup/rollup-linux-riscv64-musl@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-x64-gnu@4.36.0': '@rollup/rollup-linux-s390x-gnu@4.37.0':
optional: true optional: true
'@rollup/rollup-linux-x64-musl@4.36.0': '@rollup/rollup-linux-x64-gnu@4.37.0':
optional: true optional: true
'@rollup/rollup-win32-arm64-msvc@4.36.0': '@rollup/rollup-linux-x64-musl@4.37.0':
optional: true optional: true
'@rollup/rollup-win32-ia32-msvc@4.36.0': '@rollup/rollup-win32-arm64-msvc@4.37.0':
optional: true optional: true
'@rollup/rollup-win32-x64-msvc@4.36.0': '@rollup/rollup-win32-ia32-msvc@4.37.0':
optional: true
'@rollup/rollup-win32-x64-msvc@4.37.0':
optional: true optional: true
'@sec-ant/readable-stream@0.4.1': {} '@sec-ant/readable-stream@0.4.1': {}
@@ -2754,66 +2757,66 @@ snapshots:
'@sindresorhus/merge-streams@4.0.0': {} '@sindresorhus/merge-streams@4.0.0': {}
'@tailwindcss/node@4.0.14': '@tailwindcss/node@4.0.17':
dependencies: dependencies:
enhanced-resolve: 5.18.1 enhanced-resolve: 5.18.1
jiti: 2.4.2 jiti: 2.4.2
tailwindcss: 4.0.14 tailwindcss: 4.0.17
'@tailwindcss/oxide-android-arm64@4.0.14': '@tailwindcss/oxide-android-arm64@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-darwin-arm64@4.0.14': '@tailwindcss/oxide-darwin-arm64@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-darwin-x64@4.0.14': '@tailwindcss/oxide-darwin-x64@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-freebsd-x64@4.0.14': '@tailwindcss/oxide-freebsd-x64@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-linux-arm-gnueabihf@4.0.14': '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-linux-arm64-gnu@4.0.14': '@tailwindcss/oxide-linux-arm64-gnu@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-linux-arm64-musl@4.0.14': '@tailwindcss/oxide-linux-arm64-musl@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-linux-x64-gnu@4.0.14': '@tailwindcss/oxide-linux-x64-gnu@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-linux-x64-musl@4.0.14': '@tailwindcss/oxide-linux-x64-musl@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-win32-arm64-msvc@4.0.14': '@tailwindcss/oxide-win32-arm64-msvc@4.0.17':
optional: true optional: true
'@tailwindcss/oxide-win32-x64-msvc@4.0.14': '@tailwindcss/oxide-win32-x64-msvc@4.0.17':
optional: true optional: true
'@tailwindcss/oxide@4.0.14': '@tailwindcss/oxide@4.0.17':
optionalDependencies: optionalDependencies:
'@tailwindcss/oxide-android-arm64': 4.0.14 '@tailwindcss/oxide-android-arm64': 4.0.17
'@tailwindcss/oxide-darwin-arm64': 4.0.14 '@tailwindcss/oxide-darwin-arm64': 4.0.17
'@tailwindcss/oxide-darwin-x64': 4.0.14 '@tailwindcss/oxide-darwin-x64': 4.0.17
'@tailwindcss/oxide-freebsd-x64': 4.0.14 '@tailwindcss/oxide-freebsd-x64': 4.0.17
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.14 '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.17
'@tailwindcss/oxide-linux-arm64-gnu': 4.0.14 '@tailwindcss/oxide-linux-arm64-gnu': 4.0.17
'@tailwindcss/oxide-linux-arm64-musl': 4.0.14 '@tailwindcss/oxide-linux-arm64-musl': 4.0.17
'@tailwindcss/oxide-linux-x64-gnu': 4.0.14 '@tailwindcss/oxide-linux-x64-gnu': 4.0.17
'@tailwindcss/oxide-linux-x64-musl': 4.0.14 '@tailwindcss/oxide-linux-x64-musl': 4.0.17
'@tailwindcss/oxide-win32-arm64-msvc': 4.0.14 '@tailwindcss/oxide-win32-arm64-msvc': 4.0.17
'@tailwindcss/oxide-win32-x64-msvc': 4.0.14 '@tailwindcss/oxide-win32-x64-msvc': 4.0.17
'@tailwindcss/vite@4.0.14(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))': '@tailwindcss/vite@4.0.17(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))':
dependencies: dependencies:
'@tailwindcss/node': 4.0.14 '@tailwindcss/node': 4.0.17
'@tailwindcss/oxide': 4.0.14 '@tailwindcss/oxide': 4.0.17
lightningcss: 1.29.2 lightningcss: 1.29.2
tailwindcss: 4.0.14 tailwindcss: 4.0.17
vite: 6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1) vite: 6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)
'@tootallnate/quickjs-emscripten@0.23.0': {} '@tootallnate/quickjs-emscripten@0.23.0': {}
@@ -2823,9 +2826,9 @@ snapshots:
'@types/parse-path@7.0.3': {} '@types/parse-path@7.0.3': {}
'@vitejs/plugin-vue@5.2.3(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13)': '@vitejs/plugin-vue@5.2.3(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13)':
dependencies: dependencies:
vite: 6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1) vite: 6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)
vue: 3.5.13 vue: 3.5.13
'@vue/babel-helper-vue-transform-on@1.4.0': {} '@vue/babel-helper-vue-transform-on@1.4.0': {}
@@ -2889,14 +2892,14 @@ snapshots:
'@vue/devtools-api@6.6.4': {} '@vue/devtools-api@6.6.4': {}
'@vue/devtools-core@7.7.2(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13)': '@vue/devtools-core@7.7.2(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13)':
dependencies: dependencies:
'@vue/devtools-kit': 7.7.2 '@vue/devtools-kit': 7.7.2
'@vue/devtools-shared': 7.7.2 '@vue/devtools-shared': 7.7.2
mitt: 3.0.1 mitt: 3.0.1
nanoid: 5.1.4 nanoid: 5.1.4
pathe: 2.0.3 pathe: 2.0.3
vite-hot-client: 0.2.4(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)) vite-hot-client: 0.2.4(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))
vue: 3.5.13 vue: 3.5.13
transitivePeerDependencies: transitivePeerDependencies:
- vite - vite
@@ -3023,7 +3026,7 @@ snapshots:
dependencies: dependencies:
run-applescript: 7.0.0 run-applescript: 7.0.0
bwip-js@4.5.2: {} bwip-js@4.5.3: {}
callsites@3.1.0: {} callsites@3.1.0: {}
@@ -3590,9 +3593,7 @@ snapshots:
mute-stream@2.0.0: {} mute-stream@2.0.0: {}
nanoid@3.3.10: {} nanoid@3.3.11: {}
nanoid@3.3.8: {}
nanoid@5.1.4: {} nanoid@5.1.4: {}
@@ -3724,13 +3725,13 @@ snapshots:
postcss@8.4.49: postcss@8.4.49:
dependencies: dependencies:
nanoid: 3.3.8 nanoid: 3.3.11
picocolors: 1.1.1 picocolors: 1.1.1
source-map-js: 1.2.1 source-map-js: 1.2.1
postcss@8.5.3: postcss@8.5.3:
dependencies: dependencies:
nanoid: 3.3.10 nanoid: 3.3.11
picocolors: 1.1.1 picocolors: 1.1.1
source-map-js: 1.2.1 source-map-js: 1.2.1
@@ -3835,29 +3836,30 @@ snapshots:
rfdc@1.4.1: {} rfdc@1.4.1: {}
rollup@4.36.0: rollup@4.37.0:
dependencies: dependencies:
'@types/estree': 1.0.6 '@types/estree': 1.0.6
optionalDependencies: optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.36.0 '@rollup/rollup-android-arm-eabi': 4.37.0
'@rollup/rollup-android-arm64': 4.36.0 '@rollup/rollup-android-arm64': 4.37.0
'@rollup/rollup-darwin-arm64': 4.36.0 '@rollup/rollup-darwin-arm64': 4.37.0
'@rollup/rollup-darwin-x64': 4.36.0 '@rollup/rollup-darwin-x64': 4.37.0
'@rollup/rollup-freebsd-arm64': 4.36.0 '@rollup/rollup-freebsd-arm64': 4.37.0
'@rollup/rollup-freebsd-x64': 4.36.0 '@rollup/rollup-freebsd-x64': 4.37.0
'@rollup/rollup-linux-arm-gnueabihf': 4.36.0 '@rollup/rollup-linux-arm-gnueabihf': 4.37.0
'@rollup/rollup-linux-arm-musleabihf': 4.36.0 '@rollup/rollup-linux-arm-musleabihf': 4.37.0
'@rollup/rollup-linux-arm64-gnu': 4.36.0 '@rollup/rollup-linux-arm64-gnu': 4.37.0
'@rollup/rollup-linux-arm64-musl': 4.36.0 '@rollup/rollup-linux-arm64-musl': 4.37.0
'@rollup/rollup-linux-loongarch64-gnu': 4.36.0 '@rollup/rollup-linux-loongarch64-gnu': 4.37.0
'@rollup/rollup-linux-powerpc64le-gnu': 4.36.0 '@rollup/rollup-linux-powerpc64le-gnu': 4.37.0
'@rollup/rollup-linux-riscv64-gnu': 4.36.0 '@rollup/rollup-linux-riscv64-gnu': 4.37.0
'@rollup/rollup-linux-s390x-gnu': 4.36.0 '@rollup/rollup-linux-riscv64-musl': 4.37.0
'@rollup/rollup-linux-x64-gnu': 4.36.0 '@rollup/rollup-linux-s390x-gnu': 4.37.0
'@rollup/rollup-linux-x64-musl': 4.36.0 '@rollup/rollup-linux-x64-gnu': 4.37.0
'@rollup/rollup-win32-arm64-msvc': 4.36.0 '@rollup/rollup-linux-x64-musl': 4.37.0
'@rollup/rollup-win32-ia32-msvc': 4.36.0 '@rollup/rollup-win32-arm64-msvc': 4.37.0
'@rollup/rollup-win32-x64-msvc': 4.36.0 '@rollup/rollup-win32-ia32-msvc': 4.37.0
'@rollup/rollup-win32-x64-msvc': 4.37.0
fsevents: 2.3.3 fsevents: 2.3.3
run-applescript@7.0.0: {} run-applescript@7.0.0: {}
@@ -3960,7 +3962,7 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {} supports-preserve-symlinks-flag@1.0.0: {}
tailwindcss@4.0.14: {} tailwindcss@4.0.17: {}
tapable@2.2.1: {} tapable@2.2.1: {}
@@ -4015,16 +4017,16 @@ snapshots:
url-join@5.0.0: {} url-join@5.0.0: {}
validator@13.12.0: {} validator@13.15.0: {}
vite-hot-client@0.2.4(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)): vite-hot-client@0.2.4(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)):
dependencies: dependencies:
vite: 6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1) vite: 6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)
vite-plugin-inspect@0.8.9(rollup@4.36.0)(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)): vite-plugin-inspect@0.8.9(rollup@4.37.0)(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)):
dependencies: dependencies:
'@antfu/utils': 0.7.10 '@antfu/utils': 0.7.10
'@rollup/pluginutils': 5.1.4(rollup@4.36.0) '@rollup/pluginutils': 5.1.4(rollup@4.37.0)
debug: 4.4.0 debug: 4.4.0
error-stack-parser-es: 0.1.5 error-stack-parser-es: 0.1.5
fs-extra: 11.3.0 fs-extra: 11.3.0
@@ -4032,28 +4034,28 @@ snapshots:
perfect-debounce: 1.0.0 perfect-debounce: 1.0.0
picocolors: 1.1.1 picocolors: 1.1.1
sirv: 3.0.1 sirv: 3.0.1
vite: 6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1) vite: 6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
- supports-color - supports-color
vite-plugin-vue-devtools@7.7.2(rollup@4.36.0)(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13): vite-plugin-vue-devtools@7.7.2(rollup@4.37.0)(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13):
dependencies: dependencies:
'@vue/devtools-core': 7.7.2(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13) '@vue/devtools-core': 7.7.2(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))(vue@3.5.13)
'@vue/devtools-kit': 7.7.2 '@vue/devtools-kit': 7.7.2
'@vue/devtools-shared': 7.7.2 '@vue/devtools-shared': 7.7.2
execa: 9.5.2 execa: 9.5.2
sirv: 3.0.1 sirv: 3.0.1
vite: 6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1) vite: 6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)
vite-plugin-inspect: 0.8.9(rollup@4.36.0)(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)) vite-plugin-inspect: 0.8.9(rollup@4.37.0)(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))
vite-plugin-vue-inspector: 5.3.1(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)) vite-plugin-vue-inspector: 5.3.1(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1))
transitivePeerDependencies: transitivePeerDependencies:
- '@nuxt/kit' - '@nuxt/kit'
- rollup - rollup
- supports-color - supports-color
- vue - vue
vite-plugin-vue-inspector@5.3.1(vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)): vite-plugin-vue-inspector@5.3.1(vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)):
dependencies: dependencies:
'@babel/core': 7.26.10 '@babel/core': 7.26.10
'@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.10) '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.10)
@@ -4064,15 +4066,15 @@ snapshots:
'@vue/compiler-dom': 3.5.13 '@vue/compiler-dom': 3.5.13
kolorist: 1.8.0 kolorist: 1.8.0
magic-string: 0.30.17 magic-string: 0.30.17
vite: 6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1) vite: 6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
vite@6.2.2(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1): vite@6.2.3(@types/node@18.11.18)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.6.1):
dependencies: dependencies:
esbuild: 0.25.1 esbuild: 0.25.1
postcss: 8.5.3 postcss: 8.5.3
rollup: 4.36.0 rollup: 4.37.0
optionalDependencies: optionalDependencies:
'@types/node': 18.11.18 '@types/node': 18.11.18
fsevents: 2.3.3 fsevents: 2.3.3

View File

@@ -1,13 +1,13 @@
<template> <template>
<footer class="p-8"> <footer>
<p class="text-sm sm:py-2 sm:mt-0 mt-4 text-center md:text-left"> <p class="text-sm sm:py-2 sm:mt-0 mt-4 text-center md:text-left">
Lauf für Kaya! Selfservice<br>Copyright © 2025<br>proudly powered by Lauf für Kaya! Selfservice<br>Copyright © 2025<br>proudly powered by
<a class="underline" target="_blank" rel="noopener,noreferrer" <a class="underline" target="_blank" rel="noopener,noreferrer"
href="https://odit.services?ref=lfk">ODIT.Services</a><br> href="https://odit.services?ref=lfk">ODIT.Services</a><br>
<a target="_blank" rel="noopener,noreferrer" :href="[[imprint_url]]" class="underline">{{ <a target="_blank" rel="noopener,noreferrer" :href="[[imprint_url]]" class="underline">{{
$t('imprint') }}</a> <a target="_blank" rel="noopener,noreferrer" :href="[[privacy_url]]" class="underline">{{ $t('imprint') }}</a> <a target="_blank" rel="noopener,noreferrer" :href="[[privacy_url]]" class="underline">{{
$t('privacy_policy') }}</a> $t('privacy_policy') }}</a>
</p> </p>
</footer> </footer>
</template> </template>
<script> <script>

View File

@@ -13,15 +13,21 @@
"current_total_amount_in_eur": "Aktueller Gesamtbetrag (in €)", "current_total_amount_in_eur": "Aktueller Gesamtbetrag (in €)",
"delete_my_data": "Meine Daten löschen", "delete_my_data": "Meine Daten löschen",
"distance": "Distanz", "distance": "Distanz",
"donation_on_event_day": "Am Lauftag kann Bargeld in unsere Spendenbox gespendet werden 💶",
"download_certificate": "Urkunde herunterladen", "download_certificate": "Urkunde herunterladen",
"download_registrationcode": "Registrierungscode herunterladen", "download_registrationcode": "Registrierungscode herunterladen",
"e_mail_adress": "E-Mail Adresse", "e_mail_adress": "E-Mail Adresse",
"e_mail_des_sponsors": "E-Mail des Sponsors", "e_mail_des_sponsors": "E-Mail des Sponsors",
"error_requesting_the_login_link": "Fehler beim Anfordern des Login-Links...", "error_requesting_the_login_link": "Fehler beim Anfordern des Login-Links...",
"first_lap": "👏 erste Runde", "first_lap": "👏 erste Runde",
"geben_sie_ihre_handynummer_an": "Ihre Handynummer",
"hinweis": "Hinweis:",
"i_accept": "Ich habe die ", "i_accept": "Ich habe die ",
"i_accept_end": "gelesen und akzeptiert.", "i_accept_end": "gelesen und akzeptiert.",
"if_you_are_the_system_administrator_please_refer_to_the_official_product_documentation_readme_for_configuration_guidance": "Wenn Sie der Systemadministrator sind, finden Sie Konfigurationsanweisungen in der offiziellen Produktdokumentation / README.", "if_you_are_the_system_administrator_please_refer_to_the_official_product_documentation_readme_for_configuration_guidance": "Wenn Sie der Systemadministrator sind, finden Sie Konfigurationsanweisungen in der offiziellen Produktdokumentation / README.",
"ihr_nachname": "Ihr Nachname",
"ihr_vorname": "Ihr Vorname",
"ihre_e_mail_adresse": "Ihre E-Mail Adresse",
"imprint": "Impressum", "imprint": "Impressum",
"invalid_input_phone_number_should_be_international_format": "ungültige Eingabe... Die Telefonnummer sollte ein internationales Format haben", "invalid_input_phone_number_should_be_international_format": "ungültige Eingabe... Die Telefonnummer sollte ein internationales Format haben",
"lap_time": "Rundenzeit", "lap_time": "Rundenzeit",
@@ -38,7 +44,7 @@
"not_registered_yet": "Noch nicht registriert?", "not_registered_yet": "Noch nicht registriert?",
"organization": "Organisation", "organization": "Organisation",
"ort": "Ort", "ort": "Ort",
"phone_number": "Telefonnummer (international formatiert)", "phone_number": "Handynummer (optional)",
"please_provide_a_valid_zipcode": "Bitte geben Sie eine gültige Postleitzahl an...", "please_provide_a_valid_zipcode": "Bitte geben Sie eine gültige Postleitzahl an...",
"please_provide_valid_mail": "Bitte geben Sie eine gültige E-Mail Adresse an", "please_provide_valid_mail": "Bitte geben Sie eine gültige E-Mail Adresse an",
"plz": "PLZ", "plz": "PLZ",
@@ -49,10 +55,11 @@
"profile": "Profil", "profile": "Profil",
"provide_address": "Adresse angeben?", "provide_address": "Adresse angeben?",
"register": { "register": {
"register_now": "Jetzt für den Lauf für Kaya! 2025 registrieren." "register_now": "Jetzt für den LfK! 2025 registrieren."
}, },
"register_now": "Jetzt registrieren!", "register_now": "Jetzt registrieren!",
"register_now_small": "Jetzt registrieren", "register_now_small": "Jetzt registrieren",
"registration_local_phone_nr": "Handynummern ohne Vorwahl werden als deutsche Telefonnummer gewertet",
"registration_running": "Registrierung läuft...", "registration_running": "Registrierung läuft...",
"registrationcode": "Registrierungscode", "registrationcode": "Registrierungscode",
"registrieren": "Registrieren", "registrieren": "Registrieren",
@@ -60,6 +67,7 @@
"registrierungscode_generiert": "Registrierungscode generiert!", "registrierungscode_generiert": "Registrierungscode generiert!",
"registrierungscode_wird_generiert": "Registrierungscode wird generiert...", "registrierungscode_wird_generiert": "Registrierungscode wird generiert...",
"resend_the_registration_mail": "Login-Link anfordern", "resend_the_registration_mail": "Login-Link anfordern",
"spenden_info": "Spenden-Info",
"sponsor_add_agree": "Mit dem Absenden bestätige ich, dass der Sponsor mit der Übermittlung seiner Daten einverstanden ist und ich dessen Berechtigung habe", "sponsor_add_agree": "Mit dem Absenden bestätige ich, dass der Sponsor mit der Übermittlung seiner Daten einverstanden ist und ich dessen Berechtigung habe",
"sponsoring": "Sponsoring", "sponsoring": "Sponsoring",
"sponsoring_pro_kilometer_in_eur": "Sponsoring pro Kilometer (in €)", "sponsoring_pro_kilometer_in_eur": "Sponsoring pro Kilometer (in €)",

View File

@@ -13,15 +13,21 @@
"current_total_amount_in_eur": "Current total amount (in €)", "current_total_amount_in_eur": "Current total amount (in €)",
"delete_my_data": "Delete my data", "delete_my_data": "Delete my data",
"distance": "Distance", "distance": "Distance",
"donation_on_event_day": "On race day, cash can be donated to our donation box 💶",
"download_certificate": "Download certificate", "download_certificate": "Download certificate",
"download_registrationcode": "Download registrationcode", "download_registrationcode": "Download registrationcode",
"e_mail_adress": "mail address", "e_mail_adress": "mail address",
"e_mail_des_sponsors": "E-Mail of the Sponsor", "e_mail_des_sponsors": "E-Mail of the Sponsor",
"error_requesting_the_login_link": "Error requesting the login link...", "error_requesting_the_login_link": "Error requesting the login link...",
"first_lap": "👏 first lap", "first_lap": "👏 first lap",
"geben_sie_ihre_handynummer_an": "Your mobile number",
"hinweis": "Note:",
"i_accept": "I have read and accepted the ", "i_accept": "I have read and accepted the ",
"i_accept_end": "", "i_accept_end": "",
"if_you_are_the_system_administrator_please_refer_to_the_official_product_documentation_readme_for_configuration_guidance": "If you are the system administrator, please refer to the official product documentation/ README for configuration guidance.", "if_you_are_the_system_administrator_please_refer_to_the_official_product_documentation_readme_for_configuration_guidance": "If you are the system administrator, please refer to the official product documentation/ README for configuration guidance.",
"ihr_nachname": "Your last name",
"ihr_vorname": "Your first name",
"ihre_e_mail_adresse": "Your email address",
"imprint": "Imprint", "imprint": "Imprint",
"invalid_input_phone_number_should_be_international_format": "invalid input... phone number should be international format", "invalid_input_phone_number_should_be_international_format": "invalid input... phone number should be international format",
"lap_time": "Lap time", "lap_time": "Lap time",
@@ -38,7 +44,7 @@
"not_registered_yet": "Not registered yet?", "not_registered_yet": "Not registered yet?",
"organization": "Organization", "organization": "Organization",
"ort": "City", "ort": "City",
"phone_number": "Phone Number (international format)", "phone_number": "mobile number (optional)",
"please_provide_a_valid_zipcode": "Please provide a valid zipcode...", "please_provide_a_valid_zipcode": "Please provide a valid zipcode...",
"please_provide_valid_mail": "Please provide a valid mail address.", "please_provide_valid_mail": "Please provide a valid mail address.",
"plz": "zipcode", "plz": "zipcode",
@@ -49,10 +55,11 @@
"profile": "Profile", "profile": "Profile",
"provide_address": "Provide a postal address?", "provide_address": "Provide a postal address?",
"register": { "register": {
"register_now": "Register now for Lauf für Kaya! 2025." "register_now": "Register now for LfK! 2025."
}, },
"register_now": "Register now!", "register_now": "Register now!",
"register_now_small": "Register now", "register_now_small": "Register now",
"registration_local_phone_nr": "Mobile numbers without an area code are considered German phone numbers",
"registration_running": "registration is running...", "registration_running": "registration is running...",
"registrationcode": "Registration Code", "registrationcode": "Registration Code",
"registrieren": "Register Now", "registrieren": "Register Now",
@@ -60,6 +67,7 @@
"registrierungscode_generiert": "created registration code!", "registrierungscode_generiert": "created registration code!",
"registrierungscode_wird_generiert": "creating registration code...", "registrierungscode_wird_generiert": "creating registration code...",
"resend_the_registration_mail": "Send me a login link", "resend_the_registration_mail": "Send me a login link",
"spenden_info": "info for donations",
"sponsor_add_agree": "By submitting, I confirm that the sponsor agrees to the transmission of his data and that I have his authorization", "sponsor_add_agree": "By submitting, I confirm that the sponsor agrees to the transmission of his data and that I have his authorization",
"sponsoring": "Sponsoring", "sponsoring": "Sponsoring",
"sponsoring_pro_kilometer_in_eur": "Sponsoring per Kilometer (in €)", "sponsoring_pro_kilometer_in_eur": "Sponsoring per Kilometer (in €)",

View File

@@ -4,8 +4,7 @@
<section class="px-4 py-24 mx-auto"> <section class="px-4 py-24 mx-auto">
<div class="w-full mx-auto text-center"> <div class="w-full mx-auto text-center">
<img src="/favicon-lfk.png" class="h-32 mx-auto" /> <img src="/favicon-lfk.png" class="h-32 mx-auto" />
<h1 <h1 class="mb-6 text-4xl font-extrabold leading-none tracking-normal md:text-6xl md:tracking-tight">
class="mb-6 text-4xl font-extrabold leading-none tracking-normal md:text-6xl md:tracking-tight">
Lauf Für Kaya!<br>2025</h1> Lauf Für Kaya!<br>2025</h1>
<h2 class="mb-6 text-xl font-bold leading-none tracking-normal md:text-3xl md:tracking-tight"> <h2 class="mb-6 text-xl font-bold leading-none tracking-normal md:text-3xl md:tracking-tight">
Selfservice Portal</h2> Selfservice Portal</h2>
@@ -18,7 +17,9 @@
</div> </div>
</section> </section>
</div> </div>
<Footer /> <div class="p-8">
<Footer />
</div>
</template> </template>
<script setup> <script setup>

View File

@@ -1,139 +1,122 @@
<template> <template>
<div class="w-full p-4 lg:px-48 xl:w-2/3 xl:mx-auto"> <div class="w-full p-4 lg:px-48 xl:w-2/3 xl:mx-auto">
<div class="md:pr-10 md:mb-0 mb-6 pr-0 w-full text-center text-black dark:text-gray-200"> <div class="md:pr-10 md:mb-0 mb-6 pr-0 w-full text-center text-black dark:text-gray-200">
<img src="/favicon-lfk.png" class="h-20 mx-auto" /> <img src="/favicon-lfk.png" class="h-20 mx-auto" />
<div v-if="loadstate === 'loaded'"> <div v-if="loadstate === 'loaded'">
<h1 class="text-3xl font-bold whitespace-nowrap" v-text="(state.firstname || '') + <h1 class="text-3xl font-bold whitespace-nowrap" v-text="(state.firstname || '') +
' ' + ' ' +
(state.middlename || '') + (state.middlename || '') +
' ' + ' ' +
(state.lastname || '') (state.lastname || '')
"></h1> "></h1>
<p class="text-md whitespace-nowrap">Team: {{ state.group }}</p> <p v-if="state.group === 'Citizen'" class="text-md whitespace-nowrap">Bürgerlauf<br>Start: 14:00 Uhr</p>
</div> <p v-else class="text-md whitespace-nowrap">Team: {{ state.group }}</p>
<h1 v-else class="text-3xl font-bold whitespace-nowrap">Daten werden geladen...</h1>
</div> </div>
<div v-if="loadstate === 'loaded'" class="flex flex-wrap"> <h1 v-else class="text-3xl font-bold whitespace-nowrap">Daten werden geladen...</h1>
<div class="w-full"> </div>
<div class=""> <div v-if="loadstate === 'loaded'" class="flex flex-wrap">
<div class="grid grid-cols-3 text-center gap-1"> <div class="w-full">
<button @click="() => { <div class="">
state.activetab = 'profile'; <div class="grid grid-cols-3 text-center gap-1">
} <button @click="() => {
" :class="{ state.activetab = 'profile';
'tab-active font-medium bg-blue-600 hover:bg-blue-700 text-white': }
state.activetab === 'profile', " :class="{
'bg-neutral-200': 'tab-active font-medium bg-blue-600 hover:bg-blue-700 text-white':
state.activetab !== 'profile', state.activetab === 'profile',
}" class="cursor-pointer rounded-md p-2 py-3 md:py-4 md:px-6 block" type="button"> 'bg-neutral-200':
{{ $t("profile") }} state.activetab !== 'profile',
</button> }" class="cursor-pointer rounded-md p-2 py-3 md:py-4 md:px-6 block" type="button">
<button @click="() => { {{ $t("profile") }}
state.activetab = 'laptimes'; </button>
} <button @click="() => {
" :class="{ state.activetab = 'laptimes';
'tab-active font-medium bg-blue-600 hover:bg-blue-700 text-white': }
state.activetab === 'laptimes', " :class="{
'bg-neutral-200': 'tab-active font-medium bg-blue-600 hover:bg-blue-700 text-white':
state.activetab !== 'laptimes', state.activetab === 'laptimes',
}" class="cursor-pointer rounded-md p-2 py-3 md:py-4 md:px-6 block" type="button"> 'bg-neutral-200':
{{ $t("lap_times") }} state.activetab !== 'laptimes',
</button> }" class="cursor-pointer rounded-md p-2 py-3 md:py-4 md:px-6 block" type="button">
<button @click="() => { {{ $t("lap_times") }}
state.activetab = 'sponsorings'; </button>
} <button @click="() => {
" :class="{ state.activetab = 'sponsorings';
'tab-active font-medium bg-blue-600 hover:bg-blue-700 text-white': }
state.activetab === 'sponsorings', " :class="{
'bg-neutral-200': 'tab-active font-medium bg-blue-600 hover:bg-blue-700 text-white':
state.activetab !== 'sponsorings', state.activetab === 'sponsorings',
}" class="cursor-pointer rounded-md p-2 py-3 md:py-4 md:px-6 block" type="button"> 'bg-neutral-200':
{{ $t("sponsoring") }} state.activetab !== 'sponsorings',
</button> }" class="cursor-pointer rounded-md p-2 py-3 md:py-4 md:px-6 block" type="button">
</div> {{ $t("sponsoring") }}
<div v-if="state.activetab === 'profile'" class="tab-content block"> </button>
<div class="w-full mx-auto"> </div>
<div class="flex flex-col"> <div v-if="state.activetab === 'profile'" class="tab-content block">
<div class="flex flex-wrap w-full"> <div class="w-full mx-auto">
<div class="w-full"> <div class="flex flex-col">
<div v-if="state.delete_active === false"> <div class="flex flex-wrap w-full">
<button type="button" <div class="w-full">
class="mt-2 focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md bg-blue-600 hover:bg-blue-700 hover:shadow-lg w-full md:w-auto cursor-pointer mb-1 md:mr-1" <div v-if="state.delete_active === false">
@click="get_certificate"> <button type="button"
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" class="mt-2 focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md bg-blue-600 hover:bg-blue-700 hover:shadow-lg w-full md:w-auto cursor-pointer mb-1 md:mr-1"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" @click="get_certificate">
class="inline-block"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /> stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
<polyline points="7 10 12 15 17 10" /> class="inline-block">
<line x1="12" x2="12" y1="15" y2="3" /> <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
</svg> <polyline points="7 10 12 15 17 10" />
{{ $t("download_certificate") }} <line x1="12" x2="12" y1="15" y2="3" />
</button> </svg>
{{ $t("download_certificate") }}
</button>
</div> </div>
<div> <div>
<div class="text-lg">{{ $t("registrationcode") }}</div> <div class="text-lg">{{ $t("registrationcode") }}</div>
<img class="w-full md:w-auto mb-2 bg-white p-2" alt="Registrierungscode" :src="state.barcode" /> <img class="w-full md:w-auto mb-2 bg-white p-2" alt="Registrierungscode" :src="state.barcode" />
<button type="button" <button type="button"
class="focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md bg-blue-600 hover:bg-blue-700 hover:shadow-lg w-full md:w-auto cursor-pointer mb-1 md:mr-1" class="focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md bg-blue-600 hover:bg-blue-700 hover:shadow-lg w-full md:w-auto cursor-pointer mb-1 md:mr-1"
@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 xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="inline-block"> class="inline-block">
<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" x2="12" y1="15" y2="3" /> <line x1="12" x2="12" y1="15" y2="3" />
</svg> </svg>
{{ $t("download_registrationcode") }} {{ $t("download_registrationcode") }}
</button> </button>
</div> </div>
<div class="mb-2"> <div class="mb-2">
<div class="text-lg">{{ $t("e_mail_adress") }}</div> <div class="text-lg">{{ $t("e_mail_adress") }}</div>
<p v-text="state.email || '---'" /> <p v-text="state.email || '---'" />
</div> </div>
<div class="mb-2"> <div class="mb-2">
<div class="text-lg">{{ $t("phone_number") }}</div> <div class="text-lg">{{ $t("phone_number") }}</div>
<p v-text="state.phone || '---'" /> <p v-text="state.phone || '---'" />
</div>
</div> </div>
</div> </div>
</div> </div>
<div v-if="state.delete_active === true"> </div>
<button type="button" <div v-if="state.delete_active === true">
class="focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md mb-1 md:mb-auto w-full md:w-auto cursor-pointer bg-blue-600 hover:bg-blue-700 hover:shadow-lg" <button type="button"
@click="() => { class="focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md mb-1 md:mb-auto w-full md:w-auto cursor-pointer bg-blue-600 hover:bg-blue-700 hover:shadow-lg"
state.delete_active = false;
}
">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="inline-block">
<circle cx="12" cy="12" r="10" />
<path d="m4.9 4.9 14.2 14.2" />
</svg>
{{ $t("cancel_keep_my_data") }}
</button>
<button type="button"
class="focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md w-full md:w-auto cursor-pointer bg-red-600 hover:bg-red-700 hover:shadow-lg md:ml-1"
@click="delete_me">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="inline-block">
<path d="M3 6h18" />
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
<line x1="10" x2="10" y1="11" y2="17" />
<line x1="14" x2="14" y1="11" y2="17" />
</svg>
{{ $t("confirm_delete_all_of_my_data") }}
</button>
</div>
<button v-else type="button"
class="focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md bg-red-600 hover:bg-red-700 hover:shadow-lg w-full md:w-auto cursor-pointer"
@click="() => { @click="() => {
state.delete_active = true; state.delete_active = false;
} }
"> ">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="inline-block">
<circle cx="12" cy="12" r="10" />
<path d="m4.9 4.9 14.2 14.2" />
</svg>
{{ $t("cancel_keep_my_data") }}
</button>
<button type="button"
class="focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md w-full md:w-auto cursor-pointer bg-red-600 hover:bg-red-700 hover:shadow-lg md:ml-1"
@click="delete_me">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="inline-block"> class="inline-block">
@@ -143,281 +126,246 @@
<line x1="10" x2="10" y1="11" y2="17" /> <line x1="10" x2="10" y1="11" y2="17" />
<line x1="14" x2="14" y1="11" y2="17" /> <line x1="14" x2="14" y1="11" y2="17" />
</svg> </svg>
{{ $t("delete_my_data") }} {{ $t("confirm_delete_all_of_my_data") }}
</button> </button>
</div> </div>
<button v-else type="button"
class="focus:border-black focus:ring-2 focus:ring-black text-white text-base font-medium md:text-sm py-3.5 px-5 md:py-2.5 md:px-5 rounded-md bg-red-600 hover:bg-red-700 hover:shadow-lg w-full md:w-auto cursor-pointer"
@click="() => {
state.delete_active = true;
}
">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="inline-block">
<path d="M3 6h18" />
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
<line x1="10" x2="10" y1="11" y2="17" />
<line x1="14" x2="14" y1="11" y2="17" />
</svg>
{{ $t("delete_my_data") }}
</button>
</div> </div>
</div> </div>
<div v-if="state.activetab === 'laptimes'" class="tab-content block"> </div>
<div class="py-4 w-full"> <div v-if="state.activetab === 'laptimes'" class="tab-content block">
<section class="dark:bg-gray-900 body-font"> <div class="py-4 w-full">
<div class="mx-auto"> <section class="dark:bg-gray-900 body-font">
<div class="w-full mx-auto"> <div class="mx-auto">
<div v-if="state.scans.length > 0"> <div class="w-full mx-auto">
<p class="mb-2"> <div v-if="state.scans.length > 0">
{{ $t('total_distance') }}: {{ getReadableDistanceForUI() }} <p class="mb-2">
</p> {{ $t('total_distance') }}: {{ getTotalReadableDistance() }}
</p>
<table class="table-auto w-full text-left whitespace-no-wrap"> <table class="table-auto w-full text-left whitespace-no-wrap">
<thead class=" <thead class="
text-black text-black
bg-gray-300 bg-gray-300
dark:text-white dark:text-white
text-sm text-sm
dark:bg-gray-800 dark:bg-gray-800
"> ">
<tr> <tr>
<th class=" <th class="
px-4 px-4
py-3 py-3
title-font title-font
tracking-wider tracking-wider
font-medium font-medium
"> ">
{{ $t("distance") }} {{ $t("distance") }}
</th> </th>
<th class=" <th class="
px-4 px-4
py-3 py-3
title-font title-font
tracking-wider tracking-wider
font-medium font-medium
"> ">
{{ $t("lap_time") }} {{ $t("lap_time") }}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody class="text-gray-900 dark:text-gray-50"> <tbody class="text-gray-900 dark:text-gray-50">
<tr v-for="s in state.scans" :key="s.id"> <tr v-for="s in state.scans" :key="s.id">
<td class="px-4 py-3"> <td class="px-4 py-3">
<span v-text="s.distance_readable"></span> <span v-text="s.distance_readable"></span>
</td> </td>
<td class="px-4 py-3" v-text="s.lapTime_readable"></td> <td class="px-4 py-3" v-text="s.lapTime_readable"></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<div v-else class=" <div v-else class="
text-center text-center
font-medium font-medium
text-black text-black
dark:text-white dark:text-white
text-xl text-xl
"> ">
<img src="../assets/empty_laps.svg" class="mx-auto h-56" <img src="../assets/empty_laps.svg" class="mx-auto h-56"
:alt="[[$t('no_laps_scans_were_recorded_yet')]]" /> :alt="[[$t('no_laps_scans_were_recorded_yet')]]" />
{{ $t("no_laps_scans_were_recorded_yet") }} {{ $t("no_laps_scans_were_recorded_yet") }}
</div>
</div> </div>
</div> </div>
</section>
</div>
</div>
<div v-if="state.activetab === 'sponsorings'" class="tab-content block">
<div v-if="mode === 'add_sponsoring'">
<h1 class="text-3xl">{{ $t('add_sponsoring') }}</h1>
<form>
<div class="mt-6 grid gap-4 lg:gap-6">
<!-- Grid -->
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-6">
<div>
<label for="sponsorvorname"
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"
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">
</div>
<div>
<label for="sponsornachname"
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"
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">
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-6">
<!-- End Grid -->
<div>
<label for="sponsortel" class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{
$t('telefonnummer_des_sponsors') }}</label>
<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">
</div>
<div>
<label for="sponsormail" class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{
$t('e_mail_des_sponsors') }}</label>
<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">
</div>
</div>
<div>
<label for="eurokilometer" class="block mb-2 text-sm text-gray-700 font-medium dark:text-white">{{
$t('sponsoring_pro_kilometer_in_eur') }}</label>
<input v-bind="newsponsor_value" type="number" name="eurokilometer" id="eurokilometer"
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">
</div>
</div>
</form>
<!-- End Grid -->
<!-- Checkbox -->
<div class="mt-3 flex">
<div class="flex">
<input v-model="newsponsor_check" id="sponsor_agree" name="sponsor_agree" type="checkbox"
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 class="ms-3">
<label for="sponsor_agree" class="text-sm text-gray-600 dark:text-neutral-400">{{
$t('sponsor_add_agree') }}</label>
</div>
</div> </div>
<!-- End Checkbox --> </section>
</div>
<button :disabled="!newsponsor_check" @click="addSponsoring" type="button" </div>
class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-teal-100 text-teal-800 hover:bg-teal-200 focus:outline-hidden focus:bg-teal-200 disabled:opacity-50 disabled:pointer-events-none dark:text-teal-500 dark:bg-teal-800/30 dark:hover:bg-teal-800/20 dark:focus:bg-teal-800/20 mt-2 cursor-pointer"> <div v-if="state.activetab === 'sponsorings'" class="tab-content block">
{{ $t('add_sponsoring') }} <div
</button> class="bg-white border border-gray-200 rounded-lg shadow-lg p-4 dark:bg-neutral-800 dark:border-neutral-700 mt-2 font-medium"
role="alert" tabindex="-1" aria-labelledby="hs-discovery-label">
<div class="flex">
<div class="shrink-0">
<svg class="shrink-0 size-4 text-blue-600 mt-1" xmlns="http://www.w3.org/2000/svg" width="24"
height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 16v-4"></path>
<path d="M12 8h.01"></path>
</svg>
</div>
<div class="ms-3">
<h3 id="hs-discovery-label" class="text-gray-800 font-semibold dark:text-white">
{{ $t('spenden_info') }}
</h3>
<p class="mt-2 text-sm text-gray-700 dark:text-neutral-400">
{{ $t('donation_on_event_day') }}
</p>
</div>
</div> </div>
<div v-else> </div>
<div class="py-4 w-full"> <div class="py-4 w-full">
<section class="dark:bg-gray-900 body-font"> <section class="dark:bg-gray-900 body-font">
<div class="mx-auto"> <div class="mx-auto">
<div class="w-full mx-auto"> <div class="w-full mx-auto">
<table v-if="state.sponsorings.length > 0" class="table-auto w-full text-left whitespace-no-wrap"> <table v-if="state.sponsorings.length > 0" class="table-auto w-full text-left whitespace-no-wrap">
<thead class=" <thead class="
text-black text-black
bg-gray-300 bg-gray-300
dark:text-white dark:text-white
text-sm text-sm
dark:bg-gray-800 dark:bg-gray-800
"> ">
<tr> <tr>
<th class=" <th class="
px-4 px-4
py-3 py-3
title-font title-font
tracking-wider tracking-wider
font-medium font-medium
"> ">
Name Name
</th> </th>
<th class=" <th class="
px-4 px-4
py-3 py-3
title-font title-font
tracking-wider tracking-wider
font-medium font-medium
"> ">
{{ $t("amount_per_kilometer_in_eur") }} {{ $t("amount_per_kilometer_in_eur") }}
</th> </th>
<th class=" <th class="
px-4 px-4
py-3 py-3
title-font title-font
tracking-wider tracking-wider
font-medium font-medium
"> ">
{{ $t("current_total_amount_in_eur") }} {{ $t("current_total_amount_in_eur") }}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody class="text-gray-900 dark:text-gray-50"> <tbody class="text-gray-900 dark:text-gray-50">
<tr class="odd:bg-white even:bg-gray-100 dark:odd:bg-neutral-900 dark:even:bg-neutral-800" <tr class="odd:bg-white even:bg-gray-100 dark:odd:bg-neutral-900 dark:even:bg-neutral-800"
v-for="s in state.sponsorings" :key="s.id"> v-for="s in state.sponsorings" :key="s.id">
<td class="px-4 py-3"> <td class="px-4 py-3">
<span v-text="s.donor.firstname + ' '"></span> <span v-text="s.donor.firstname + ' '"></span>
<span v-if="s.donor.middlename"> <span v-if="s.donor.middlename">
<span v-text="s.donor.middlename"></span> <span v-text="s.donor.middlename"></span>
</span> </span>
<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 v-text="(s.amountPerDistance / 100) <span v-text="(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 v-text="(s.amount / 100) <span v-text="(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-black <tfoot class="text-black
bg-gray-300 bg-gray-300
border-t-2 border-t-2
border-t-current border-t-current
dark:text-white dark:text-white
text-sm text-sm
dark:bg-gray-800"> dark:bg-gray-800">
<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 v-text="( <span v-text="(
state.sponsorings.reduce(function ( state.sponsorings.reduce(function (
sum, sum,
current current
) { ) {
return sum + current.amountPerDistance; return sum + current.amountPerDistance;
}, },
0) / 100 0) / 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 v-text="( <span v-text="(
state.sponsorings.reduce(function ( state.sponsorings.reduce(function (
sum, sum,
current current
) { ) {
return sum + current.amount; return sum + current.amount;
}, },
0) / 100 0) / 100
) )
.toFixed(2) .toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' }) .toLocaleString('de-DE', { valute: 'EUR' })
"></span>€ "></span>€
</td> </td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
<div v-else class=" <div v-else class="
text-center text-center
font-medium font-medium
text-black text-black
dark:text-white dark:text-white
text-xl text-xl
"> ">
<img src="../assets/empty_laps.svg" class="h-56 mx-auto" :alt="[ <img src="../assets/empty_laps.svg" class="h-56 mx-auto" :alt="[
[$t('no_sponsorings_for_you_were_recorded_yet')], [$t('no_sponsorings_for_you_were_recorded_yet')],
]" /> ]" />
{{ $t("no_sponsorings_for_you_were_recorded_yet") }} {{ $t("no_sponsorings_for_you_were_recorded_yet") }}
</div>
<!-- <button
class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-teal-100 text-teal-800 hover:bg-teal-200 focus:outline-hidden focus:bg-teal-200 disabled:opacity-50 disabled:pointer-events-none dark:text-teal-500 dark:bg-teal-800/30 dark:hover:bg-teal-800/20 dark:focus:bg-teal-800/20 mt-2"
@click="mode = 'add_sponsoring'">{{ $t('add_sponsoring') }}</button> -->
</div>
</div> </div>
</section> </div>
</div> </div>
</div> </section>
</div> </div>
</div> </div>
</div> </div>
<!-- --> </div>
<Footer></Footer>
</div> </div>
<!-- -->
<Footer />
</template> </template>
<script setup> <script setup>
@@ -430,22 +378,6 @@ import { useI18n } from 'vue-i18n';
import { TYPE, useToast } from "vue-toastification"; import { TYPE, useToast } from "vue-toastification";
const { t } = useI18n() const { t } = useI18n()
const loadstate = ref("loading") const loadstate = ref("loading")
const mode = ref("")
//
const newsponsor_check = ref(false)
const newsponsor_value = ref("")
const newsponsor_mail = ref("")
const newsponsor_tel = ref("")
const newsponsor_vorname = ref("")
const newsponsor_nachname = ref("")
function shareSponsorLink() {
navigator.share({
title: state.firstname,
text: "Am 23.05.2025 findet der Lauf für Kaya! statt 🏃‍♂️🏃‍♀️\nWerde mein Sponsor beim Lauf für Kaya! 2025 und unterstütze mich pro gelaufenem Kilometer: https://lauf-fuer-kaya.de",
// url: "https://lauf-fuer-kaya.de",
})
}
function textToBase64Barcode(text) { function textToBase64Barcode(text) {
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
@@ -488,8 +420,8 @@ const props = defineProps({
}); });
const accesstoken = props.token; const accesstoken = props.token;
function getReadableDistanceForUI() { function getTotalReadableDistance() {
return state.scans.reduce((accumulator, currentValue) => accumulator + currentValue.distance, 0) return getReadableDistance(state.scans.reduce((accumulator, currentValue) => accumulator + currentValue.distance, 0));
} }
function getReadableDistance(distance) { function getReadableDistance(distance) {
@@ -521,6 +453,7 @@ runnerSelfServiceControllerGet({ path: { jwt: accesstoken } }).then(({ data }) =
}); });
runnerSelfServiceControllerGetScans({ path: { jwt: accesstoken } }).then(({ data }) => { runnerSelfServiceControllerGetScans({ path: { jwt: accesstoken } }).then(({ data }) => {
let counter = 0 let counter = 0
data = data.filter((s) => s.valid === true);
data.map(function (s) { data.map(function (s) {
if (counter === 0) { if (counter === 0) {
s.lapTime_readable = t('first_lap') s.lapTime_readable = t('first_lap')
@@ -535,25 +468,11 @@ runnerSelfServiceControllerGetScans({ path: { jwt: accesstoken } }).then(({ data
counter++; counter++;
return s; return s;
}); });
data.filter((s) => s.valid === true);
state.scans = data; state.scans = data;
}) })
.catch((error) => { .catch((error) => {
toast.error(t('profil_konnte_nicht_geladen_werden')); toast.error(t('profil_konnte_nicht_geladen_werden'));
}); });
function addSponsoring() {
const postdata = {
"receiptNeeded": false,
"firstname": newsponsor_vorname.value,
"middlename": "",
"lastname": newsponsor_nachname.value,
"phone": newsponsor_tel.value,
"email": newsponsor_mail.value,
"address": {}
}
console.log(postdata);
// TODO: implement: donationControllerPostDistance({body:{}})
}
function delete_me() { function delete_me() {
toast.clear(); toast.clear();
toast(t('profil_wird_geloescht')); toast(t('profil_wird_geloescht'));
@@ -587,6 +506,7 @@ function get_certificate() {
last_name: state.lastname, last_name: state.lastname,
id: state.fullobject.id, id: state.fullobject.id,
distance: state.fullobject.distance, distance: state.fullobject.distance,
self_service_link: window.location.href,
group: { group: {
name: state.group, name: state.group,
id: state.fullobject.group.id || 0, id: state.fullobject.group.id || 0,

View File

@@ -4,7 +4,7 @@
<img class="mx-auto h-24 w-auto" src="/favicon-lfk.png" alt /> <img class="mx-auto h-24 w-auto" src="/favicon-lfk.png" alt />
<h1 class="sm:text-3xl text-2xl font-semibold title-font mb-4 text-center">Lauf für Kaya! - {{ <h1 class="sm:text-3xl text-2xl font-semibold title-font mb-4 text-center">Lauf für Kaya! - {{
$t('profile') $t('profile')
}}</h1> }}</h1>
<p class="mx-auto leading-relaxed text-base text-center"> <p class="mx-auto leading-relaxed text-base text-center">
{{ $t('access_is_only_provided_via_your_email_link') }} {{ $t('access_is_only_provided_via_your_email_link') }}
</p> </p>
@@ -28,7 +28,7 @@
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" /> 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(user_email) && user_email !== ''" class="text-sm">{{ <p v-if="!isEmail(user_email) && user_email !== ''" class="text-sm">{{
$t('please_provide_valid_mail') $t('please_provide_valid_mail')
}}</p> }}</p>
</div> </div>
<div class="mt-2"> <div class="mt-2">
<button :disabled="(!state.submit_enabled)" <button :disabled="(!state.submit_enabled)"
@@ -55,7 +55,7 @@
</div> </div>
</div> </div>
</div> </div>
<Footer></Footer> <Footer />
</template> </template>
<script setup> <script setup>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="min-h-screen flex items-center justify-center" v-if="registrationState === 'registered'"> <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-6 px-6">
<img class="mx-auto h-24 w-auto" src="/favicon-lfk.png" alt /> <img class="mx-auto h-24 w-auto" src="/favicon-lfk.png" alt />
<h1 class="sm:text-3xl text-2xl font-semibold title-font mb-4 text-center"> <h1 class="sm:text-3xl text-2xl font-semibold title-font mb-4 text-center">
Lauf für Kaya! - {{ $t('registriert') }} Lauf für Kaya! - {{ $t('registriert') }}
@@ -12,26 +12,26 @@
</div> </div>
</div> </div>
<div class="min-h-screen flex items-center justify-center" v-else> <div class="min-h-screen flex items-center justify-center" v-else>
<div class="max-w-md w-full py-12 px-6"> <div class="max-w-md w-full py-6 px-6">
<img class="mx-auto h-24 w-auto" src="/favicon-lfk.png" alt /> <img class="mx-auto h-24 w-auto" src="/favicon-lfk.png" alt />
<h1 class="sm:text-3xl text-2xl font-semibold title-font mb-4 text-center"> <h1 class="sm:text-3xl text-2xl font-semibold title-font text-center">
Lauf für Kaya! - {{ $t("registrieren") }} Lauf für Kaya!
</h1> </h1>
<p class="mx-auto leading-relaxed text-base text-center font-medium"> <p class="mx-auto leading-relaxed text-lg text-center font-medium mb-4">
{{ $t("register.register_now") }} {{ $t("register.register_now") }}
</p> </p>
<p v-if="state.org_name !== ''" class="mx-auto leading-relaxed text-base text-center font-medium"> <div v-if="state.org_name !== ''" class="w-full text-center">
{{ $t("organization") }}: {{ state.org_name }} <span
</p> class="inline-flex items-center gap-x-1.5 py-1.5 px-3 rounded-lg mx-auto font-medium bg-blue-100 text-blue-800 dark:bg-blue-800/30 dark:text-blue-500">{{ state.org_name }}</span>
<p v-if="state.org_name !== '' && state.org_teams.length > 0" </div>
class="mx-auto leading-relaxed text-base text-center"> <label v-if="state.org_name !== '' && state.org_teams.length > 0" for="select_team" class="block font-semibold mt-2">
Team: Team:
</p> </label>
<select v-model="org_team" v-if="state.org_name !== '' && state.org_teams.length > 0" class=" <select id="select_team" v-model="org_team" v-if="state.org_name !== '' && state.org_teams.length > 0" class="
w-full w-full
border border-2
bg-white bg-white
rounded rounded-md
px-3 px-3
py-2 py-2
outline-none outline-none
@@ -47,102 +47,123 @@
{{ t.name }} {{ t.name }}
</option> </option>
</select> </select>
<p v-if="state.org_name === ''" class="mx-auto leading-relaxed text-base text-center"> <div v-if="state.org_name === ''" class="w-full text-center">
{{ $t('buergerlauf') }} <span
</p> class="inline-flex items-center gap-x-1.5 py-1.5 px-3 rounded-lg mx-auto font-medium bg-blue-100 text-blue-800 dark:bg-blue-800/30 dark:text-blue-500">{{
$t('buergerlauf') }}</span>
</div>
<div class="mt-4"> <div class="mt-4">
<label for="first_name" class="block font-medium"> <label for="first_name" class="block font-semibold mt-2">
{{ $t("vorname") }} {{ $t("vorname") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
<input v-model="userdetails.firstname" name="firstname" id="first_name" autocomplete="off" <input v-model="userdetails.firstname" name="firstname" id="first_name" autocomplete="off"
:placeholder="[[$t('vorname')]]" type="text" :class="{ :placeholder="[[$t('ihr_vorname')]]" type="text" :class="{
'border-red-500': !userdetails.firstname.trim(), '': !userdetails.firstname.trim(),
'border-green-300': userdetails.firstname.trim(), 'border-green-300': userdetails.firstname.trim(),
}" class=" }" class="
dark:bg-gray-800 dark:bg-gray-800
mt-1
block block
w-full w-full
shadow-sm shadow-sm
sm:text-sm sm:text-sm
border-gray-300 border-2 border-2 placeholder:text-gray-800
bg-gray-50 bg-gray-50
text-gray-500 text-gray-500
rounded-md rounded-md
p-2 p-2
" /> " />
<!-- --> <!-- -->
<label for="last_name" class="block font-medium"> <label for="last_name" class="block font-semibold mt-2">
{{ $t("nachname") }} {{ $t("nachname") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
<input v-model="userdetails.lastname" name="lastname" id="last_name" autocomplete="off" <input v-model="userdetails.lastname" name="lastname" id="last_name" autocomplete="off"
:placeholder="[[$t('nachname')]]" type="text" :class="{ :placeholder="[[$t('ihr_nachname')]]" type="text" :class="{
'border-red-500': !userdetails.lastname.trim(), '': !userdetails.lastname.trim(),
'border-green-300': userdetails.lastname.trim(), 'border-green-300': userdetails.lastname.trim(),
}" class=" }" class="
dark:bg-gray-800 dark:bg-gray-800
mt-1
block block
w-full w-full
shadow-sm shadow-sm
sm:text-sm sm:text-sm
border-gray-300 border-2 border-2 placeholder:text-gray-800
bg-gray-50 bg-gray-50
text-gray-500 text-gray-500
rounded-md rounded-md
p-2 p-2
" /> " />
<!-- --> <!-- -->
<label for="email_address" class="block font-medium"> <label for="email_address" class="block font-semibold mt-2">
{{ $t("e_mail_adress") }} {{ $t("e_mail_adress") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
<input v-model="userdetails.mail" name="email_address" id="email_address" autocomplete="off" <input v-model="userdetails.mail" name="email_address" id="email_address" autocomplete="off"
:placeholder="[[$t('e_mail_adress')]]" type="email" :class="{ :placeholder="[[$t('ihre_e_mail_adresse')]]" type="email" :class="{
'border-red-500': !isEmail(userdetails.mail), '': !isEmail(userdetails.mail),
'border-green-300': isEmail(userdetails.mail), 'border-green-300': isEmail(userdetails.mail),
}" class=" }" class="
dark:bg-gray-800 dark:bg-gray-800
mt-1
block block
w-full w-full
shadow-sm shadow-sm
sm:text-sm sm:text-sm
border-2 border-2 placeholder:text-gray-800
bg-gray-50 bg-gray-50
text-gray-500 text-gray-500
rounded-md rounded-md
p-2 p-2
" /> " />
<p v-if="!isEmail(userdetails.mail)" class="text-sm"> <p v-if="userdetails.mail !== '' && !isEmail(userdetails.mail)" class="text-sm">
{{ $t("please_provide_valid_mail") }} {{ $t("please_provide_valid_mail") }}
</p> </p>
<!-- --> <!-- -->
<label for="phone" class="select-none block font-medium">{{ <label for="phone" class="block font-semibold mt-2">{{
$t("phone_number") $t("phone_number")
}}</label> }}</label>
<div v-if="userdetails.phone !== '' && !userdetails.phone.includes('+')"
class="bg-blue-100 border border-blue-200 text-black rounded-lg p-4 mb-1" role="alert" tabindex="-1"
aria-labelledby="hs-actions-label">
<div class="flex">
<div class="shrink-0">
<svg class="shrink-0 size-4 mt-1" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 16v-4"></path>
<path d="M12 8h.01"></path>
</svg>
</div>
<div class="ms-3">
<h3 id="hs-actions-label" class="font-semibold">
{{ $t('hinweis') }}
</h3>
<div class="mt-2 text-sm text-gray-800 font-medium">
{{ $t('registration_local_phone_nr') }}
</div>
</div>
</div>
</div>
<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('geben_sie_ihre_handynummer_an')]]" type="text" :class="{
'border-red-500': '':
!isPhoneOkay(userdetails.phone), userdetails.phone === '',
'border-green-300': 'border-red-300':
isPhoneOkay(userdetails.phone), !isPhoneOkay(),
}" class=" }" class="
dark:bg-gray-800 dark:bg-gray-800
mt-1
block block
w-full w-full
shadow-sm shadow-sm
sm:text-sm sm:text-sm
border-2 border-2 placeholder:text-gray-800
bg-gray-50 bg-gray-50
text-gray-500 text-gray-500
rounded-md rounded-md
p-2 p-2
" /> " />
<p v-if="!isPhoneOkay(userdetails.phone)" class="text-sm"> <p v-if="!isPhoneOkay()" class="text-sm">
{{ $t("this_is_not_a_valid_international_phone_number") }} {{ $t("this_is_not_a_valid_international_phone_number") }}
</p> </p>
<!-- --> <!-- -->
@@ -160,7 +181,7 @@
</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-semibold mt-2">
{{ $t("strasse") }} {{ $t("strasse") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
@@ -170,12 +191,11 @@
'border-green-300': userdetails.address.street.trim(), 'border-green-300': userdetails.address.street.trim(),
}" class=" }" class="
dark:bg-gray-800 dark:bg-gray-800
mt-1
block block
w-full w-full
shadow-sm shadow-sm
sm:text-sm sm:text-sm
border-gray-300 border-2 border-2 placeholder:text-gray-800
bg-gray-50 bg-gray-50
text-gray-500 text-gray-500
rounded-md rounded-md
@@ -183,18 +203,17 @@
" /> " />
</div> </div>
<div class="col-span-6"> <div class="col-span-6">
<label for="address2" class="block font-medium">{{ <label for="address2" class="block font-semibold mt-2">{{
$t("apartment_suite_etc") $t("apartment_suite_etc")
}}</label> }}</label>
<input v-model="userdetails.address.address2" type="text" name="address2" <input v-model="userdetails.address.address2" type="text" name="address2"
:placeholder="[[$t('apartment_suite_etc')]]" id="address2" autocomplete="street-address" class=" :placeholder="[[$t('apartment_suite_etc')]]" id="address2" autocomplete="street-address" class="
dark:bg-gray-800 dark:bg-gray-800
mt-1
block block
w-full w-full
shadow-sm shadow-sm
sm:text-sm sm:text-sm
border-gray-300 border-2 border-2 placeholder:text-gray-800
bg-gray-50 bg-gray-50
text-gray-500 text-gray-500
rounded-md rounded-md
@@ -202,7 +221,7 @@
" /> " />
</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-semibold mt-2">
{{ $t("ort") }} {{ $t("ort") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
@@ -212,12 +231,11 @@
'border-green-300': userdetails.address.city.trim(), 'border-green-300': userdetails.address.city.trim(),
}" class=" }" class="
dark:bg-gray-800 dark:bg-gray-800
mt-1
block block
w-full w-full
shadow-sm shadow-sm
sm:text-sm sm:text-sm
border-gray-300 border-2 border-2 placeholder:text-gray-800
bg-gray-50 bg-gray-50
text-gray-500 text-gray-500
rounded-md rounded-md
@@ -225,7 +243,7 @@
" /> " />
</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-semibold mt-2">
{{ $t("plz") }} {{ $t("plz") }}
<span class="font-bold">*</span> <span class="font-bold">*</span>
</label> </label>
@@ -241,12 +259,11 @@
), ),
}" class=" }" class="
dark:bg-gray-800 dark:bg-gray-800
mt-1
block block
w-full w-full
shadow-sm shadow-sm
sm:text-sm sm:text-sm
border-gray-300 border-2 border-2 placeholder:text-gray-800
bg-gray-50 bg-gray-50
text-gray-500 text-gray-500
rounded-md rounded-md
@@ -296,7 +313,7 @@
text-center text-center
py-2 py-2
px-3 px-3
border-2 border-gray-300 border-2 placeholder:text-gray-800 border-gray-300
rounded-md rounded-md
p-1 p-1
bg-blue-800 bg-blue-800
@@ -313,7 +330,9 @@
</div> </div>
</div> </div>
</div> </div>
<Footer></Footer> <div class="p-8">
<Footer />
</div>
</template> </template>
<script setup> <script setup>
@@ -348,17 +367,30 @@ let userdetails = ref({
phone: "", phone: "",
address: { street: "", address2: "", city: "", zipcode: "" }, address: { street: "", address2: "", city: "", zipcode: "" },
}); });
function formatPhoneNumber(phoneNumber, countryCode = "+49") {
// Remove all non-digit characters
const cleanedNumber = phoneNumber.replace(/\D/g, "");
// Check if the number starts with the country code
if (cleanedNumber.startsWith(countryCode.replace("+", ""))) {
return "+" + cleanedNumber; // already international
}
// Check if the number starts with 0
if (cleanedNumber.startsWith("0")) {
return countryCode + cleanedNumber.slice(1);
}
// If it doesn't start with 0 or the country code, assume it's a local number.
// In this case, prepend the country code.
return countryCode + cleanedNumber;
}
function isPhoneOkay() { function isPhoneOkay() {
if (userdetails.value.phone === "") { if (userdetails.value.phone === "") {
return true return true
} }
if (userdetails.value.phone.includes(" ")) { const formattedNumber = formatPhoneNumber(userdetails.value.phone)
return false if (isMobilePhone(formattedNumber)) {
}
if (!userdetails.value.phone.includes("+")) {
return false
}
if (isMobilePhone(userdetails.value.phone)) {
return true return true
} }
return false return false
@@ -400,7 +432,7 @@ function login() {
address: {}, address: {},
}; };
if (userdetails.value.phone !== "") { if (userdetails.value.phone !== "") {
postdata.phone = userdetails.value.phone postdata.phone = formatPhoneNumber(userdetails.value.phone)
} }
if (provide_address.value === true) { if (provide_address.value === true) {
postdata.address = { postdata.address = {