Compare commits

...

234 Commits

Author SHA1 Message Date
niggl 128c6abd73 chore(release): 1.4.1
Build release images / build-container (push) Successful in 49s
2025-04-25 15:41:19 +02:00
niggl 094e731947 fix(laptimes): Filter out invalid scans 2025-04-25 15:40:47 +02:00
niggl 8d6f290fd5 fix(certificate): Provide selfservice url on certificate 2025-04-25 15:38:31 +02:00
philipp 57600fad7f chore(release): 1.4.0
Build release images / build-container (push) Successful in 45s
2025-03-28 22:36:34 +01:00
philipp 421dedcb8d ci: update release commit message 2025-03-28 22:36:21 +01:00
philipp 00c5181855 chore(deps): bump 2025-03-28 22:35:53 +01:00
philipp 6f5c5b4833 chore(deps): bump 2025-03-28 22:31:43 +01:00
philipp 347cfe0304 ci: only tagged for now 2025-03-28 22:30:26 +01:00
philipp 6afe3207fa feat(register): org/team as badge ui
Build Latest image / build-container (push) Successful in 47s
2025-03-28 22:30:06 +01:00
philipp 4ccac8a0b8 feat: improved registration ui 2025-03-28 22:21:44 +01:00
philipp 3a9cd95830 🚀Bumped version to v1.3.1
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
philipp 65dc27add1 feat: footer cleanup
Build Latest image / build-container (push) Has been cancelled
2025-03-28 18:59:53 +01:00
philipp c9e3b613e1 🚀Bumped version to v1.3.0
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
philipp f0c668c1c3 feat: only show international phone number thing if + is missing
Build Latest image / build-container (push) Successful in 45s
2025-03-28 18:29:29 +01:00
philipp e418d2a2b7 feat: improved Register UI
Build Latest image / build-container (push) Successful in 45s
2025-03-28 17:47:12 +01:00
philipp e14a6d6329 feat: improve phone number registration 2025-03-28 17:38:13 +01:00
philipp e1a87eda4a 🚀Bumped version to v1.2.7
Build Latest image / build-container (push) Successful in 1m3s
Build release images / build-container (push) Successful in 1m6s
2025-03-23 19:55:05 +01:00
philipp 0e557ef408 footer: cleanup imprint & privacy url
Build Latest image / build-container (push) Has been cancelled
2025-03-23 19:54:47 +01:00
philipp 0af73525bc footer padding
Build Latest image / build-container (push) Successful in 52s
2025-03-23 19:53:48 +01:00
philipp 422df7c3f8 fix: footer
Build Latest image / build-container (push) Has been cancelled
2025-03-23 19:53:35 +01:00
niggl bab145d78c chore: clean up .dockerignore by removing Gatsby references
Build Latest image / build-container (push) Successful in 44s
2025-03-22 23:03:20 +01:00
niggl a862593c53 refactor(ci): Switch to actions 2025-03-22 23:02:14 +01:00
philipp 63fc5ec747 🚀Bumped version to v1.2.6 2025-03-18 22:59:20 +01:00
philipp c98a65d918 fix(profile): font sizes 2025-03-18 22:59:01 +01:00
philipp b1ab04fa53 🚀Bumped version to v1.2.5 2025-03-18 21:32:48 +01:00
philipp 9af9c897f1 feat: improved icons 2025-03-18 21:32:32 +01:00
philipp 51b66eb85b feat: improved tabs 2025-03-18 21:29:13 +01:00
philipp b3197dd3f9 feat: cleanup 2025-03-18 21:15:52 +01:00
philipp 50fbfe05f1 refactor: simplify imprint + privacy 2025-03-18 21:12:23 +01:00
philipp 0ff6df68d6 feat: cleanup 2025-03-18 21:06:39 +01:00
philipp 03532cc365 feat: profile cleanup 2025-03-18 21:05:13 +01:00
philipp d50719c0da feat: profile cleanup 2025-03-18 20:58:42 +01:00
philipp 865058c8bb refactor: move to new lfk ts client 2025-03-18 00:05:04 +01:00
philipp d503061604 register: drop middlename 2025-03-18 00:01:05 +01:00
philipp d5eefbb5e2 fix(register): phone number verification 2025-03-18 00:00:51 +01:00
philipp f1d552ce64 🚀Bumped version to v1.2.4 2025-03-17 22:35:58 +01:00
philipp 2939911c99 feat: loading screen 2025-03-17 22:35:12 +01:00
philipp e7b9c6e203 🚀Bumped version to v1.2.3 2025-03-17 22:22:39 +01:00
philipp 3641d2a783 no selfservice sponsor add for now 2025-03-17 22:21:17 +01:00
philipp ccea9d6197 shareSponsorLink function 2025-03-17 22:20:54 +01:00
philipp c94f9e550e i18n 2025-03-17 22:15:00 +01:00
philipp 0848209d49 feat: disable darkmode for now, also is better for visibility on day of run... 2025-03-17 22:06:51 +01:00
philipp 1202f2ebca feat: profile cleanup 2025-03-17 22:06:32 +01:00
philipp 4714b81465 wip 2025-03-17 22:00:31 +01:00
philipp 7f2e6b9160 cleanup 2025-03-17 21:54:06 +01:00
philipp 0366f95951 feat: cleanup profile 2025-03-17 21:52:44 +01:00
philipp 382757aa66 feat: wip: sponsoring add 2025-03-17 21:43:47 +01:00
philipp 34e63cf690 feat: improve profile 2025-03-17 21:32:02 +01:00
philipp 846d10f0b9 feat: improve profile 2025-03-17 21:29:13 +01:00
philipp 86ec22aa43 feat: cleanup profile 2025-03-17 21:16:57 +01:00
philipp f6f46f41bf feat(footer): 2024 2025-03-17 20:32:32 +01:00
philipp 64bb2d157d chore(deps): bump 2025-03-17 20:32:23 +01:00
philipp c8ceae5cf0 🚀Bumped version to v1.2.2
ci/woodpecker/push/build Pipeline failed
ci/woodpecker/tag/release Pipeline was successful
2024-12-16 17:10:39 +01:00
philipp 1d7cd601ee feat(profile): add cursor pointer
ci/woodpecker/push/build Pipeline failed
2024-12-16 17:10:27 +01:00
philipp 9ddb188ef6 🚀Bumped version to v1.2.1
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/tag/release Pipeline was successful
2024-12-16 17:03:30 +01:00
philipp 4996b8c526 Merge branch 'dev' of https://git.odit.services/lfk/selfservice into dev 2024-12-16 17:03:06 +01:00
niggl 7d2a29c0d8 🚀Bumped version to v1.2.0
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/tag/release Pipeline was successful
2024-12-16 16:56:10 +01:00
niggl 721892c315 refacor(documents): Switch to new document-server 2024-12-16 16:55:26 +01:00
philipp d5641312ca feat(profile): updated tab alignment 2024-12-16 16:55:16 +01:00
philipp c34a8a7fcc refactor(profile): replace styles with tailwindcss 2024-12-16 16:55:01 +01:00
philipp 55abb9ed22 feat(profile): show total distance 2024-12-16 16:54:06 +01:00
philipp 1d55445c1b 🚀Bumped version to v1.1.2
ci/woodpecker/push/build Pipeline failed
ci/woodpecker/tag/release Pipeline was successful
2024-12-11 23:08:38 +01:00
philipp 762454a086 fix(profile): migrate to code128 2024-12-11 23:08:27 +01:00
philipp 25c2a170bc chore(deps): bump all 2024-12-11 22:45:30 +01:00
philipp b21ad636ad refactor: drop postbuild step 2024-12-11 22:45:20 +01:00
philipp 4771bf1359 🚀Bumped version to v1.1.1
ci/woodpecker/tag/release Pipeline was successful
ci/woodpecker/push/build Pipeline was successful
2024-12-11 22:43:36 +01:00
philipp dbe707b062 fix(profile): passed id is a jwt 2024-12-11 22:43:02 +01:00
philipp dee1b7a6ea 🚀Bumped version to v1.1.0
ci/woodpecker/tag/release Pipeline was successful
ci/woodpecker/push/build Pipeline was successful
2024-12-02 16:50:31 +01:00
philipp 4bcbc67436 refactor: drop sub-directory routing 2024-12-02 16:48:15 +01:00
niggl 595735ad00 🚀Bumped version to v1.0.1
ci/woodpecker/tag/release Pipeline was successful
ci/woodpecker/push/build Pipeline was successful
2024-12-02 15:53:04 +01:00
niggl 7fcb6a9fc3 fix(container): Add dockeringore 2024-12-02 15:51:25 +01:00
philipp 2285ea5070 🚀Bumped version to v1.0.0
ci/woodpecker/push/build Pipeline was successful
2024-12-02 15:32:47 +01:00
philipp 4af5c4545b refactor
ci/woodpecker/push/build Pipeline was successful
2024-12-02 13:16:45 +01:00
philipp f296cbc1a0 i18n 2024-12-02 13:08:55 +01:00
philipp 4fcc38c374 updated profile page 2024-12-02 13:08:08 +01:00
philipp 90c085db28 footer update 2024-12-02 13:07:57 +01:00
philipp 1a3ab98412 improved style in registered view 2024-12-02 12:58:09 +01:00
philipp 048edfba89 i18n 2024-12-02 12:56:43 +01:00
philipp 0acda07eb5 add i18n ally snake case config 2024-12-02 12:42:00 +01:00
philipp afffde8fa0 registration brand font + more translations 2024-12-02 12:34:42 +01:00
philipp 1eab535381 wip: general updates 2024-12-02 11:54:05 +01:00
philipp 196b386d6d refactor: translations 2024-12-02 11:31:24 +01:00
philipp 548148e898 fix: translations 2024-12-02 11:29:05 +01:00
philipp 6376dcb5fe feat(Footer): ref lfk 2024-12-02 11:25:11 +01:00
philipp 75b61d991b feat(Home): improve ui 2024-12-02 11:24:04 +01:00
philipp af9a168f58 feat: lfk font 2024-12-02 11:12:00 +01:00
philipp f71b01c39a chore(deps): node@23.3.0 2024-12-02 11:06:26 +01:00
philipp 3e289d83f9 feat(Home): improve background.jpg import
ci/woodpecker/push/build Pipeline was successful
2024-12-02 11:00:07 +01:00
philipp ec6d252928 refactor: code cleanup 2024-12-02 10:55:06 +01:00
philipp 4a11fef0e0 chore(deps): update all
ci/woodpecker/push/build Pipeline was successful
2024-12-02 10:40:06 +01:00
philipp b85c3958c2 chore: pnpm v9
ci/woodpecker/push/build Pipeline is running
2024-12-02 10:16:59 +01:00
niggl 780bc54604 refactor(ci): Make ready for new woodpecker
ci/woodpecker/push/build Pipeline was successful
2024-11-26 19:23:40 +01:00
philipp cb2f8eeab1 chore: 2025 2024-11-21 10:49:46 +01:00
niggl c36db2c18f Pin pnpm
ci/woodpecker/push/build Pipeline was successful
2023-11-06 20:27:30 +01:00
niggl decc80fcc1 Merge branch 'dev' of git.odit.services:lfk/selfservice into dev
ci/woodpecker/push/build Pipeline failed
2023-11-06 20:25:28 +01:00
niggl 9a3d307dfa feat(ci)!: Switch to woodpecker 2023-11-06 20:25:26 +01:00
philipp 240f44df60 🚀Bumped version to v0.11.3
continuous-integration/drone/push Build is passing
2023-04-07 15:17:49 +02:00
philipp 677e65f44a chore(deps): pnpm@8.1.1 2023-04-07 15:17:27 +02:00
philipp 772eca64bb fix(Footer): darkmode colors in lightmode
continuous-integration/drone/push Build is failing
2023-04-07 15:15:26 +02:00
philipp 25d25401df fix: registration code white bg
close #50
2023-04-07 15:13:44 +02:00
niggl cac5103d52 switched drone to kaniko with cache
continuous-integration/drone/push Build is passing
2023-03-29 20:20:06 +02:00
niggl 6aca13f0cb Pinned pnpm and lockfile 2023-03-29 20:17:33 +02:00
niggl 78fea1ea04 Switched dockerfile to pnpm with cache 2023-03-29 20:17:18 +02:00
niggl fa51b31fe4 🚀Bumped version to v0.11.2
continuous-integration/drone/push Build is passing
2023-03-15 19:27:59 +01:00
niggl b9624aa5ad Added footer to every page 2023-03-15 19:27:40 +01:00
niggl 09e48e771f Accept tos to accept privacy_policy 2023-03-15 19:22:35 +01:00
philipp 8364321a7c 🚀Bumped version to v0.11.1
continuous-integration/drone/push Build is passing
2023-02-18 17:27:22 +01:00
philipp 659fa77dca Profile: add "---" if no data set
continuous-integration/drone/push Build is passing
2023-02-18 17:26:54 +01:00
philipp 10c9127256 🚀Bumped version to v0.11.0
continuous-integration/drone/push Build is passing
2023-02-03 17:24:42 +01:00
philipp a3a1e89aa1 pnpm migration
continuous-integration/drone/push Build is passing
2023-02-03 17:24:25 +01:00
philipp 5587175534 🚀Bumped version to v0.10.0
continuous-integration/drone/push Build is passing
2023-02-03 17:19:08 +01:00
philipp 8e2b355466 updated nginx config for cache busting
continuous-integration/drone/push Build is passing
2023-02-03 17:18:57 +01:00
philipp eccce0795b text cleanups + footer
continuous-integration/drone/push Build is passing
2023-02-03 17:14:01 +01:00
philipp 54540be6e1 improved profile page padding + full width registration code for easier scanning
continuous-integration/drone/push Build is passing
2023-02-03 17:04:25 +01:00
philipp 3392a2e68e 🚀Bumped version to v0.9.0
continuous-integration/drone/push Build is passing
2023-02-03 16:52:50 +01:00
philipp 8928f841dc wip: registration confirmation ui
continuous-integration/drone/push Build is passing
2023-02-03 16:52:38 +01:00
philipp 9ac14e8a5d wip: error registration ui feedback
continuous-integration/drone/push Build is passing
2023-02-03 16:48:14 +01:00
philipp 4a5b9d2569 🚀Bumped version to v0.8.3
continuous-integration/drone/push Build is passing
2023-02-03 16:44:43 +01:00
philipp 123509d0a6 fix: registration code (broke in merge)
continuous-integration/drone/push Build is passing
2023-02-03 16:44:10 +01:00
philipp 51f8d0fb42 wip: fix registration code
continuous-integration/drone/push Build is passing
2023-02-03 16:41:42 +01:00
philipp f4d1c7b053 🚀Bumped version to v0.8.2
continuous-integration/drone/push Build is passing
2023-02-03 13:51:54 +01:00
philipp ab9b400fff /profile/ dont instantly show mail format error
continuous-integration/drone/push Build is passing
2023-02-03 13:51:23 +01:00
philipp ac75828309 /profile/ move from anchor tag to button
continuous-integration/drone/push Build is passing
2023-02-03 13:51:09 +01:00
philipp c7f3a893af /profile/ toast styles
continuous-integration/drone/push Build is passing
2023-02-03 13:50:54 +01:00
philipp 30fd7ead08 /profile/ autocomplete mail
continuous-integration/drone/push Build is passing
2023-02-03 13:50:40 +01:00
philipp 64e6ef8cec /profile/ text cleanups
continuous-integration/drone/push Build is passing
2023-02-03 13:50:27 +01:00
philipp c35f943957 move /registered/ to props
continuous-integration/drone/push Build is passing
2023-02-03 13:46:18 +01:00
niggl 292e44057a 🚀Bumped version to v0.8.1
continuous-integration/drone/push Build is passing
2023-02-02 15:54:17 +01:00
niggl 20fca6794d Adjusted button text 2023-02-02 15:53:58 +01:00
niggl 8139d63715 Switched request login link api path to login (backend v13.0.0) 2023-02-02 15:52:33 +01:00
philipp 7051909bf9 🚀Bumped version to v0.8.0
continuous-integration/drone/push Build is passing
2023-02-02 00:16:29 +01:00
philipp f7a0682c33 Merge pull request 'dont autologin on register -> require mail link' (#47) from feature/46-dont-autologin-on-register-require-mail-link into dev
continuous-integration/drone/push Build is passing
Reviewed-on: #47
2023-02-01 23:16:11 +00:00
philipp c63adf557b 🚀Bumped version to v0.7.11
continuous-integration/drone/push Build is passing
2023-02-02 00:15:58 +01:00
philipp 077b33f031 Profile: improved mobile responsiveness/ design + toast clear
continuous-integration/drone/push Build is passing
2023-02-02 00:15:12 +01:00
philipp 52a6b3dc77 fix: registration code download button style
continuous-integration/drone/push Build is passing
2023-02-02 00:10:48 +01:00
philipp eb20b547e7 add /registered/?mail route
ref #46
2023-02-02 00:08:14 +01:00
niggl 8b5e1cac13 🚀Bumped version to v0.7.10
continuous-integration/drone/push Build is passing
2023-02-01 17:50:46 +01:00
niggl 20c6a420e9 Merge branch 'dev' of git.odit.services:lfk/selfservice into dev
continuous-integration/drone/push Build is passing
2023-02-01 17:48:52 +01:00
niggl 53800b4fa3 Added download for registration code 2023-02-01 17:42:58 +01:00
philipp debbd9219c 🚀Bumped version to v0.7.9
continuous-integration/drone/push Build is passing
2023-02-01 17:40:23 +01:00
philipp 9b261bf200 fix codeconfig.height
continuous-integration/drone/push Build is passing
2023-02-01 17:40:09 +01:00
philipp 713dd15312 drop jsbarcode
continuous-integration/drone/push Build is passing
2023-02-01 17:39:59 +01:00
niggl 64382880c4 Pinned version 2023-02-01 17:39:15 +01:00
niggl 9e06c46411 Configureable barcode format via bwp-js 2023-02-01 17:39:03 +01:00
philipp 8cfddb5029 migrate to bwip-js
continuous-integration/drone/push Build is passing
2023-02-01 17:36:22 +01:00
philipp e5a01bcd76 🚀Bumped version to v0.7.8
continuous-integration/drone/push Build is passing
2023-02-01 14:50:04 +01:00
philipp 851190e6a7 add barcode to profile
continuous-integration/drone/push Build is passing
2023-02-01 14:48:06 +01:00
philipp 1603a097f7 certificate generation: success toast styling
continuous-integration/drone/push Build is passing
2023-02-01 14:47:38 +01:00
philipp c2b615294e 🚀Bumped version to v0.7.7
continuous-integration/drone/push Build is passing
2023-01-31 13:47:39 +01:00
philipp c64762831f fix: registration w/o phone
continuous-integration/drone/push Build is passing
2023-01-31 13:47:32 +01:00
philipp 9b446abc1f 🚀Bumped version to v0.7.6
continuous-integration/drone/push Build is passing
2023-01-31 13:47:19 +01:00
philipp 5d974e562e update release script
continuous-integration/drone/push Build is passing
2023-01-31 13:45:45 +01:00
philipp a030f6b738 update texts of pdf generation status toasts
continuous-integration/drone/push Build is passing
close #44
2023-01-31 13:45:28 +01:00
philipp 1249248a9d 🚀Bumped version to v0.7.5
continuous-integration/drone/push Build is passing
2023-01-30 18:19:53 +01:00
philipp 0bd6d543bf update nginx base
continuous-integration/drone/push Build is passing
2023-01-30 18:18:26 +01:00
philipp 92d7bfd594 updated base node image
continuous-integration/drone/push Build is failing
2023-01-30 18:16:25 +01:00
philipp 917cb6be34 fix: relativ links
continuous-integration/drone/push Build is failing
2023-01-30 18:13:50 +01:00
philipp d159cb59be AGB link 2023-01-30 18:13:43 +01:00
philipp 9812d79d4d 2023
continuous-integration/drone/push Build is failing
2023-01-30 18:12:50 +01:00
niggl 4663214ede 🚀Bumped version to v0.7.4
continuous-integration/drone/push Build is passing
2021-04-21 15:58:49 +02:00
niggl 9c9ceaa666 Updated dronefile
continuous-integration/drone/push Build is passing
2021-04-21 15:57:45 +02:00
niggl 602d80bd14 🚀Bumped version to v0.7.3
continuous-integration/drone/push Build is passing
2021-04-21 15:38:27 +02:00
niggl 45ee4ab812 Merge pull request 'Button fixes bugfix/42-button_links' (#43) from bugfix/42-button_links into dev
continuous-integration/drone/push Build is passing
Reviewed-on: #43
2021-04-21 13:38:10 +00:00
niggl 020c310865 Fixed register button link
ref #42
2021-04-21 12:33:16 +02:00
niggl 1102d29c0e Removed useless register now button
ref #42
2021-04-21 12:31:46 +02:00
niggl 1a3af200dd 🚀Bumped version to v0.7.2
continuous-integration/drone/push Build is passing
2021-04-14 12:19:43 +02:00
niggl 71f419ffb4 Merge branch 'dev' of git.odit.services:lfk/selfservice into dev
continuous-integration/drone/push Build is passing
2021-04-14 12:18:09 +02:00
niggl b74bea0340 Document generation hotfix 🐞 2021-04-14 12:18:02 +02:00
philipp b0172c500b 🚀Bumped version to v0.7.1
continuous-integration/drone/push Build is passing
2021-04-13 18:08:19 +02:00
philipp 75b4dac0fe Merge pull request 'bugfix/31-env-js-linking-ci' (#41) from bugfix/31-env-js-linking-ci into dev
continuous-integration/drone/push Build is passing
Reviewed-on: #41
close #31
2021-04-13 16:02:44 +00:00
philipp 51d058bf96 added 'yarn postbuild' script for fixing env.js in dist/index.html
ref #31
2021-04-13 17:58:43 +02:00
philipp ad13bae068 dependency bump 2021-04-13 17:57:41 +02:00
niggl 152e74190d 🚀Bumped version to v0.7.0
continuous-integration/drone/push Build is passing
2021-04-06 21:28:02 +02:00
niggl 4c83e2e738 Merge pull request 'Donation list feature/39-donation_list' (#40) from feature/39-donation_list into dev
continuous-integration/drone/push Build is passing
Reviewed-on: #40
2021-04-06 19:27:30 +00:00
niggl cb1b9d330b Sorted translations 🌍
ref #39
2021-04-06 21:25:36 +02:00
niggl 3b4c11e4c0 Merge branch 'feature/39-donation_list' of git.odit.services:lfk/selfservice into feature/39-donation_list 2021-04-06 21:25:12 +02:00
niggl 89820d4450 Added total to bottom of page
ref #39
2021-04-06 21:25:10 +02:00
philipp 121022c843 added distance formatting
ref #39
2021-04-06 21:23:24 +02:00
niggl d713fbef94 Added translations 🌍
ref #39
2021-04-06 17:27:18 +02:00
niggl 815a36f202 Now w/ formatted currency amount
ref #39
2021-04-06 17:20:41 +02:00
niggl baa6da3dd0 Fixed spaces in name
ref #39
2021-04-06 17:18:09 +02:00
niggl f141130db5 Added basic sponsoring table
ref #39
2021-04-06 17:14:22 +02:00
niggl 5a123b0cf8 Updated env description
continuous-integration/drone/push Build is passing
2021-04-06 17:03:05 +02:00
niggl f5ae2145df 🚀Bumped version to v0.6.1
continuous-integration/drone/push Build is passing
2021-04-06 17:01:20 +02:00
niggl 96c0e56986 Fixed imprint/privacy default links
continuous-integration/drone/push Build is passing
2021-04-06 17:00:55 +02:00
niggl bc1de2acdc 🚀Bumped version to v0.6.0
continuous-integration/drone/push Build is passing
2021-04-03 18:53:32 +02:00
niggl 5c558aa9ee Merge branch 'dev' of git.odit.services:lfk/selfservice into dev 2021-04-03 18:53:14 +02:00
niggl 145b49906b Revert "🚀Bumped version to v0.6.0"
This reverts commit 0a62e8f5d1.
2021-04-03 18:53:12 +02:00
niggl 0a62e8f5d1 🚀Bumped version to v0.6.0 2021-04-03 18:52:54 +02:00
niggl 53eeb6be3d Merge pull request 'Certificate download feature/19-runner_certficates' (#38) from feature/19-runner_certficates into dev
continuous-integration/drone/push Build is passing
Reviewed-on: #38
2021-04-03 16:51:22 +00:00
niggl a554a90e74 Merge branch 'dev' into feature/19-runner_certficates
# Conflicts:
#	index.html
2021-04-03 18:50:16 +02:00
niggl c3b2b93d90 Reverted relative linking fix
ref #19
2021-04-03 18:48:53 +02:00
niggl 1a3c9edeb3 🚀Bumped version to v0.5.1
continuous-integration/drone/push Build is passing
2021-04-03 18:38:44 +02:00
niggl 7064a5bd82 Merge branch 'dev' into feature/19-runner_certficates 2021-04-03 16:28:18 +00:00
niggl fd6bd88d42 Merge pull request 'Env linking bugfix bugfix/31-env_linking' (#37) from bugfix/31-env_linking into dev
continuous-integration/drone/push Build is passing
Reviewed-on: #37
2021-04-03 16:27:56 +00:00
niggl f0a7f35dec Renoved fixed data
ref #19
2021-04-03 18:11:57 +02:00
niggl b938cfc49e Fixed blob handling
ref #19
2021-04-03 18:11:22 +02:00
niggl f6334397dc first part of certificate generation with manual data
ref #19
2021-04-03 17:57:24 +02:00
niggl 544542ac1e Added building pipeline for current branch
continuous-integration/drone/push Build is passing
ref #31
2021-04-03 15:26:07 +02:00
niggl 67c0dae537 Now manually linking env and main
ref #31
2021-04-03 15:24:52 +02:00
philipp cd6a139daf Merge pull request 'feature/30-profile-forgot-link' (#35) from feature/30-profile-forgot-link into dev
continuous-integration/drone/push Build is failing
Reviewed-on: #35
close #30
2021-04-02 19:00:50 +00:00
niggl ec44a8b63e Merge branch 'dev' into feature/30-profile-forgot-link
# Conflicts:
#	src/locales/en.json
#	src/views/Home.vue
2021-04-01 19:58:37 +02:00
niggl 676f0e8339 🚀Bumped version to v0.5.0
continuous-integration/drone/push Build is passing
2021-04-01 19:57:02 +02:00
niggl 27fd8f9a91 Revert "🚀Bumped version to v0.5.0"
This reverts commit b8c1b8c43b.
2021-04-01 19:56:52 +02:00
niggl bc1c824d9f Merge branch 'dev' of git.odit.services:lfk/selfservice into dev 2021-04-01 19:56:30 +02:00
niggl b8c1b8c43b 🚀Bumped version to v0.5.0 2021-04-01 19:56:09 +02:00
niggl 713db5e1e8 Removed useless code
ref #30
2021-04-01 19:55:23 +02:00
niggl 0795ea318d Fixed post url and body
ref #30
2021-04-01 19:55:01 +02:00
niggl bd512e0651 Merge pull request 'Runner self deletion feature/21-user_deletion' (#36) from feature/21-user_deletion into dev
continuous-integration/drone/push Build is passing
Reviewed-on: #36
2021-04-01 17:50:41 +00:00
niggl cf0437c3a7 Sorted translations
ref #21
2021-04-01 19:42:51 +02:00
niggl 8a24505d64 Added translations
ref #21
2021-04-01 19:42:33 +02:00
niggl 175bb168ae Content i18n run 🌍
ref #21
2021-04-01 19:40:49 +02:00
niggl 9751c2e9fd Added error toast
ref #21
2021-04-01 19:37:21 +02:00
niggl 7440fc404e Updated toasts and removed useless code
ref #21
2021-04-01 19:36:40 +02:00
niggl ba3dedb164 Added translations 🌍
ref #21
2021-04-01 19:35:54 +02:00
niggl d710d4b68f Updated icons
ref #21
2021-04-01 19:35:42 +02:00
niggl 125fcdd8cf Merge branch 'feature/21-user_deletion' of git.odit.services:lfk/selfservice into feature/21-user_deletion 2021-04-01 19:31:29 +02:00
niggl 8773239244 Added confirmation for profile deletion
ref #21
2021-04-01 19:31:25 +02:00
niggl 85b0549a11 Added confirmation for profile deletion 2021-04-01 19:31:19 +02:00
niggl fc04e71311 Implemented basic deletion
ref #21
2021-04-01 19:27:12 +02:00
niggl 619078cce8 Added data deletion button
ref #21
2021-04-01 19:25:09 +02:00
philipp 30f3a51ef8 add forgot view + action
ref #30
2021-04-01 19:22:23 +02:00
philipp 60dea511b9 🐞 fix home routes
ref #30
2021-04-01 19:07:14 +02:00
philipp 863568d7d0 basic ProfileNone layout
ref #30
2021-04-01 19:07:04 +02:00
philipp 555823954a Merge branch 'main' into dev
continuous-integration/drone/push Build was killed
2021-04-01 16:45:25 +00:00
philipp efcb7f5674 🚀Bumped version to v0.4.5
continuous-integration/drone/push Build was killed
2021-04-01 18:40:10 +02:00
philipp e796f6dcaf Merge pull request 'feature/32-registration-language' (#33) from feature/32-registration-language into dev
continuous-integration/drone/push Build was killed
Reviewed-on: #33
close #32
2021-04-01 16:38:49 +00:00
philipp 52a082841d 🐞 fix /profile/ router on register
ref #32
2021-04-01 18:31:37 +02:00
philipp e3f7497af5 pass browser locale to api/runners/register/
ref #32
2021-04-01 18:31:18 +02:00
philipp 9b62962758 🚀Bumped version to v0.4.4
continuous-integration/drone/push Build was killed
2021-03-31 20:16:18 +02:00
philipp 84dc33bf14 🚑 hotfix - baseurl_selfservice -> baseurl 2021-03-31 20:14:58 +02:00
philipp cad34d357b 🚀Bumped version to v0.4.3
continuous-integration/drone/push Build was killed
2021-03-31 20:13:03 +02:00
philipp 2056ce1e62 🚑 hotfix - Profile api path 2021-03-31 20:11:40 +02:00
niggl 1c19657935 Merge pull request 'RELEASE 0.3.0' (#25) from dev into main
continuous-integration/drone/push Build is passing
Reviewed-on: #25
2021-03-30 16:20:04 +00:00
38 changed files with 6347 additions and 1253 deletions
+185
View File
@@ -0,0 +1,185 @@
# ---> Node
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
# ---> Windows
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# ---> macOS
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# ---> Vue
# gitignore template for Vue.js projects
#
# Recommended template: Node.gitignore
# TODO: where does this rule come from?
docs/_book
# TODO: where does this rule come from?
test/
/package-lock.json
/yarn.lock
/public/env.js
-109
View File
@@ -1,109 +0,0 @@
---
kind: secret
name: docker_username
get:
path: odit-registry-builder
name: username
---
kind: secret
name: docker_password
get:
path: odit-registry-builder
name: password
---
kind: secret
name: git_ssh
get:
path: odit-git-bot
name: sshkey
---
kind: pipeline
type: kubernetes
name: build:dev
steps:
# - name: run full license export
# depends_on: ["clone"]
# image: node:alpine
# commands:
# - yarn
# - yarn licenses:export
# - name: push new licenses file to repo
# depends_on: ["run full license export"]
# image: appleboy/drone-git-push
# settings:
# branch: dev
# commit: true
# commit_message: new license file version [CI SKIP]
# author_email: bot@odit.services
# remote: git@git.odit.services:lfk/selfservice.git
# ssh_key:
# from_secret: git_ssh
- name: build dev
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: registry.odit.services/lfk/selfservice
tags:
- dev
registry: registry.odit.services
mtu: 1000
trigger:
branch:
- dev
event:
- push
---
kind: pipeline
type: kubernetes
name: build:latest
steps:
- name: build latest
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: registry.odit.services/lfk/selfservice
tags:
- latest
registry: registry.odit.services
mtu: 1000
trigger:
branch:
- main
event:
- push
---
kind: pipeline
type: kubernetes
name: build:tags
steps:
- name: build $DRONE_TAG
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: registry.odit.services/lfk/selfservice
tags:
- '${DRONE_TAG}'
registry: registry.odit.services
mtu: 1000
trigger:
event:
- tag
+27
View File
@@ -0,0 +1,27 @@
name: Build release images
on:
push:
tags:
- "*.*.*"
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:${{ github.ref_name }}
platforms: linux/amd64,linux/arm64
+5 -1
View File
@@ -2,5 +2,9 @@
"i18n-ally.localesPaths": [ "i18n-ally.localesPaths": [
"src/locales" "src/locales"
], ],
"i18n-ally.keystyle": "nested" "i18n-ally.keystyle": "nested",
"i18n-ally.extract.keygenStyle": "snake_case",
"i18n-ally.enabledFrameworks": [
"vue"
]
} }
+452
View File
@@ -2,8 +2,460 @@
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.1](https://git.odit.services/lfk/selfservice/compare/1.4.0...1.4.1)
- 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)
> 23 March 2025
- 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)
- fix: footer [`422df7c`](https://git.odit.services/lfk/selfservice/commit/422df7c3f832dc29721e783dc4a86ee55e9d8ccc)
- footer padding [`0af7352`](https://git.odit.services/lfk/selfservice/commit/0af73525bc154ba730351d7a4970e9737edaa4db)
- chore: clean up .dockerignore by removing Gatsby references [`bab145d`](https://git.odit.services/lfk/selfservice/commit/bab145d78c16dd7c56136a274d051cf408935e3e)
#### [1.2.6](https://git.odit.services/lfk/selfservice/compare/1.2.5...1.2.6)
> 18 March 2025
- 🚀Bumped version to v1.2.6 [`63fc5ec`](https://git.odit.services/lfk/selfservice/commit/63fc5ec7474f65c743db9c281829fef31b623af6)
- fix(profile): font sizes [`c98a65d`](https://git.odit.services/lfk/selfservice/commit/c98a65d918e5d652ee98044b4d5333c7000e1c87)
#### [1.2.5](https://git.odit.services/lfk/selfservice/compare/1.2.4...1.2.5)
> 18 March 2025
- refactor: move to new lfk ts client [`865058c`](https://git.odit.services/lfk/selfservice/commit/865058c8bb7eec03278bf1f4a7b708429d0b5b20)
- feat: cleanup [`b3197dd`](https://git.odit.services/lfk/selfservice/commit/b3197dd3f95cd7d222f1ea168e9826f7ad7ef903)
- refactor: simplify imprint + privacy [`50fbfe0`](https://git.odit.services/lfk/selfservice/commit/50fbfe05f1ba830ea19f9e86b7a2fdce588f1a31)
- feat: improved tabs [`51b66eb`](https://git.odit.services/lfk/selfservice/commit/51b66eb85b3003996ac2414757ae62ee7ba80ce5)
- fix(register): phone number verification [`d5eefbb`](https://git.odit.services/lfk/selfservice/commit/d5eefbb5e22f4cc7b50e1f0c469779d3b7e310f5)
- feat: improved icons [`9af9c89`](https://git.odit.services/lfk/selfservice/commit/9af9c897f17b8a1be12f47dc271382629fc298ff)
- feat: profile cleanup [`d50719c`](https://git.odit.services/lfk/selfservice/commit/d50719c0dad4e3fbf008fb240edff80c4ea6ab4c)
- 🚀Bumped version to v1.2.5 [`b1ab04f`](https://git.odit.services/lfk/selfservice/commit/b1ab04fa53817178e016d7c2c387db12c0f6a987)
- register: drop middlename [`d503061`](https://git.odit.services/lfk/selfservice/commit/d5030616043fb9fa4eccc7894ee3ada92928d102)
- feat: profile cleanup [`03532cc`](https://git.odit.services/lfk/selfservice/commit/03532cc365e38d7313ff2e8571ae15975d8a53e5)
- feat: cleanup [`0ff6df6`](https://git.odit.services/lfk/selfservice/commit/0ff6df68d61404c7be7a1e9b88a354fb12ce0907)
#### [1.2.4](https://git.odit.services/lfk/selfservice/compare/1.2.3...1.2.4)
> 17 March 2025
- feat: loading screen [`2939911`](https://git.odit.services/lfk/selfservice/commit/2939911c993c3817d841d4cb4660aa940e478cc0)
- 🚀Bumped version to v1.2.4 [`f1d552c`](https://git.odit.services/lfk/selfservice/commit/f1d552ce64557b5da0dea91e114d3ebf2f8f0199)
#### [1.2.3](https://git.odit.services/lfk/selfservice/compare/1.2.2...1.2.3)
> 17 March 2025
- chore(deps): bump [`64bb2d1`](https://git.odit.services/lfk/selfservice/commit/64bb2d157daab257b6e0e7c4e6ed04f4b3772740)
- feat: cleanup profile [`86ec22a`](https://git.odit.services/lfk/selfservice/commit/86ec22aa435d9138ae3cde6387ce7ead14f3c964)
- feat: improve profile [`846d10f`](https://git.odit.services/lfk/selfservice/commit/846d10f0b95dad460a068bdaf3ca489d96c0b723)
- feat: profile cleanup [`1202f2e`](https://git.odit.services/lfk/selfservice/commit/1202f2ebca5fbc0baea145dda6f99668d8c47e92)
- feat: improve profile [`34e63cf`](https://git.odit.services/lfk/selfservice/commit/34e63cf690431da973a969376b493d8b34f5c7c0)
- i18n [`c94f9e5`](https://git.odit.services/lfk/selfservice/commit/c94f9e550e1cbe4626242423deb6d9ab994eea63)
- feat: wip: sponsoring add [`382757a`](https://git.odit.services/lfk/selfservice/commit/382757aa66cd79a6a8081ff4b21f6efe46a3ccfd)
- feat: cleanup profile [`0366f95`](https://git.odit.services/lfk/selfservice/commit/0366f95951d1415b300b174699d93e4bf17f3e18)
- 🚀Bumped version to v1.2.3 [`e7b9c6e`](https://git.odit.services/lfk/selfservice/commit/e7b9c6e2036addd18e109e3ab040e69dee2f658d)
- shareSponsorLink function [`ccea9d6`](https://git.odit.services/lfk/selfservice/commit/ccea9d61975bfa54928d557735cd3ce79d671435)
- no selfservice sponsor add for now [`3641d2a`](https://git.odit.services/lfk/selfservice/commit/3641d2a78341b91a26a9d4cc31c40707096768b1)
- feat: disable darkmode for now, also is better for visibility on day of run... [`0848209`](https://git.odit.services/lfk/selfservice/commit/0848209d49e4445881bf9536d87fe18ea2a6c924)
- wip [`4714b81`](https://git.odit.services/lfk/selfservice/commit/4714b814650d4138d8522dd57b5ee59a8c96a0ac)
- feat(footer): 2024 [`f6f46f4`](https://git.odit.services/lfk/selfservice/commit/f6f46f41bf2c6fcf75dbd79a28f6dd14114445e3)
- cleanup [`7f2e6b9`](https://git.odit.services/lfk/selfservice/commit/7f2e6b916076874cfb2e787ae174320b50d2d7e0)
#### [1.2.2](https://git.odit.services/lfk/selfservice/compare/1.2.1...1.2.2)
> 16 December 2024
- feat(profile): add cursor pointer [`1d7cd60`](https://git.odit.services/lfk/selfservice/commit/1d7cd601ee027dd7df0405079e208d03078210bb)
- 🚀Bumped version to v1.2.2 [`c8ceae5`](https://git.odit.services/lfk/selfservice/commit/c8ceae5cf016341af1bc903fb219e544bb2f0d58)
#### [1.2.1](https://git.odit.services/lfk/selfservice/compare/1.2.0...1.2.1)
> 16 December 2024
- feat(profile): show total distance [`55abb9e`](https://git.odit.services/lfk/selfservice/commit/55abb9ed22e4c66c05536897ba33b12915eea226)
- refactor(profile): replace styles with tailwindcss [`c34a8a7`](https://git.odit.services/lfk/selfservice/commit/c34a8a7fcc77a0fa27280365ebf2382fbffc1e61)
- 🚀Bumped version to v1.2.1 [`9ddb188`](https://git.odit.services/lfk/selfservice/commit/9ddb188ef659742018f00d786e030f80a0d9bbc5)
- feat(profile): updated tab alignment [`d564131`](https://git.odit.services/lfk/selfservice/commit/d5641312ca0b35a5c5ab9b7b19ed3a40971ac4fd)
#### [1.2.0](https://git.odit.services/lfk/selfservice/compare/1.1.2...1.2.0)
> 16 December 2024
- refacor(documents): Switch to new document-server [`721892c`](https://git.odit.services/lfk/selfservice/commit/721892c315de9c2c1158d0f728dc2ef387a5d8c2)
- 🚀Bumped version to v1.2.0 [`7d2a29c`](https://git.odit.services/lfk/selfservice/commit/7d2a29c0d834fbe783e59308af89bb8fb46a8015)
#### [1.1.2](https://git.odit.services/lfk/selfservice/compare/1.1.1...1.1.2)
> 11 December 2024
- chore(deps): bump all [`25c2a17`](https://git.odit.services/lfk/selfservice/commit/25c2a170bc9cde66498ae3d7f966201f2b28b679)
- 🚀Bumped version to v1.1.2 [`1d55445`](https://git.odit.services/lfk/selfservice/commit/1d55445c1b67ec2e1be73172d8e451f038451f59)
- refactor: drop postbuild step [`b21ad63`](https://git.odit.services/lfk/selfservice/commit/b21ad636ad69886878d5bd0f441f4187e4f22a5c)
- fix(profile): migrate to code128 [`762454a`](https://git.odit.services/lfk/selfservice/commit/762454a08674303881063337ddf86da564b191f1)
#### [1.1.1](https://git.odit.services/lfk/selfservice/compare/1.1.0...1.1.1)
> 11 December 2024
- 🚀Bumped version to v1.1.1 [`4771bf1`](https://git.odit.services/lfk/selfservice/commit/4771bf135986f90f344757083236539b9d590e83)
- fix(profile): passed id is a jwt [`dbe707b`](https://git.odit.services/lfk/selfservice/commit/dbe707b062ced048428b8c1f62a0ab047ab0051b)
#### [1.1.0](https://git.odit.services/lfk/selfservice/compare/1.0.1...1.1.0)
> 2 December 2024
- refactor: drop sub-directory routing [`4bcbc67`](https://git.odit.services/lfk/selfservice/commit/4bcbc67436e6c0b0905e3ef2613894854d659091)
- 🚀Bumped version to v1.1.0 [`dee1b7a`](https://git.odit.services/lfk/selfservice/commit/dee1b7a6eab11689bae8914e74bea7cb364475e2)
#### [1.0.1](https://git.odit.services/lfk/selfservice/compare/1.0.0...1.0.1)
> 2 December 2024
- fix(container): Add dockeringore [`7fcb6a9`](https://git.odit.services/lfk/selfservice/commit/7fcb6a9fc3f98772990790f6385200732f8bce7c)
- 🚀Bumped version to v1.0.1 [`595735a`](https://git.odit.services/lfk/selfservice/commit/595735ad003b849521e6e5f2b24da4880f768dff)
### [1.0.0](https://git.odit.services/lfk/selfservice/compare/0.11.3...1.0.0)
> 2 December 2024
- chore(deps): update all [`4a11fef`](https://git.odit.services/lfk/selfservice/commit/4a11fef0e0ad0940535fd1d6a1a57a829dc2b50d)
- chore: pnpm v9 [`b85c395`](https://git.odit.services/lfk/selfservice/commit/b85c3958c288293bb98df2326f73dfad1684e3cb)
- wip: general updates [`1eab535`](https://git.odit.services/lfk/selfservice/commit/1eab5353810a0a351cfc72b493c5156f55a4c9d2)
- refactor [`4af5c45`](https://git.odit.services/lfk/selfservice/commit/4af5c4545bfaad21d71bcbf91d2cd8ea53847b62)
- fix: translations [`548148e`](https://git.odit.services/lfk/selfservice/commit/548148e8982d7d146182af9f2a69de87f0b3529e)
- refactor: translations [`196b386`](https://git.odit.services/lfk/selfservice/commit/196b386d6d57e91fbb4f46091a59ba04bb6e6984)
- feat(ci)!: Switch to woodpecker [`9a3d307`](https://git.odit.services/lfk/selfservice/commit/9a3d307dfae0851eb842ad3f1c34460bca13bff1)
- i18n [`048edfb`](https://git.odit.services/lfk/selfservice/commit/048edfba89a69efd3362dd8df8b89f8780f5f3fe)
- registration brand font + more translations [`afffde8`](https://git.odit.services/lfk/selfservice/commit/afffde8fa04df88d0a8bff05d0a28550414ce385)
- feat: lfk font [`af9a168`](https://git.odit.services/lfk/selfservice/commit/af9a168f587768d8b1af8990729e743481ba687d)
- updated profile page [`4fcc38c`](https://git.odit.services/lfk/selfservice/commit/4fcc38c374553b22f92a734903df1b7a032348fa)
- 🚀Bumped version to v1.0.0 [`2285ea5`](https://git.odit.services/lfk/selfservice/commit/2285ea507069cf362baa950e7337aec72a37d4e3)
- i18n [`f296cbc`](https://git.odit.services/lfk/selfservice/commit/f296cbc1a0c9035db6546c85781be71b152264d7)
- feat(Footer): ref lfk [`6376dcb`](https://git.odit.services/lfk/selfservice/commit/6376dcb5fe7e3b1e1e639e41bc1b682036d838a0)
- feat(Home): improve ui [`75b61d9`](https://git.odit.services/lfk/selfservice/commit/75b61d991bd483aaf00871c12c9268fc6e21435b)
- refactor(ci): Make ready for new woodpecker [`780bc54`](https://git.odit.services/lfk/selfservice/commit/780bc54604998abd275f3b7d50a3849002eb243d)
- refactor: code cleanup [`ec6d252`](https://git.odit.services/lfk/selfservice/commit/ec6d252928fb84248041a3675590b85293c96133)
- chore: 2025 [`cb2f8ee`](https://git.odit.services/lfk/selfservice/commit/cb2f8eeab1a7e260df938b8aa94fa31f8e1b5efe)
- footer update [`90c085d`](https://git.odit.services/lfk/selfservice/commit/90c085db28798bbcac24eb9700285221a9bcad92)
- improved style in registered view [`1a3ab98`](https://git.odit.services/lfk/selfservice/commit/1a3ab98412b82eeb1f0dea8ea642f5fc6435c09d)
- add i18n ally snake case config [`0acda07`](https://git.odit.services/lfk/selfservice/commit/0acda07eb53a85f7b2e87a3e26d90b7cdf1fe012)
- feat(Home): improve background.jpg import [`3e289d8`](https://git.odit.services/lfk/selfservice/commit/3e289d83f9db98641f0f7f732b622dab9955f3a1)
- chore(deps): node@23.3.0 [`f71b01c`](https://git.odit.services/lfk/selfservice/commit/f71b01c39a62ef4402004e2fbcfacb37bc92ea39)
- Pin pnpm [`c36db2c`](https://git.odit.services/lfk/selfservice/commit/c36db2c18fc5f7cfd7bf5d295f3faf3931df736b)
#### [0.11.3](https://git.odit.services/lfk/selfservice/compare/0.11.2...0.11.3)
> 7 April 2023
- fix: registration code white bg [`#50`](https://git.odit.services/lfk/selfservice/issues/50)
- Pinned pnpm and lockfile [`6aca13f`](https://git.odit.services/lfk/selfservice/commit/6aca13f0cb1bc8fa43f0f09c554cec0758acd7a1)
- switched drone to kaniko with cache [`cac5103`](https://git.odit.services/lfk/selfservice/commit/cac5103d52427e777e4c3624ebb253ad7bd393d6)
- Switched dockerfile to pnpm with cache [`78fea1e`](https://git.odit.services/lfk/selfservice/commit/78fea1ea045a7281fe0a2841fc4d5f1505dcb3cf)
- 🚀Bumped version to v0.11.3 [`240f44d`](https://git.odit.services/lfk/selfservice/commit/240f44df60184c492f6cff3d864c1f9f2563ff80)
- chore(deps): pnpm@8.1.1 [`677e65f`](https://git.odit.services/lfk/selfservice/commit/677e65f44ae4bcc6f9af4732d813f337da0c51d2)
- fix(Footer): darkmode colors in lightmode [`772eca6`](https://git.odit.services/lfk/selfservice/commit/772eca64bb38ce1cf1ea1b58859dd744588a88e1)
#### [0.11.2](https://git.odit.services/lfk/selfservice/compare/0.11.1...0.11.2)
> 15 March 2023
- Added footer to every page [`b9624aa`](https://git.odit.services/lfk/selfservice/commit/b9624aa5ad57002852c84081fc710c2e977251bd)
- 🚀Bumped version to v0.11.2 [`fa51b31`](https://git.odit.services/lfk/selfservice/commit/fa51b31fe41d41b3ec9becad07ddab4cf73be051)
- Accept tos to accept privacy_policy [`09e48e7`](https://git.odit.services/lfk/selfservice/commit/09e48e771f4c0db4a7dbb898b05b347f1aad2292)
#### [0.11.1](https://git.odit.services/lfk/selfservice/compare/0.11.0...0.11.1)
> 18 February 2023
- Profile: add "---" if no data set [`659fa77`](https://git.odit.services/lfk/selfservice/commit/659fa77dca3b527d896d752386e91a167a1b8f4f)
- 🚀Bumped version to v0.11.1 [`8364321`](https://git.odit.services/lfk/selfservice/commit/8364321a7cb6a0037ee0c5055b028c4cf883fb10)
#### [0.11.0](https://git.odit.services/lfk/selfservice/compare/0.10.0...0.11.0)
> 3 February 2023
- pnpm migration [`a3a1e89`](https://git.odit.services/lfk/selfservice/commit/a3a1e89aa14798e1d180697f91809e282a229f23)
- 🚀Bumped version to v0.11.0 [`10c9127`](https://git.odit.services/lfk/selfservice/commit/10c9127256edf2cbad1dc6690d5f4e87c32f6396)
#### [0.10.0](https://git.odit.services/lfk/selfservice/compare/0.9.0...0.10.0)
> 3 February 2023
- text cleanups + footer [`eccce07`](https://git.odit.services/lfk/selfservice/commit/eccce0795b6960aa3a2e9368de5ae4bdf80997d7)
- updated nginx config for cache busting [`8e2b355`](https://git.odit.services/lfk/selfservice/commit/8e2b355466e9a37510be8bf03311d6b28e1a0d9f)
- improved profile page padding + full width registration code for easier scanning [`54540be`](https://git.odit.services/lfk/selfservice/commit/54540be6e12ed85afc96061b8548cd4ec6700eec)
- 🚀Bumped version to v0.10.0 [`5587175`](https://git.odit.services/lfk/selfservice/commit/5587175534188e05ab43d0eed9745484e01edb63)
#### [0.9.0](https://git.odit.services/lfk/selfservice/compare/0.8.3...0.9.0)
> 3 February 2023
- wip: error registration ui feedback [`9ac14e8`](https://git.odit.services/lfk/selfservice/commit/9ac14e8a5d740fb4cd87645e69b2cfde73e4acc7)
- wip: registration confirmation ui [`8928f84`](https://git.odit.services/lfk/selfservice/commit/8928f841dcd370daf28416adbf1adbe16fa4d76f)
- 🚀Bumped version to v0.9.0 [`3392a2e`](https://git.odit.services/lfk/selfservice/commit/3392a2e68edb8fcf2aa6dd4b962abbf6ac27a414)
#### [0.8.3](https://git.odit.services/lfk/selfservice/compare/0.8.2...0.8.3)
> 3 February 2023
- fix: registration code (broke in merge) [`123509d`](https://git.odit.services/lfk/selfservice/commit/123509d0a6d15fe254e28f7a316bd6c260fe7bd2)
- 🚀Bumped version to v0.8.3 [`4a5b9d2`](https://git.odit.services/lfk/selfservice/commit/4a5b9d25698931158a602b2159b4e6c4fa129e8e)
- wip: fix registration code [`51f8d0f`](https://git.odit.services/lfk/selfservice/commit/51f8d0fb42d0dbba268799eb9385686d22fd2284)
#### [0.8.2](https://git.odit.services/lfk/selfservice/compare/0.8.1...0.8.2)
> 3 February 2023
- move /registered/ to props [`c35f943`](https://git.odit.services/lfk/selfservice/commit/c35f943957e5ba84361a437c1d945331248746d1)
- 🚀Bumped version to v0.8.2 [`f4d1c7b`](https://git.odit.services/lfk/selfservice/commit/f4d1c7b053d1e7210911772bde1b2d80a30ab225)
- /profile/ text cleanups [`64e6ef8`](https://git.odit.services/lfk/selfservice/commit/64e6ef8cec38a8193c4fb28c5f1b26ee0e4d5063)
- /profile/ move from anchor tag to button [`ac75828`](https://git.odit.services/lfk/selfservice/commit/ac75828309043532c6ab8aad63e0c40edf450459)
- /profile/ toast styles [`c7f3a89`](https://git.odit.services/lfk/selfservice/commit/c7f3a893af8705af12f2e7ae7e40197ca4c28666)
- /profile/ dont instantly show mail format error [`ab9b400`](https://git.odit.services/lfk/selfservice/commit/ab9b400fff1b421a41dd27479a81fb5e3740b9ef)
- /profile/ autocomplete mail [`30fd7ea`](https://git.odit.services/lfk/selfservice/commit/30fd7ead0833b0b3ab4e5509608aa92112151380)
#### [0.8.1](https://git.odit.services/lfk/selfservice/compare/0.8.0...0.8.1)
> 2 February 2023
- 🚀Bumped version to v0.8.1 [`292e440`](https://git.odit.services/lfk/selfservice/commit/292e44057aee9ef57a51aa9fa0372c3678b81de0)
- Adjusted button text [`20fca67`](https://git.odit.services/lfk/selfservice/commit/20fca6794dd7e0c714cd09c80a68b1d3592ab09c)
- Switched request login link api path to login (backend v13.0.0) [`8139d63`](https://git.odit.services/lfk/selfservice/commit/8139d637151c8c0184e4a98f151991b429d0a70c)
#### [0.8.0](https://git.odit.services/lfk/selfservice/compare/0.7.11...0.8.0)
> 2 February 2023
- 🚀Bumped version to v0.8.0 [`7051909`](https://git.odit.services/lfk/selfservice/commit/7051909bf960fb44b43e979ac4d304dff9ef2ec4)
- Merge pull request 'dont autologin on register -> require mail link' (#47) from feature/46-dont-autologin-on-register-require-mail-link into dev [`f7a0682`](https://git.odit.services/lfk/selfservice/commit/f7a0682c3392b8882be4a676882c8a49d55bd5fe)
- add /registered/?mail route [`eb20b54`](https://git.odit.services/lfk/selfservice/commit/eb20b547e79d352f3b7cd1b5ce7b7dbfcf8c19f7)
#### [0.7.11](https://git.odit.services/lfk/selfservice/compare/0.7.10...0.7.11)
> 2 February 2023
- Profile: improved mobile responsiveness/ design + toast clear [`077b33f`](https://git.odit.services/lfk/selfservice/commit/077b33f03180d0bd6c45becaaa63d3408c645deb)
- 🚀Bumped version to v0.7.11 [`c63adf5`](https://git.odit.services/lfk/selfservice/commit/c63adf557bcb29c8eccc05d5a83d476c75380d95)
- fix: registration code download button style [`52a6b3d`](https://git.odit.services/lfk/selfservice/commit/52a6b3dc776b806eaa8fee058a1c381ab63a8ea5)
#### [0.7.10](https://git.odit.services/lfk/selfservice/compare/0.7.9...0.7.10)
> 1 February 2023
- Configureable barcode format via bwp-js [`9e06c46`](https://git.odit.services/lfk/selfservice/commit/9e06c464118c5b5d0cd78c8b8379523bf3bfdbd4)
- Added download for registration code [`53800b4`](https://git.odit.services/lfk/selfservice/commit/53800b4fa355bb972e51e71b5b1f98772deed114)
- 🚀Bumped version to v0.7.10 [`8b5e1ca`](https://git.odit.services/lfk/selfservice/commit/8b5e1cac1353373b13cf9d570deb7cadcd437247)
- Pinned version [`6438288`](https://git.odit.services/lfk/selfservice/commit/64382880c40ba5c1e3c9004ce7fc65099849cd44)
#### [0.7.9](https://git.odit.services/lfk/selfservice/compare/0.7.8...0.7.9)
> 1 February 2023
- migrate to bwip-js [`8cfddb5`](https://git.odit.services/lfk/selfservice/commit/8cfddb502964be7edf45cdc524344ea2f7f20142)
- fix codeconfig.height [`9b261bf`](https://git.odit.services/lfk/selfservice/commit/9b261bf20023561a7c9691dff33c9a6d2b5c0cac)
- 🚀Bumped version to v0.7.9 [`debbd92`](https://git.odit.services/lfk/selfservice/commit/debbd9219cb53dbd48cf0cb7bee329b765ce4647)
- drop jsbarcode [`713dd15`](https://git.odit.services/lfk/selfservice/commit/713dd153126851e8cf1045bf5ba3ca702a39c738)
#### [0.7.8](https://git.odit.services/lfk/selfservice/compare/0.7.7...0.7.8)
> 1 February 2023
- add barcode to profile [`851190e`](https://git.odit.services/lfk/selfservice/commit/851190e6a7f8b9cccbf05e60f9b50b96c196959c)
- 🚀Bumped version to v0.7.8 [`e5a01bc`](https://git.odit.services/lfk/selfservice/commit/e5a01bcd7629164655cacd10dd1f014260c67c4b)
- certificate generation: success toast styling [`1603a09`](https://git.odit.services/lfk/selfservice/commit/1603a097f71ed85c901baf8da04cb06b86474649)
#### [0.7.7](https://git.odit.services/lfk/selfservice/compare/0.7.6...0.7.7)
> 31 January 2023
- 🚀Bumped version to v0.7.7 [`c2b6152`](https://git.odit.services/lfk/selfservice/commit/c2b615294e605db37695b13cec1158f535986911)
- fix: registration w/o phone [`c647628`](https://git.odit.services/lfk/selfservice/commit/c64762831f1e6dffc9cbc3f531e23435b455a5a9)
#### [0.7.6](https://git.odit.services/lfk/selfservice/compare/0.7.5...0.7.6)
> 31 January 2023
- update texts of pdf generation status toasts [`#44`](https://git.odit.services/lfk/selfservice/issues/44)
- 🚀Bumped version to v0.7.6 [`9b446ab`](https://git.odit.services/lfk/selfservice/commit/9b446abc1fa231bb1f5a78c545400c617eaa4af5)
- update release script [`5d974e5`](https://git.odit.services/lfk/selfservice/commit/5d974e562ed1ed5aeac579afe000c2dca945ff71)
#### [0.7.5](https://git.odit.services/lfk/selfservice/compare/0.7.4...0.7.5)
> 30 January 2023
- fix: relativ links [`917cb6b`](https://git.odit.services/lfk/selfservice/commit/917cb6be340844bcc2318bf73cec37c3c831fd5d)
- 🚀Bumped version to v0.7.5 [`1249248`](https://git.odit.services/lfk/selfservice/commit/1249248a9d3e0d72665bca6871a651f2491a4039)
- 2023 [`9812d79`](https://git.odit.services/lfk/selfservice/commit/9812d79d4de820ce791f69634c5861f4f04ad7f1)
- update nginx base [`0bd6d54`](https://git.odit.services/lfk/selfservice/commit/0bd6d543bf60b7a333b96d5d319269d4bf50db96)
- updated base node image [`92d7bfd`](https://git.odit.services/lfk/selfservice/commit/92d7bfd59407273f86809b53ffc9f67fb8ba0ec7)
- AGB link [`d159cb5`](https://git.odit.services/lfk/selfservice/commit/d159cb59be35f963abc89c42732ba6110d27830c)
#### [0.7.4](https://git.odit.services/lfk/selfservice/compare/0.7.3...0.7.4)
> 21 April 2021
- Updated dronefile [`9c9ceaa`](https://git.odit.services/lfk/selfservice/commit/9c9ceaa6664f6ea21a536a12f04e552156e81da4)
- 🚀Bumped version to v0.7.4 [`4663214`](https://git.odit.services/lfk/selfservice/commit/4663214ede3880386b5389885e32c953571290e6)
#### [0.7.3](https://git.odit.services/lfk/selfservice/compare/0.7.2...0.7.3)
> 21 April 2021
- 🚀Bumped version to v0.7.3 [`602d80b`](https://git.odit.services/lfk/selfservice/commit/602d80bd14c4bd00a24b746be1e74d9e41af0445)
- Merge pull request 'Button fixes bugfix/42-button_links' (#43) from bugfix/42-button_links into dev [`45ee4ab`](https://git.odit.services/lfk/selfservice/commit/45ee4ab81260adf5b938d9f5359d256cce879acb)
- Removed useless register now button [`1102d29`](https://git.odit.services/lfk/selfservice/commit/1102d29c0e174b7a34fc4d3e6fe32d2dfb276765)
- Fixed register button link [`020c310`](https://git.odit.services/lfk/selfservice/commit/020c310865912b8f0752069e1c7e2adf71ab9835)
#### [0.7.2](https://git.odit.services/lfk/selfservice/compare/0.7.1...0.7.2)
> 14 April 2021
- 🚀Bumped version to v0.7.2 [`1a3af20`](https://git.odit.services/lfk/selfservice/commit/1a3af200dd41c8cc4271690ed72bef911901ce54)
- Document generation hotfix 🐞 [`b74bea0`](https://git.odit.services/lfk/selfservice/commit/b74bea03401c672ae774aaddc6da5beb67e2890e)
#### [0.7.1](https://git.odit.services/lfk/selfservice/compare/0.7.0...0.7.1)
> 13 April 2021
- Merge pull request 'bugfix/31-env-js-linking-ci' (#41) from bugfix/31-env-js-linking-ci into dev [`#31`](https://git.odit.services/lfk/selfservice/issues/31)
- ⏫ dependency bump [`ad13bae`](https://git.odit.services/lfk/selfservice/commit/ad13bae068416bed10d00e6887a05d580a836482)
- 🚀Bumped version to v0.7.1 [`b0172c5`](https://git.odit.services/lfk/selfservice/commit/b0172c500b0613209ac44e61023043065b3854b0)
- added 'yarn postbuild' script for fixing env.js in dist/index.html [`51d058b`](https://git.odit.services/lfk/selfservice/commit/51d058bf966c3dcb064562e6bf696a748d0cd148)
#### [0.7.0](https://git.odit.services/lfk/selfservice/compare/0.6.1...0.7.0)
> 6 April 2021
- 🚀Bumped version to v0.7.0 [`152e741`](https://git.odit.services/lfk/selfservice/commit/152e74190d13d30110d494a9062f868390ca19b3)
- Merge pull request 'Donation list feature/39-donation_list' (#40) from feature/39-donation_list into dev [`4c83e2e`](https://git.odit.services/lfk/selfservice/commit/4c83e2e738a075354383dca4d500808f761247d2)
- Added total to bottom of page [`89820d4`](https://git.odit.services/lfk/selfservice/commit/89820d44501793365248b8e778522cdc188afa70)
- Sorted translations 🌍 [`cb1b9d3`](https://git.odit.services/lfk/selfservice/commit/cb1b9d330b28f11cceed9691aee4ccee5246d346)
- Added basic sponsoring table [`f141130`](https://git.odit.services/lfk/selfservice/commit/f141130db5ede60a623747f4e324f66259e5bc75)
- Added translations 🌍 [`d713fbe`](https://git.odit.services/lfk/selfservice/commit/d713fbef94e75fbbc62254ea8f0ca50dc4e93d79)
- Now w/ formatted currency amount [`815a36f`](https://git.odit.services/lfk/selfservice/commit/815a36f20271f47f49c3814b001c3404d43113cd)
- Fixed spaces in name [`baa6da3`](https://git.odit.services/lfk/selfservice/commit/baa6da3dd06c493fccc61945b9bcbd9b2e79d910)
- Updated env description [`5a123b0`](https://git.odit.services/lfk/selfservice/commit/5a123b0cf89f49d450becbbc03b28c5bb6416b7c)
- added distance formatting [`121022c`](https://git.odit.services/lfk/selfservice/commit/121022c8434484a363a3f2ea68aba4d8ef7cad2d)
#### [0.6.1](https://git.odit.services/lfk/selfservice/compare/0.6.0...0.6.1)
> 6 April 2021
- 🚀Bumped version to v0.6.1 [`f5ae214`](https://git.odit.services/lfk/selfservice/commit/f5ae2145df07413329f60c229d9571fd1de2ca79)
- Fixed imprint/privacy default links [`96c0e56`](https://git.odit.services/lfk/selfservice/commit/96c0e5698697361e65c5aa80c9a0aada5c3d5f30)
#### [0.6.0](https://git.odit.services/lfk/selfservice/compare/0.5.1...0.6.0)
> 3 April 2021
- 🚀Bumped version to v0.6.0 [`bc1de2a`](https://git.odit.services/lfk/selfservice/commit/bc1de2acdcbf8f3319026887cb6b3d594fcd63dc)
- first part of certificate generation with manual data [`f633439`](https://git.odit.services/lfk/selfservice/commit/f6334397dc99cd38d31ef524bc26ba7d386b33dd)
- Renoved fixed data [`f0a7f35`](https://git.odit.services/lfk/selfservice/commit/f0a7f35dec07508a07d4c11abda297ad0bf91187)
- Revert "🚀Bumped version to v0.6.0" [`145b499`](https://git.odit.services/lfk/selfservice/commit/145b49906bdf2d75abf93e1779f188a691a3a909)
- 🚀Bumped version to v0.6.0 [`0a62e8f`](https://git.odit.services/lfk/selfservice/commit/0a62e8f5d1929bfe9a53a9709a3031f06a2487c3)
- Merge pull request 'Certificate download feature/19-runner_certficates' (#38) from feature/19-runner_certficates into dev [`53eeb6b`](https://git.odit.services/lfk/selfservice/commit/53eeb6be3ddf4735a11b6c4636c28b4d16aa58ee)
- Fixed blob handling [`b938cfc`](https://git.odit.services/lfk/selfservice/commit/b938cfc49e269e76761a752f8257ebbab88f6959)
- Reverted relative linking fix [`c3b2b93`](https://git.odit.services/lfk/selfservice/commit/c3b2b93d90102b4e31cfce15220acfc8fe48a7c5)
#### [0.5.1](https://git.odit.services/lfk/selfservice/compare/0.5.0...0.5.1)
> 3 April 2021
- Merge pull request 'feature/30-profile-forgot-link' (#35) from feature/30-profile-forgot-link into dev [`#30`](https://git.odit.services/lfk/selfservice/issues/30)
- 🚀Bumped version to v0.5.1 [`1a3c9ed`](https://git.odit.services/lfk/selfservice/commit/1a3c9edeb3987907ffe2223da8f3be079a1c80d2)
- Merge pull request 'Env linking bugfix bugfix/31-env_linking' (#37) from bugfix/31-env_linking into dev [`fd6bd88`](https://git.odit.services/lfk/selfservice/commit/fd6bd88d4238cca2a2755ab1bc51ff7870bef947)
- basic ProfileNone layout [`863568d`](https://git.odit.services/lfk/selfservice/commit/863568d7d0e132dd1b7d13a2cb1afe8db02c472c)
- add forgot view + action [`30f3a51`](https://git.odit.services/lfk/selfservice/commit/30f3a51ef82ad966225abc6fd95508af56106924)
- Added building pipeline for current branch [`544542a`](https://git.odit.services/lfk/selfservice/commit/544542ac1e9717506676c1495c2d530eca833d31)
- Removed useless code [`713db5e`](https://git.odit.services/lfk/selfservice/commit/713db5e1e8fed5f38b3a5d19cfe870eff16eeda1)
- Now manually linking env and main [`67c0dae`](https://git.odit.services/lfk/selfservice/commit/67c0dae537df5842e89c0ed040c0fef02df01b69)
- Fixed post url and body [`0795ea3`](https://git.odit.services/lfk/selfservice/commit/0795ea318d80b764eee89462ad87da86aa7ce0ae)
- 🐞 fix home routes [`60dea51`](https://git.odit.services/lfk/selfservice/commit/60dea511b9fbb6d206ee531618e788e686fa6b5a)
#### [0.5.0](https://git.odit.services/lfk/selfservice/compare/0.4.5...0.5.0)
> 1 April 2021
- 🚀Bumped version to v0.5.0 [`676f0e8`](https://git.odit.services/lfk/selfservice/commit/676f0e83393be823ccb612846650a9a98bf7f0b3)
- Revert "🚀Bumped version to v0.5.0" [`27fd8f9`](https://git.odit.services/lfk/selfservice/commit/27fd8f9a9106294ae6522f2fff42dfbf84f06f82)
- 🚀Bumped version to v0.5.0 [`b8c1b8c`](https://git.odit.services/lfk/selfservice/commit/b8c1b8c43b6d050d239d836bbb6ace2504fdcd21)
- Merge pull request 'Runner self deletion feature/21-user_deletion' (#36) from feature/21-user_deletion into dev [`bd512e0`](https://git.odit.services/lfk/selfservice/commit/bd512e0651363f1f2543136d354d9ada9990d83d)
- Sorted translations [`cf0437c`](https://git.odit.services/lfk/selfservice/commit/cf0437c3a738d42154ed1336d6020b88661b462f)
- Added translations 🌍 [`ba3dedb`](https://git.odit.services/lfk/selfservice/commit/ba3dedb1643e2d5f1c2ab92224a11c1c8a82ae71)
- Added confirmation for profile deletion [`8773239`](https://git.odit.services/lfk/selfservice/commit/8773239244c064a888a4ad1f66298f2811fcc2ae)
- Added confirmation for profile deletion [`85b0549`](https://git.odit.services/lfk/selfservice/commit/85b0549a11927758c579cd08bc8015ae00105a84)
- Updated icons [`d710d4b`](https://git.odit.services/lfk/selfservice/commit/d710d4b68ff0e9515eb4a0a4ea0def7b3552e599)
- Added data deletion button [`619078c`](https://git.odit.services/lfk/selfservice/commit/619078cce8281bef520b05bf3e735c26d0752375)
- Content i18n run 🌍 [`175bb16`](https://git.odit.services/lfk/selfservice/commit/175bb168ae134009c26072b76cd74948aecc189f)
- Implemented basic deletion [`fc04e71`](https://git.odit.services/lfk/selfservice/commit/fc04e713110df161c481cb9a3b64e78b30d4f79b)
- Added translations [`8a24505`](https://git.odit.services/lfk/selfservice/commit/8a24505d64832001d6a44800f61f7e0705892046)
- Updated toasts and removed useless code [`7440fc4`](https://git.odit.services/lfk/selfservice/commit/7440fc404ea2a8e68e7ce896e8369700069b2021)
- Added error toast [`9751c2e`](https://git.odit.services/lfk/selfservice/commit/9751c2e9fd99650efab4d5edce3909c907ea9391)
- Merge pull request 'RELEASE 0.3.0' (#25) from dev into main [`1c19657`](https://git.odit.services/lfk/selfservice/commit/1c196579356a70f9d761f7f69d79033157570076)
#### [0.4.5](https://git.odit.services/lfk/selfservice/compare/0.4.4...0.4.5)
> 1 April 2021
- Merge pull request 'feature/32-registration-language' (#33) from feature/32-registration-language into dev [`#32`](https://git.odit.services/lfk/selfservice/issues/32)
- 🚀Bumped version to v0.4.5 [`efcb7f5`](https://git.odit.services/lfk/selfservice/commit/efcb7f56745aa3f347eb98399ee1bcb68a157e9d)
- 🐞 fix /profile/ router on register [`52a0828`](https://git.odit.services/lfk/selfservice/commit/52a082841d47d1ed9c0997776a0784285a3f6ba7)
- pass browser locale to api/runners/register/ [`e3f7497`](https://git.odit.services/lfk/selfservice/commit/e3f7497af5860b2472b6cdfd33090b9d68b9fb49)
#### [0.4.4](https://git.odit.services/lfk/selfservice/compare/0.4.3...0.4.4)
> 31 March 2021
- 🚀Bumped version to v0.4.4 [`9b62962`](https://git.odit.services/lfk/selfservice/commit/9b62962758f8a73d669bca69b77f2c09a13c9e7a)
- 🚑 hotfix - baseurl_selfservice -> baseurl [`84dc33b`](https://git.odit.services/lfk/selfservice/commit/84dc33bf14ace839261aea02ffbcac5d627f8200)
#### [0.4.3](https://git.odit.services/lfk/selfservice/compare/0.4.2...0.4.3)
> 31 March 2021
- 🚀Bumped version to v0.4.3 [`cad34d3`](https://git.odit.services/lfk/selfservice/commit/cad34d357b9bd8501eed26b35b5324d2b4f756c3)
- 🚑 hotfix - Profile api path [`2056ce1`](https://git.odit.services/lfk/selfservice/commit/2056ce1e62a33e14bce5bdef5ea8cd38e039dc62)
#### [0.4.2](https://git.odit.services/lfk/selfservice/compare/0.4.1...0.4.2) #### [0.4.2](https://git.odit.services/lfk/selfservice/compare/0.4.1...0.4.2)
> 31 March 2021
- 🚀Bumped version to v0.4.2 [`3b2c99c`](https://git.odit.services/lfk/selfservice/commit/3b2c99c7090de03aab12415342136460ddd735ee)
- 🚑 fix organization registration token [`f150821`](https://git.odit.services/lfk/selfservice/commit/f150821f0f60e4798b02ebf50588da61ccb51279) - 🚑 fix organization registration token [`f150821`](https://git.odit.services/lfk/selfservice/commit/f150821f0f60e4798b02ebf50588da61ccb51279)
#### [0.4.1](https://git.odit.services/lfk/selfservice/compare/0.4.0...0.4.1) #### [0.4.1](https://git.odit.services/lfk/selfservice/compare/0.4.0...0.4.1)
+9 -5
View File
@@ -1,9 +1,13 @@
FROM node:15.9.0-alpine3.13 FROM node:23.10.0-alpine3.21 AS build
# ARG NPM_REGISTRY_URL=https://registry.npmjs.org
WORKDIR /app WORKDIR /app
COPY . . COPY . .
RUN yarn # RUN npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@9
RUN yarn build RUN npm i -g pnpm@10.7
RUN pnpm i --frozen-lockfile
RUN pnpm build
# final image # final image
FROM fholzer/nginx-brotli:v1.19.1 FROM registry.odit.services/library/nginx-brotli:3.15 AS final
COPY --from=0 /app/dist /usr/share/nginx/html COPY --from=build /app/dist /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf COPY ./nginx.conf /etc/nginx/nginx.conf
+1 -22
View File
@@ -2,29 +2,8 @@
runner selfservice portal runner selfservice portal
## ⚡ Development
### Requirements
- Node.js v14.16.0 or newer
- yarn package manager >= v1.22.10 < 2
### Recommended Extensions
- will be automatically recommended via `./vscode/extensions.json`
- we also provide a config for i18n-ally in the `./vscode/` folder
### Fastest Dev Environment
- You can install the [Remote - Containers](https://github.com/Microsoft/vscode-remote-release) extension and use all recommended extensions and editor settings via the provided `./devcontainer/` config
### Manual Dev Environment
```
yarn && yarn dev --open
```
## 🔨 Environment config ## 🔨 Environment config
- copy the `/public/env.sample.js` file to `/public/env.js` - copy the `/public/env.sample.js` file to `/public/env.js`
- set the required environment variables - set the required environment variables
- `documentserver_key`: url to the [document server](https://git.odit.services/lfk/document-server) instance - `documentserver_key`: url to the [document server](https://git.odit.services/lfk/document-server) instance
- `baseurl`: url to the main lfk instance - WITH TRAILING SLASH - `baseurl`: url to the main lfk instance - WITH TRAILING SLASH
- see [@lfk/deployment](https://git.odit.services/lfk/deployment) for a complete deployment guide
- `baseurl_selfservice`: location of the selfservice instance - WITH TRAILING SLASH
- e.g. path: `/selfservice/`
- e.g. url: `https://example.com/selfservice/`
+16 -16
View File
@@ -1,17 +1,17 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="de"> <html lang="de">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon-lfk.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lauf für Kaya! - Selfservice</title> <title>Lauf für Kaya! - Selfservice</title>
</head> </head>
<body class="dark:bg-gray-900 text-black dark:text-white p-0"> <body class="dark:bg-gray-900 text-black dark:text-white p-0">
<div id="app"></div> <div id="app"></div>
<script src="/env.js"></script> <script src="/env.js"></script>
<script defer type="module" src="/src/main.js"></script> <script defer type="module" src="/src/main.js"></script>
</body> </body>
</html> </html>
+29 -23
View File
@@ -7,15 +7,21 @@ http {
error_page 404 /index.html; error_page 404 /index.html;
root /usr/share/nginx/html; root /usr/share/nginx/html;
location / { location / {
rewrite /register/(.*) /$1 break; rewrite /register/(.*) /$1 break;
rewrite /profile/(.*) /$1 break; rewrite /profile/(.*) /$1 break;
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
} }
location ~* \.(?:ico|css|gif|jpe?g|png)$ { location ~* \.(?:ico|css|gif|jpe?g|png)$ {
rewrite /register/(.*) /$1 break; rewrite /register/(.*) /$1 break;
rewrite /profile/(.*) /$1 break; rewrite /profile/(.*) /$1 break;
expires 1y; expires 1y;
add_header Pragma public; add_header Pragma public;
@@ -35,24 +41,24 @@ http {
gzip_buffers 16 8k; gzip_buffers 16 8k;
gzip_http_version 1.1; gzip_http_version 1.1;
gzip_types application/javascript gzip_types application/javascript
application/rss+xml application/rss+xml
application/vnd.ms-fontobject application/vnd.ms-fontobject
application/x-font application/x-font
application/x-font-opentype application/x-font-opentype
application/x-font-otf application/x-font-otf
application/x-font-truetype application/x-font-truetype
application/x-font-ttf application/x-font-ttf
application/x-javascript application/x-javascript
application/xhtml+xml application/xhtml+xml
application/xml application/xml
font/opentype font/opentype
font/otf font/otf
font/ttf font/ttf
image/svg+xml image/svg+xml
image/x-icon image/x-icon
text/css text/css
text/javascript text/javascript
text/plain text/plain
text/xml; text/xml;
} }
} }
+10 -8
View File
@@ -1,16 +1,18 @@
const fs = require('fs'); import { readdirSync, readFileSync, writeFileSync } from "node:fs";
// get all language files // get all language files
const files = fs.readdirSync('./src/locales/'); const files = readdirSync("./src/locales/");
files.forEach((f) => { files.forEach((f) => {
// read file as object // read file as object
const unordered = JSON.parse(fs.readFileSync(`src/locales/${f}`)); const unordered = JSON.parse(readFileSync(`src/locales/${f}`));
// order object by keys alpabetically A-Z // order object by keys alpabetically A-Z
const ordered = Object.keys(unordered).sort().reduce((obj, key) => { const ordered = Object.keys(unordered)
obj[key] = unordered[key]; .sort()
return obj; .reduce((obj, key) => {
}, {}); obj[key] = unordered[key];
return obj;
}, {});
// format output as json for commit diff compatibility // format output as json for commit diff compatibility
const out = JSON.stringify(ordered, 0, 4); const out = JSON.stringify(ordered, 0, 4);
// write output file // write output file
fs.writeFileSync(`src/locales/${f}`, out); writeFileSync(`src/locales/${f}`, out);
}); });
+50 -50
View File
@@ -1,50 +1,50 @@
{ {
"name": "@odit/lfk-selfservice", "name": "@odit/lfk-selfservice",
"version": "0.4.2", "version": "1.4.1",
"scripts": { "type": "module",
"dev": "vite", "scripts": {
"build": "vite build", "dev": "vite",
"release": "release-it --only-version" "build": "vite build",
}, "release": "release-it"
"dependencies": { },
"marked": "2.0.1", "dependencies": {
"redaxios": "0.4.1", "@fontsource/athiti": "5.2.5",
"toastify-js": "1.10.0", "@odit/lfk-client": "^0.0.1",
"validator": "13.5.2", "@tailwindcss/vite": "4.0.17",
"vue-i18n": "9.0.0", "bwip-js": "4.5.3",
"vue-toastification": "2.0.0-rc.1", "marked": "15.0.7",
"vue": "3.0.9", "redaxios": "0.5.1",
"vue-router": "4.0.5" "tailwindcss": "4.0.17",
}, "toastify-js": "1.12.0",
"devDependencies": { "validator": "13.15.0",
"@tailwindcss/jit": "0.1.18", "vue": "3.5.13",
"@tailwindcss/aspect-ratio": "0.2.0", "vue-i18n": "10.0.5",
"@tailwindcss/forms": "0.3.2", "vue-router": "4.5.0",
"@tailwindcss/line-clamp": "0.2.0", "vue-toastification": "2.0.0-rc.1"
"@tailwindcss/typography": "0.4.0", },
"@vitejs/plugin-vue": "1.2.1", "devDependencies": {
"@vue/compiler-sfc": "3.0.10", "@vitejs/plugin-vue": "5.2.3",
"autoprefixer": "10.2.5", "autoprefixer": "10.4.21",
"tailwindcss": "2.0.4", "release-it": "18.1.2",
"release-it": "14.5.0", "vite": "6.2.3",
"vite": "2.1.5" "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": false, "push": true,
"tag": true, "tag": true,
"tagName": null, "tagName": "${version}",
"tagAnnotation": "v${version}" "tagAnnotation": "${version}"
}, },
"npm": { "npm": {
"publish": false "publish": false
}, },
"hooks": { "hooks": {
"after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node order_i18n.js && git add src/locales" "after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node order_i18n.js && git add src/locales"
} }
} }
} }
+4150
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -1,6 +0,0 @@
module.exports = {
plugins: {
'@tailwindcss/jit': {},
autoprefixer: {},
},
}
+10 -8
View File
@@ -1,12 +1,14 @@
const config = { const config = {
// required // required
documentserver_key: '', documentserver_key: "",
// required, with trailing slash // required, with trailing slash
baseurl: '', baseurl: "",
// optional, will fallback to /selfservice/ // optional, full url, will fallback to https://lauf-fuer-kaya.de/impressum
baseurl_selfservice: '/selfservice/', url_imprint: "",
// optional, will fallback to /imprint // optional, full url, will fallback to https://lauf-fuer-kaya.de/datenschutz
url_imprint: '', url_privacy: "",
// optional, will fallback to /privacy // full url (including fqdn)
url_privacy: '' baseurl_documentserver: "http://localhost:3000",
// optional, will fallback to code128
code_format: "ean13",
}; };

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

-1
View File
@@ -1 +0,0 @@
TODO:
-1
View File
@@ -1 +0,0 @@
TODO:

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

-29
View File
@@ -1,29 +0,0 @@
<template>
<section class="container px-4 py-32 mx-auto">
<div class="w-full mx-auto lg:w-1/3">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="h-20 feather feather-alert-triangle"
viewBox="0 0 24 24"
>
<path
d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0zM12 9v4M12 17h.01"
/>
</svg>
<p
class="mt-5 mb-3 text-xl font-bold text-black dark:text-gray-50 md:text-2xl"
>{{ $t('configuration_error') }}</p>
<p class="mb-3 text-base font-medium text-gray-700 dark:text-gray-400">
{{ $t('the_system_is_not_properly_configured_please_contact_the_system_administrator_for_help') }}
<br />
<br />
{{ $t('if_you_are_the_system_administrator_please_refer_to_the_official_product_documentation_readme_for_configuration_guidance') }}
</p>
</div>
</section>
</template>
+11 -28
View File
@@ -1,38 +1,21 @@
<template> <template>
<footer class="text-gray-400 bg-gray-900 body-font"> <footer>
<div class="container px-5 py-8 mx-auto flex items-center sm:flex-row flex-col"> <p class="text-sm sm:py-2 sm:mt-0 mt-4 text-center md:text-left">
<p class="text-sm text-gray-400 sm:ml-4 sm:pl-4 sm:py-2 sm:mt-0 mt-4"> Lauf für Kaya! Selfservice<br>Copyright © 2025<br>proudly powered by
Lauf für Kaya! Selfservice - Copyright © 2021 + proudly powered by <a class="underline" target="_blank" rel="noopener,noreferrer"
<a href="https://odit.services?ref=lfk">ODIT.Services</a><br>
class="underline" <a target="_blank" rel="noopener,noreferrer" :href="[[imprint_url]]" class="underline">{{
target="_blank" $t('imprint') }}</a> <a target="_blank" rel="noopener,noreferrer" :href="[[privacy_url]]" class="underline">{{
rel="noopener,noreferrer" $t('privacy_policy') }}</a>
href="https://odit.services" </p>
>ODIT.Services</a>
</p>
<span class="inline-flex sm:ml-auto sm:mt-0 mt-4 justify-center sm:justify-start">
<a
target="_blank"
rel="noopener,noreferrer"
:href="[[imprint_url]]"
class="ml-3 text-gray-400 underline"
>Impressum</a>
<a
target="_blank"
rel="noopener,noreferrer"
:href="[[privacy_url]]"
class="ml-3 text-gray-400 underline"
>Datenschutzerklärung</a>
</span>
</div>
</footer> </footer>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
imprint_url: config.url_imprint || "/imprint/" imprint_url: config.url_imprint || "https://lauf-fuer-kaya.de/impressum"
, privacy_url: config.url_privacy || "/privacy/" , privacy_url: config.url_privacy || "https://lauf-fuer-kaya.de/datenschutz"
} }
}, },
} }
-30
View File
@@ -1,30 +0,0 @@
<template>
<h1>{{ msg }}</h1>
<p>
<a href="https://vitejs.dev/guide/features.html" target="_blank">Vite Documentation</a> |
<a href="https://v3.vuejs.org/" target="_blank">Vue 3 Documentation</a>
</p>
<button @click="state.count++">count is: {{ state.count }}</button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test hot module replacement.
</p>
</template>
<script setup>
import { defineProps, reactive } from 'vue'
defineProps({
msg: String
})
const state = reactive({ count: 0 })
</script>
<style scoped>
a {
color: #42b983;
}
</style>
-109
View File
@@ -1,109 +0,0 @@
<template>
<div class="min-h-screen flex items-center justify-center">
<div class="max-w-md w-full py-12 px-6">
<img class="mx-auto h-24 w-auto" src="/favicon.png" alt="" />
<h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-center">Lauf für Kaya! - Registrieren</h1>
<p
class="mx-auto leading-relaxed text-base text-center"
>Bitte anmelden...</p>
<div class="mt-5">
<div class="rounded-md shadow-sm">
<div>
<input
aria-label="E-Mail Adresse"
name="email"
type="email"
required
class="border-gray-300 placeholder-gray-500 appearance-none rounded-none relative block w-full px-3 py-2 border text-gray-900 rounded-t-md focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
placeholder="E-Mail Adresse"
v-model="mail"
/>
</div>
<div class="-mt-px relative">
<input
aria-label="Passwort"
name="password"
type="password"
required
class="border-gray-300 placeholder-gray-500 appearance-none rounded-none relative block w-full px-3 py-2 border text-gray-900 rounded-b-md focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
placeholder="Passwort"
/>
<div class="absolute inset-y-0 right-0 pr-3 flex items-center text-sm">
<a href="./reset" class="text-gray-900 underline">Passwort vergessen?</a>
</div>
</div>
</div>
<div class="mt-5">
<button
v-if="loading === false"
@click="login"
type="submit"
class="relative block w-full py-2 px-3 border border-transparent rounded-md font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm text-white"
>
<span class="absolute left-0 inset-y pl-3">
<svg class="h-5 w-5 text-gray-500" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
clip-rule="evenodd"
/>
</svg>
</span>
Log in
</button>
<button
v-if="loading === true"
type="submit"
class="relative block w-full py-2 px-3 border border-transparent rounded-md font-semibold bg-yellow-500 sm:text-sm text-black"
>
<span class="absolute left-0 inset-y pl-3">
<svg class="h-5 w-5 text-gray-500" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
clip-rule="evenodd"
/>
</svg>
</span>
Logging in...
</button>
</div>
</div>
<div class="mt-6">
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white dark:bg-gray-900">Sie haben noch keinen Account?</span>
</div>
</div>
<div class="mt-6">
<a
href="./register"
class="block w-full text-center py-2 px-3 border border-gray-300 rounded-md font-medium hover:border-gray-400 focus:outline-none focus:border-gray-400 sm:text-sm"
>Account erstellen</a>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import axios from "redaxios";
import Toastify from "toastify-js";
let mail = ref("");
let loading = ref(false);
function login() {
loading.value = true;
axios.get("").then((res) => {
loading.value = false;
Toastify({
text: "This is a toast",
duration: 3000,
}).showToast();
});
}
</script>
-109
View File
@@ -1,109 +0,0 @@
<template>
<div class="min-h-screen flex items-center justify-center">
<div class="max-w-md w-full py-12 px-6">
<!-- <img class="mx-auto h-8 w-auto" src="/img/tailwindui-logo.svg" alt="" /> -->
<h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-center">Login</h1>
<p
class="mx-auto leading-relaxed text-base text-center"
>Bitte anmelden...</p>
<div class="mt-5">
<div class="rounded-md shadow-sm">
<div>
<input
aria-label="E-Mail Adresse"
name="email"
type="email"
required
class="border-gray-300 placeholder-gray-500 appearance-none rounded-none relative block w-full px-3 py-2 border text-gray-900 rounded-t-md focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
placeholder="E-Mail Adresse"
v-model="mail"
/>
</div>
<div class="-mt-px relative">
<input
aria-label="Passwort"
name="password"
type="password"
required
class="border-gray-300 placeholder-gray-500 appearance-none rounded-none relative block w-full px-3 py-2 border text-gray-900 rounded-b-md focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm"
placeholder="Passwort"
/>
<div class="absolute inset-y-0 right-0 pr-3 flex items-center text-sm">
<a href="./reset" class="text-gray-900 underline">Passwort vergessen?</a>
</div>
</div>
</div>
<div class="mt-5">
<button
v-if="loading === false"
@click="login"
type="submit"
class="relative block w-full py-2 px-3 border border-transparent rounded-md font-semibold bg-gray-800 hover:bg-gray-700 focus:bg-gray-900 focus:outline-none focus:shadow-outline sm:text-sm text-white"
>
<span class="absolute left-0 inset-y pl-3">
<svg class="h-5 w-5 text-gray-500" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
clip-rule="evenodd"
/>
</svg>
</span>
Log in
</button>
<button
v-if="loading === true"
type="submit"
class="relative block w-full py-2 px-3 border border-transparent rounded-md font-semibold bg-yellow-500 sm:text-sm text-black"
>
<span class="absolute left-0 inset-y pl-3">
<svg class="h-5 w-5 text-gray-500" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
clip-rule="evenodd"
/>
</svg>
</span>
Logging in...
</button>
</div>
</div>
<div class="mt-6">
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white dark:bg-gray-900">Sie haben noch keinen Account?</span>
</div>
</div>
<div class="mt-6">
<a
href="./register"
class="block w-full text-center py-2 px-3 border border-gray-300 rounded-md font-medium hover:border-gray-400 focus:outline-none focus:border-gray-400 sm:text-sm"
>Account erstellen</a>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import axios from "redaxios";
import Toastify from "toastify-js";
let mail = ref("");
let loading = ref(false);
function login() {
loading.value = true;
axios.get("").then((res) => {
loading.value = false;
Toastify({
text: "This is a toast",
duration: 3000,
}).showToast();
});
}
</script>
+52 -8
View File
@@ -1,41 +1,85 @@
{ {
"already_have_an_account": "Sie haben bereits einen Account?", "access_is_only_provided_via_your_email_link": "Der Zugang erfolgt über den Link, den Sie bei der Registrierung erhalten haben.",
"add_sponsoring": "Sponsoring hinzufügen",
"alle_daten_geloescht": "Alle Daten gelöscht!",
"already_registered": "bereits registriert...",
"amount_per_kilometer_in_eur": "Betrag pro Kilometer (in €)",
"apartment_suite_etc": "Addresszeile 2", "apartment_suite_etc": "Addresszeile 2",
"buergerlauf": "Bürgerlauf",
"cancel_keep_my_data": "Abbrechen, meine Daten behalten",
"configuration_error": "Konfigurationsfehler", "configuration_error": "Konfigurationsfehler",
"confirm_delete_all_of_my_data": "Bestätigen, meine Daten löschen",
"confirm_personal_data": "Hiermit bestätige ich die Vollständigkeit und Richtigkeit der oben genannten Angaben", "confirm_personal_data": "Hiermit bestätige ich die Vollständigkeit und Richtigkeit der oben genannten Angaben",
"current_total_amount_in_eur": "Aktueller Gesamtbetrag (in €)",
"delete_my_data": "Meine Daten löschen",
"distance": "Distanz", "distance": "Distanz",
"download_certificate": "Urkunde herunterladen", "download_certificate": "Urkunde herunterladen",
"download_registrationcode": "Registrierungscode herunterladen",
"e_mail_adress": "E-Mail Adresse", "e_mail_adress": "E-Mail Adresse",
"go_to_login": "Zum Login", "e_mail_des_sponsors": "E-Mail des Sponsors",
"error_requesting_the_login_link": "Fehler beim Anfordern des Login-Links...",
"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",
"lap_time": "Rundenzeit", "lap_time": "Rundenzeit",
"lap_times": "Rundenzeiten", "lap_times": "Rundenzeiten",
"login_link_gesendet_an_user_email_value": "Login-Link gesendet an ",
"login_link_is_requested": "Login-Link wird angefordert...",
"lost_your_registration_mail": "Brauchen Sie einen neuen Login-Link?",
"main_page_text": "Hier können Sie sich für den Lauf Für Kaya! registrieren oder ihr Läuferprofil verwalten.", "main_page_text": "Hier können Sie sich für den Lauf Für Kaya! registrieren oder ihr Läuferprofil verwalten.",
"mittelname": "Mittelname", "mittelname": "Mittelname",
"nachname": "Nachname", "nachname": "Nachname",
"no_laps_scans_were_recorded_yet": "Es wurden noch keine Runden / Scans aufgezeichnet ...", "nachname_des_sponsors": "Nachname des Sponsors",
"no_laps_scans_were_recorded_yet": "Noch keine Runden aufgezeichnet ...",
"no_sponsorings_for_you_were_recorded_yet": "Es gibt noch keine Sponsorings für dich",
"not_registered_yet": "Noch nicht registriert?",
"organization": "Organisation",
"ort": "Ort", "ort": "Ort",
"phone_number": "Telefonnummer", "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",
"privacy_policy": "Datenschutzerklärung", "privacy_policy": "Datenschutzerklärung",
"profil_konnte_nicht_geladen_werden": "Profil konnte nicht geladen werden...",
"profil_konnte_nicht_geloescht_werden": "Profil konnte nicht gelöscht werden...",
"profil_wird_geloescht": "Profil wird gelöscht...",
"profile": "Profil", "profile": "Profil",
"provide_address": "Adresse angeben?", "provide_address": "Adresse angeben?",
"register": { "register": {
"register_now": "Jetzt für den Lauf für Kaya! 2021 registrieren." "register_now": "Jetzt für den LfK! 2025 registrieren."
}, },
"register_now": "Jetzt registrieren!", "register_now": "Jetzt registrieren!",
"register_now_small": "Jetzt registrieren",
"registration_local_phone_nr": "Handynummern ohne Vorwahl werden als deutsche Telefonnummer gewertet",
"registration_running": "Registrierung läuft...",
"registrationcode": "Registrierungscode",
"registrieren": "Registrieren", "registrieren": "Registrieren",
"save_changes": "Änderungen speichern", "registriert": "Registriert",
"registrierungscode_generiert": "Registrierungscode generiert!",
"registrierungscode_wird_generiert": "Registrierungscode wird generiert...",
"resend_the_registration_mail": "Login-Link anfordern",
"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 €)",
"strasse": "Straße", "strasse": "Straße",
"telefonnummer_des_sponsors": "Telefonnummer des Sponsors",
"the_system_is_not_properly_configured_please_contact_the_system_administrator_for_help": "Das System ist nicht richtig konfiguriert. Bitte wenden Sie sich an den Systemadministrator, um Hilfe zu erhalten.", "the_system_is_not_properly_configured_please_contact_the_system_administrator_for_help": "Das System ist nicht richtig konfiguriert. Bitte wenden Sie sich an den Systemadministrator, um Hilfe zu erhalten.",
"this_is_not_a_valid_international_phone_number": "Dies ist keine gültige internationale Telefonnummer", "this_is_not_a_valid_international_phone_number": "Dies ist keine gültige internationale Telefonnummer",
"tos": "AGBs", "total": "Gesamt",
"total_distance": "Gesamt-Distanz",
"urkunde_generiert": "Urkunde generiert!",
"urkunde_konnte_nicht_generiert_werden": "Urkunde konnte nicht generiert werden...",
"urkunde_wird_generiert": "Urkunde wird generiert...",
"view_my_data": "Meine Läuferdaten einsehen", "view_my_data": "Meine Läuferdaten einsehen",
"vorname": "Vorname" "vorname": "Vorname",
"vorname_des_sponsors": "Vorname des Sponsors",
"z_b_1eur_oder_0_50eur": "z.B. 1€ ODER 0,50€"
} }
+49 -7
View File
@@ -1,43 +1,85 @@
{ {
"already_have_an_account": "Already have an account?", "access_is_only_provided_via_your_email_link": "Access is only provided via the link you received upon registration.",
"add_sponsoring": "New Sponsoring",
"alle_daten_geloescht": "all data deleted!",
"already_registered": "already registered...",
"amount_per_kilometer_in_eur": "Amount per kilometer (in €)",
"apartment_suite_etc": "Apartment, suite, etc.", "apartment_suite_etc": "Apartment, suite, etc.",
"buergerlauf": "Public Run",
"cancel_keep_my_data": "Cancel, keep my data",
"configuration_error": "Configuration error", "configuration_error": "Configuration error",
"confirm_delete_all_of_my_data": "Confirm, delete all of my data",
"confirm_personal_data": "I hereby confirm that the above information is complete and correct", "confirm_personal_data": "I hereby confirm that the above information is complete and correct",
"current_total_amount_in_eur": "Current total amount (in €)",
"delete_my_data": "Delete my data",
"distance": "Distance", "distance": "Distance",
"download_certificate": "Download certificate", "download_certificate": "Download certificate",
"download_registrationcode": "Download registrationcode",
"e_mail_adress": "mail address", "e_mail_adress": "mail address",
"go_to_login": "Go To Login", "e_mail_des_sponsors": "E-Mail of the Sponsor",
"error_requesting_the_login_link": "Error requesting the login link...",
"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",
"lap_time": "Lap time", "lap_time": "Lap time",
"lap_times": "Lap times", "lap_times": "Lap times",
"login_link_gesendet_an_user_email_value": "Login-Link sent to ",
"login_link_is_requested": "Login link is requested...",
"lost_your_registration_mail": "Lost your registration mail?",
"main_page_text": "Here you can register for the Lauf Für Kaya! or manage your runner profile.", "main_page_text": "Here you can register for the Lauf Für Kaya! or manage your runner profile.",
"mittelname": "Middlename", "mittelname": "Middlename",
"nachname": "Lastname", "nachname": "Lastname",
"nachname_des_sponsors": "last name of the sponsor",
"no_laps_scans_were_recorded_yet": "No laps/ scans were recorded yet...", "no_laps_scans_were_recorded_yet": "No laps/ scans were recorded yet...",
"no_sponsorings_for_you_were_recorded_yet": "No sponsorings for you were recorded yet...",
"not_registered_yet": "Not registered yet?",
"organization": "Organization", "organization": "Organization",
"ort": "City", "ort": "City",
"phone_number": "Phone Number", "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",
"privacy_policy": "Privacy Policy", "privacy_policy": "Privacy Policy",
"profil_konnte_nicht_geladen_werden": "could not load profile...",
"profil_konnte_nicht_geloescht_werden": "couold not delete profile...",
"profil_wird_geloescht": "deleting profile...",
"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! 2021." "register_now": "Register now for LfK! 2025."
}, },
"register_now": "Register now!", "register_now": "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...",
"registrationcode": "Registration Code",
"registrieren": "Register Now", "registrieren": "Register Now",
"save_changes": "Save changes", "registriert": "Registered",
"registrierungscode_generiert": "created registration code!",
"registrierungscode_wird_generiert": "creating registration code...",
"resend_the_registration_mail": "Send me a login link",
"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 €)",
"strasse": "Street/ Block", "strasse": "Street/ Block",
"telefonnummer_des_sponsors": "Sponsor's phone number",
"the_system_is_not_properly_configured_please_contact_the_system_administrator_for_help": "The system is not properly configured. Please contact the system administrator for help.", "the_system_is_not_properly_configured_please_contact_the_system_administrator_for_help": "The system is not properly configured. Please contact the system administrator for help.",
"this_is_not_a_valid_international_phone_number": "This is not a valid international phone number", "this_is_not_a_valid_international_phone_number": "This is not a valid international phone number",
"tos": "Terms of Service", "total": "Total",
"total_distance": "total distance",
"urkunde_generiert": "created certificate",
"urkunde_konnte_nicht_generiert_werden": "could not create your certificate...",
"urkunde_wird_generiert": "creating certificate...",
"view_my_data": "View my data", "view_my_data": "View my data",
"vorname": "Firstname", "vorname": "Firstname",
"you_have_been_registered": "You have been registered!" "vorname_des_sponsors": "Sponsor's first name",
"z_b_1eur_oder_0_50eur": "e.g. €1 OR €0.50"
} }
+8
View File
@@ -2,6 +2,14 @@ import { createApp } from 'vue';
import './tailwind.css'; import './tailwind.css';
import 'toastify-js/src/toastify.css'; import 'toastify-js/src/toastify.css';
import 'vue-toastification/dist/index.css'; import 'vue-toastification/dist/index.css';
// import '@fontsource/athiti';
import '@fontsource/athiti/200.css';
import '@fontsource/athiti/300.css';
import '@fontsource/athiti/400.css';
import '@fontsource/athiti/500.css';
import '@fontsource/athiti/600.css';
import '@fontsource/athiti/700.css';
//
import App from './App.vue'; import App from './App.vue';
import { routes } from './routes.js'; import { routes } from './routes.js';
import { createRouter, createWebHistory } from 'vue-router'; import { createRouter, createWebHistory } from 'vue-router';
+12 -19
View File
@@ -1,24 +1,17 @@
// import EnvError from './components/EnvError.vue'; import Home from "./views/Home.vue";
import Home from './views/Home.vue'; import Register from "./views/Register.vue";
import Imprint from './views/Imprint.vue'; import Profile from "./views/Profile.vue";
import Privacy from './views/Privacy.vue'; import ProfileNone from "./views/ProfileNone.vue";
import Register from './views/Register.vue';
import Profile from './views/Profile.vue';
import ProfileNone from './views/ProfileNone.vue';
console.log(config); // console.log(config);
/** @type {import('vue-router').RouterOptions['routes']} */ /** @type {import('vue-router').RouterOptions['routes']} */
export const routes = [ export const routes = [
{ path: config.baseurl_selfservice + '', component: Home }, { path: "/", component: Home },
{ path: config.baseurl_selfservice + 'imprint', component: Imprint }, { path: "/register", component: Register },
{ path: config.baseurl_selfservice + 'imprint/', component: Imprint }, { path: "/register/", component: Register },
{ path: config.baseurl_selfservice + 'privacy', component: Privacy }, { path: "/register/:token", component: Register, props: true },
{ path: config.baseurl_selfservice + 'privacy/', component: Privacy }, { path: "/profile", component: Profile },
{ path: config.baseurl_selfservice + 'register', component: Register }, { path: "/profile/", component: ProfileNone },
{ path: config.baseurl_selfservice + 'register/', component: Register }, { path: "/profile/:token", component: Profile, props: true },
{ path: config.baseurl_selfservice + 'register/:token', component: Register, props: true },
{ path: config.baseurl_selfservice + 'profile', component: Profile },
{ path: config.baseurl_selfservice + 'profile/', component: ProfileNone },
{ path: config.baseurl_selfservice + 'profile/:token', component: Profile, props: true }
]; ];
+8 -3
View File
@@ -1,3 +1,8 @@
@import 'tailwindcss/base'; @import "tailwindcss";
@import 'tailwindcss/components'; @custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
@import 'tailwindcss/utilities';
* {
font-family: Athiti;
}
+18 -20
View File
@@ -1,30 +1,28 @@
<template> <template>
<div class="bg-cover bg-fixed m-0 h-screen" style="background-image: url('./background.jpg');"> <div class="bg-cover bg-fixed m-0 h-screen text-white"
<section class="container px-4 py-24 mx-auto"> v-bind:style='{ backgroundImage: "url(" + background_base64 + ")", }'>
<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.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 text-white md:text-6xl md:tracking-tight" Lauf Für Kaya!<br>2025</h1>
>Lauf Für Kaya!</h1> <h2 class="mb-6 text-xl font-bold leading-none tracking-normal md:text-3xl md:tracking-tight">
<p class="px-0 mb-6 text-lg text-gray-100 md:text-xl lg:px-24">Selfservice Portal</p> Selfservice Portal</h2>
<p class="px-0 mb-6 text-md text-gray-100 lg:px-24">{{ $t('main_page_text') }}</p> <p class="px-0 mb-6 text-md lg:px-24 font-medium">{{ $t('main_page_text') }}</p>
<div class="mt-6 sm:flex place-content-center"> <a class="w-full block mx-auto md:w-3/4 px-6 py-3 border border-transparent text-base font-semibold rounded-md text-gray-900 bg-white shadow-sm hover:text-gray-600 focus:outline-none focus:text-gray-600 xl:text-lg xl:py-4"
<a href="/register/">{{ $t('register_now') }}</a>
class="w-full sm:w-auto inline-flex px-6 py-3 border border-transparent text-base font-semibold rounded-md text-gray-900 bg-white shadow-sm hover:text-gray-600 focus:outline-none focus:text-gray-600 transition ease-in-out duration-150 xl:text-lg xl:py-4" <a href="/profile/"
href="./register" class="md:mt-4 mt-2 w-full block mx-auto md:w-3/4 px-6 py-3 text-base font-semibold rounded-md bg-gray-800 shadow-sm hover:bg-gray-700 focus:outline-none focus:bg-gray-700 xl:text-lg xl:py-4 border border-gray-400">{{
>{{ $t('register_now') }}</a> $t('view_my_data') }}</a>
<a
href="./profile"
class="mt-4 sm:ml-4 sm:mt-0 w-full sm:w-auto inline-flex px-6 py-3 border border-transparent text-base font-semibold rounded-md text-white bg-gray-800 shadow-sm hover:bg-gray-700 focus:outline-none focus:bg-gray-700 transition ease-in-out duration-150 xl:text-lg xl:py-4"
>{{ $t('view_my_data') }}</a>
</div>
</div> </div>
</section> </section>
</div> </div>
<Footer /> <div class="p-8">
<Footer />
</div>
</template> </template>
<script setup> <script setup>
import background_base64 from "../assets/background.jpg?inline";
import Footer from "@/components/Footer.vue"; import Footer from "@/components/Footer.vue";
console.log(config);
</script> </script>
-38
View File
@@ -1,38 +0,0 @@
<template>
<section class="container px-4 py-24 mx-auto">
<div class="simplecontent">
<div class="mb-24 text-left md:text-center">
<h1
class="mb-4 text-4xl font-bold leading-tight text-gray-900 dark:text-gray-50 md:text-5xl"
>{{$t('imprint')}}</h1>
</div>
<div class="mx-auto prose" v-html="content"></div>
</div>
</section>
</template>
<style src="../simple.css">
</style>
<script>
import marked from "marked";
export default {
data() {
return {
content: ""
}
},
async beforeMount() {
const browserlocale = ((navigator.languages && navigator.languages[0]) || '').substr(0, 2);
let md = "";
try {
md = await fetch(`/imprint_${browserlocale}.md`);
} catch (error) {
try {
md = await fetch(`/imprint_en.md`);
} catch (error) {
md = "Error loading Imprint";
}
}
this.content = marked(await md.text());
},
}
</script>
-38
View File
@@ -1,38 +0,0 @@
<template>
<section class="container px-4 py-24 mx-auto">
<div class="simplecontent">
<div class="mb-24 text-left md:text-center">
<h1
class="mb-4 text-4xl font-bold leading-tight text-gray-900 dark:text-gray-50 md:text-5xl"
>{{ $t('privacy_policy') }}</h1>
</div>
<div class="mx-auto prose" v-html="content"></div>
</div>
</section>
</template>
<style src="../simple.css">
</style>
<script>
import marked from "marked";
export default {
data() {
return {
content: ""
}
},
async beforeMount() {
const browserlocale = ((navigator.languages && navigator.languages[0]) || '').substr(0, 2);
let md = "";
try {
md = await fetch(`/privacy_${browserlocale}.md`);
} catch (error) {
try {
md = await fetch(`/privacy_en.md`);
} catch (error) {
md = "Error loading Privacy Policy";
}
}
this.content = marked(await md.text());
},
}
</script>
+651 -208
View File
@@ -1,209 +1,652 @@
<template> <template>
<div class="min-h-screen w-full p-4"> <div class="w-full p-4 lg:px-48 xl:w-2/3 xl:mx-auto">
<section class="text-white body-font"> <div class="md:pr-10 md:mb-0 mb-6 pr-0 w-full text-center text-black dark:text-gray-200">
<div class="container mx-auto flex items-center md:flex-row flex-col"> <img src="/favicon-lfk.png" class="h-20 mx-auto" />
<div <div v-if="loadstate === 'loaded'">
class="flex flex-col md:pr-10 md:mb-0 mb-6 pr-0 w-full md:w-auto md:text-left text-center text-black dark:text-gray-200" <h1 class="text-3xl font-bold whitespace-nowrap" v-text="(state.firstname || '') +
> ' ' +
<p (state.middlename || '') +
class="text-3xl font-bold whitespace-nowrap" ' ' +
v-text="(state.firstname || '') + ' ' + (state.middlename || '') + ' ' + (state.lastname || '')" (state.lastname || '')
></p> "></h1>
<p class="text-md whitespace-nowrap">{{ 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>
<div class="inline-flex md:ml-auto md:mr-0 mx-auto items-center"> </div>
<button <h1 v-else class="text-3xl font-bold whitespace-nowrap">Daten werden geladen...</h1>
type="button" </div>
class="focus:border-black focus:ring-2 focus:ring-black text-white text-sm py-2.5 px-5 rounded-md bg-blue-500 hover:bg-blue-600 hover:shadow-lg" <div v-if="loadstate === 'loaded'" class="flex flex-wrap">
> <div class="w-full">
<svg <div class="">
xmlns="http://www.w3.org/2000/svg" <div class="grid grid-cols-3 text-center gap-1">
width="24" <button @click="() => {
height="24" state.activetab = 'profile';
viewBox="0 0 24 24" }
fill="none" " :class="{
stroke="currentColor" 'tab-active font-medium bg-blue-600 hover:bg-blue-700 text-white':
stroke-width="2" state.activetab === 'profile',
stroke-linecap="round" 'bg-neutral-200':
stroke-linejoin="round" state.activetab !== 'profile',
class="feather feather-download" }" class="cursor-pointer rounded-md p-2 py-3 md:py-4 md:px-6 block" type="button">
style="display: inline;height: 1rem;vertical-align: sub;" {{ $t("profile") }}
> </button>
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /> <button @click="() => {
<polyline points="7 10 12 15 17 10" /> state.activetab = 'laptimes';
<line x1="12" y1="15" x2="12" y2="3" /> }
</svg> " :class="{
{{ $t('download_certificate') }} 'tab-active font-medium bg-blue-600 hover:bg-blue-700 text-white':
</button> state.activetab === 'laptimes',
</div> 'bg-neutral-200':
</div> state.activetab !== 'laptimes',
</section> }" class="cursor-pointer rounded-md p-2 py-3 md:py-4 md:px-6 block" type="button">
<div class="flex flex-wrap"> {{ $t("lap_times") }}
<div class="w-full p-4"> </button>
<div class="flex flex-wrap flex-col w-full tabs"> <button @click="() => {
<div class="flex lg:flex-wrap flex-row lg:space-x-2"> state.activetab = 'sponsorings';
<div class="flex-none"> }
<button " :class="{
@click="() => { state.activetab = 'profile' }" 'tab-active font-medium bg-blue-600 hover:bg-blue-700 text-white':
:class="{ 'tab-active border-b-2 font-medium border-blue-500': (state.activetab === 'profile') }" state.activetab === 'sponsorings',
class="tab tab-underline py-4 px-6 block" 'bg-neutral-200':
type="button" state.activetab !== 'sponsorings',
>{{ $t('profile') }}</button> }" class="cursor-pointer rounded-md p-2 py-3 md:py-4 md:px-6 block" type="button">
</div> {{ $t("sponsoring") }}
<div class="flex-none"> </button>
<button </div>
@click="() => { state.activetab = 'laptimes' }" <div v-if="state.activetab === 'profile'" class="tab-content block">
:class="{ 'tab-active border-b-2 font-medium border-blue-500': (state.activetab === 'laptimes') }" <div class="w-full mx-auto">
class="tab tab-underline py-4 px-6 block" <div class="flex flex-col">
type="button" <div class="flex flex-wrap w-full">
>{{ $t('lap_times') }}</button> <div class="w-full">
</div> <div v-if="state.delete_active === false">
<div class="flex-none"> <button type="button"
<button 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"
@click="() => { state.activetab = 'sponsorings' }" @click="get_certificate">
:class="{ 'tab-active border-b-2 font-medium border-blue-500': (state.activetab === 'sponsorings') }" <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
class="tab tab-underline py-4 px-6 block" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
type="button" class="inline-block">
>{{ $t('sponsoring') }}</button> <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
</div> <polyline points="7 10 12 15 17 10" />
</div> <line x1="12" x2="12" y1="15" y2="3" />
<div v-if="(state.activetab === 'profile')" class="tab-content block"> </svg>
<div class="py-4 w-full"> {{ $t("download_certificate") }}
<div class="flex flex-col"> </button>
<form class="form flex flex-wrap w-full">
<div class="w-full"> </div>
<div class="form-element"> <div>
<div class="text-lg">{{ $t('vorname') }}</div> <div class="text-lg">{{ $t("registrationcode") }}</div>
<p <img class="w-full md:w-auto mb-2 bg-white p-2" alt="Registrierungscode" :src="state.barcode" />
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" <button type="button"
v-text="state.firstname" 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">
</div> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
<div class="form-element"> stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
<div class="text-lg">{{ $t('mittelname') }}</div> class="inline-block">
<p <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" <polyline points="7 10 12 15 17 10" />
v-text="state.middlename" <line x1="12" x2="12" y1="15" y2="3" />
/> </svg>
</div> {{ $t("download_registrationcode") }}
<div class="form-element"> </button>
<div class="text-lg">{{ $t('nachname') }}</div> </div>
<p <div class="mb-2">
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" <div class="text-lg">{{ $t("e_mail_adress") }}</div>
v-text="state.lastname" <p v-text="state.email || '---'" />
/> </div>
</div> <div class="mb-2">
<div class="form-element"> <div class="text-lg">{{ $t("phone_number") }}</div>
<div class="text-lg">{{ $t('e_mail_adress') }}</div> <p v-text="state.phone || '---'" />
<p </div>
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" </div>
v-text="state.email" </div>
/> </div>
</div> <div v-if="state.delete_active === true">
<div class="form-element"> <button type="button"
<div class="text-lg">{{ $t('phone_number') }}</div> 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"
<p @click="() => {
class="h-10 w-full dark:bg-gray-800 rounded text-base outline-none dark:text-gray-100 text-gray-600 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" state.delete_active = false;
v-text="state.phone" }
/> ">
</div> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
</div> stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
</form> class="inline-block">
</div> <circle cx="12" cy="12" r="10" />
</div> <path d="m4.9 4.9 14.2 14.2" />
</div> </svg>
<div v-if="(state.activetab === 'laptimes')" class="tab-content block"> {{ $t("cancel_keep_my_data") }}
<div class="py-4 w-full"> </button>
<section class="text-gray-400 dark:bg-gray-900 body-font"> <button type="button"
<div class="container mx-auto"> 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"
<div class="lg:w-2/3 w-full mx-auto overflow-auto"> @click="delete_me">
<table <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
v-if="state.scans.length > 0" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="table-auto w-full text-left whitespace-no-wrap" class="inline-block">
> <path d="M3 6h18" />
<thead <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
class="text-black bg-gray-300 dark:text-white text-sm dark:bg-gray-800" <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
> <line x1="10" x2="10" y1="11" y2="17" />
<tr> <line x1="14" x2="14" y1="11" y2="17" />
<th </svg>
class="px-4 py-3 title-font tracking-wider font-medium" {{ $t("confirm_delete_all_of_my_data") }}
>{{ $t('distance') }}</th> </button>
<th </div>
class="px-4 py-3 title-font tracking-wider font-medium" <button v-else type="button"
>{{ $t('lap_time') }}</th> 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"
</tr> @click="() => {
</thead> state.delete_active = true;
<tbody class="text-gray-900 dark:text-gray-50"> }
<tr v-for="s in state.scans" :key="s.id"> ">
<td class="px-4 py-3"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
<span v-text="s.distance"></span>m stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
</td> class="inline-block">
<td class="px-4 py-3" v-text="s.lapTime"></td> <path d="M3 6h18" />
</tr> <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
</tbody> <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
</table> <line x1="10" x2="10" y1="11" y2="17" />
<div v-else class="text-center font-bold text-black dark:text-white text-2xl"> <line x1="14" x2="14" y1="11" y2="17" />
<img </svg>
src="../assets/empty_laps.svg" {{ $t("delete_my_data") }}
style="height:25rem; margin:0 auto;" </button>
:alt="[[$t('no_laps_scans_were_recorded_yet')]]" </div>
/> </div>
{{ $t('no_laps_scans_were_recorded_yet') }} </div>
</div> <div v-if="state.activetab === 'laptimes'" class="tab-content block">
</div> <div class="py-4 w-full">
</div> <section class="dark:bg-gray-900 body-font">
</section> <div class="mx-auto">
</div> <div class="w-full mx-auto">
</div> <div v-if="state.scans.length > 0">
<div v-if="(state.activetab === 'sponsorings')" class="tab-content block"> <p class="mb-2">
<div class="py-4 w-full">coming soon...</div> {{ $t('total_distance') }}: {{ getReadableDistanceForUI() }}
</div> </p>
</div>
</div> <table class="table-auto w-full text-left whitespace-no-wrap">
</div> <thead class="
</div> text-black
</template> bg-gray-300
dark:text-white
<script setup> text-sm
import { reactive } from "vue"; dark:bg-gray-800
import { useToast } from "vue-toastification"; ">
import axios from "redaxios"; <tr>
<th class="
const state = reactive({ px-4
phone: "", py-3
email: "", title-font
firstname: "", tracking-wider
middlename: "", font-medium
lastname: "", ">
scans: [], {{ $t("distance") }}
group: "", </th>
activetab: "profile", <th class="
}) px-4
const toast = useToast(); py-3
const props = defineProps({ title-font
token: String tracking-wider
}) font-medium
const accesstoken = atob(props.token); ">
axios.get(`${config.baseurl_selfservice}/api/runners/me/${accesstoken}`) {{ $t("lap_time") }}
.then(({ data }) => { </th>
state.phone = data.phone; </tr>
state.email = data.email; </thead>
state.firstname = data.firstname; <tbody class="text-gray-900 dark:text-gray-50">
state.middlename = data.middlename; <tr v-for="s in state.scans" :key="s.id">
state.lastname = data.lastname; <td class="px-4 py-3">
state.group = data.group; <span v-text="s.distance_readable"></span>
}).catch((error) => { </td>
toast.error("An error occured while loading your profile data"); <td class="px-4 py-3" v-text="s.lapTime_readable"></td>
}) </tr>
axios.get(`${config.baseurl}api/runners/me/${accesstoken}/scans`) </tbody>
.then(({ data }) => { </table>
data.map(function(s) { </div>
s.lapTime = Math.floor(s.lapTime / 60) + 'min ' + (Math.floor(s.lapTime % 60) + "").padStart(2, "0") + "s" <div v-else class="
return s; text-center
}) font-medium
data.filter(s => s.valid === true); text-black
state.scans = data; dark:text-white
}).catch((error) => { text-xl
toast.error("An error occured while loading your profile data"); ">
}) <img src="../assets/empty_laps.svg" class="mx-auto h-56"
:alt="[[$t('no_laps_scans_were_recorded_yet')]]" />
{{ $t("no_laps_scans_were_recorded_yet") }}
</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>
<!-- End Checkbox -->
<button :disabled="!newsponsor_check" @click="addSponsoring" type="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 cursor-pointer">
{{ $t('add_sponsoring') }}
</button>
</div>
<div v-else>
<div class="py-4 w-full">
<section class="dark:bg-gray-900 body-font">
<div class="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">
<thead class="
text-black
bg-gray-300
dark:text-white
text-sm
dark:bg-gray-800
">
<tr>
<th class="
px-4
py-3
title-font
tracking-wider
font-medium
">
Name
</th>
<th class="
px-4
py-3
title-font
tracking-wider
font-medium
">
{{ $t("amount_per_kilometer_in_eur") }}
</th>
<th class="
px-4
py-3
title-font
tracking-wider
font-medium
">
{{ $t("current_total_amount_in_eur") }}
</th>
</tr>
</thead>
<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"
v-for="s in state.sponsorings" :key="s.id">
<td class="px-4 py-3">
<span v-text="s.donor.firstname + ' '"></span>
<span v-if="s.donor.middlename">
<span v-text="s.donor.middlename"></span>
</span>
<span v-text="s.donor.lastname"></span>
</td>
<td class="px-4 py-3">
<span v-text="(s.amountPerDistance / 100)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })
"></span>€
</td>
<td class="px-4 py-3">
<span v-text="(s.amount / 100)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })
"></span>€
</td>
</tr>
</tbody>
<tfoot class="text-black
bg-gray-300
border-t-2
border-t-current
dark:text-white
text-sm
dark:bg-gray-800">
<tr>
<td class="px-4 py-3">{{ $t("total") }}</td>
<td class="px-4 py-3">
<span v-text="(
state.sponsorings.reduce(function (
sum,
current
) {
return sum + current.amountPerDistance;
},
0) / 100
)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })
"></span>€
</td>
<td class="px-4 py-3">
<span v-text="(
state.sponsorings.reduce(function (
sum,
current
) {
return sum + current.amount;
},
0) / 100
)
.toFixed(2)
.toLocaleString('de-DE', { valute: 'EUR' })
"></span>€
</td>
</tr>
</tfoot>
</table>
<div v-else class="
text-center
font-medium
text-black
dark:text-white
text-xl
">
<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") }}
</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>
</section>
</div>
</div>
</div>
</div>
</div>
<!-- -->
<Footer />
</div>
</template>
<script setup>
import Footer from "@/components/Footer.vue";
import { runnerSelfServiceControllerGet, runnerSelfServiceControllerGetScans, runnerSelfServiceControllerRemove } from "@odit/lfk-client";
import { toCanvas } from "bwip-js";
import axios from "redaxios";
import { reactive, ref } from "vue";
import { useI18n } from 'vue-i18n';
import { TYPE, useToast } from "vue-toastification";
const { t } = useI18n()
const 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) {
const canvas = document.createElement("canvas");
let codeconfig = {
bcid: config.code_format || "code128",
text: `${text}`,
scale: 3,
includetext: false,
textxalign: "center",
backgroundcolor: "ffffff",
};
if (
codeconfig.bcid === "code39" ||
codeconfig.bcid === "code128" ||
codeconfig.bcid === "ean13"
) {
codeconfig.height = 10;
}
toCanvas(canvas, codeconfig);
return canvas.toDataURL("image/png");
}
const state = reactive({
barcode: "",
phone: "",
email: "",
firstname: "",
middlename: "",
lastname: "",
scans: [],
sponsorings: [],
group: "",
activetab: "profile",
delete_active: false,
fullobject: {},
});
const toast = useToast();
const props = defineProps({
token: String,
});
const accesstoken = props.token;
function getReadableDistanceForUI() {
return state.scans.reduce((accumulator, currentValue) => accumulator + currentValue.distance, 0)
}
function getReadableDistance(distance) {
const km = Math.floor(distance / 1000)
const m = Math.floor(distance % 1000)
console.log({ km, m });
if (km > 0) {
return `${km},${m} km`
}
return `${m} m`
}
runnerSelfServiceControllerGet({ path: { jwt: accesstoken } }).then(({ data }) => {
loadstate.value = "loaded"
state.phone = data.phone;
state.email = data.email;
state.firstname = data.firstname;
state.middlename = data.middlename;
state.lastname = data.lastname;
state.group = data.group;
state.sponsorings = data.distanceDonations;
state.fullobject = data;
state.barcode = textToBase64Barcode(data.id ?? "???");
})
.catch((error) => {
loadstate.value = "error"
toast.clear();
toast.error(t('profil_konnte_nicht_geladen_werden'));
});
runnerSelfServiceControllerGetScans({ path: { jwt: accesstoken } }).then(({ data }) => {
let counter = 0
data = data.filter((s) => s.valid === true);
data.map(function (s) {
if (counter === 0) {
s.lapTime_readable = t('first_lap')
} else {
s.lapTime_readable =
Math.floor(s.lapTime / 60) +
"min " +
(Math.floor(s.lapTime % 60) + "").padStart(2, "0") +
"s";
}
s.distance_readable = getReadableDistance(s.distance);
counter++;
return s;
});
state.scans = data;
})
.catch((error) => {
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() {
toast.clear();
toast(t('profil_wird_geloescht'));
runnerSelfServiceControllerRemove({
path: {
jwt: accesstoken
}, query: { force: true }
}).then(() => {
toast.clear();
toast(t('alle_daten_geloescht'));
location.replace(`/`);
})
.catch((error) => {
toast.clear();
toast.error(t('profil_konnte_nicht_geloescht_werden'));
});
}
function get_certificate() {
toast(t('urkunde_wird_generiert'));
const browserlocale = (
(navigator.languages && navigator.languages[0]) ||
""
).substr(0, 2);
let url = `${config.baseurl_documentserver}/v1/pdfs/certificates?key=${config.documentserver_key}`;
let postdata = {
locale: browserlocale,
runners: [
{
first_name: state.firstname,
middle_name: state.middlename,
last_name: state.lastname,
id: state.fullobject.id,
distance: state.fullobject.distance,
self_service_link: window.location.href,
group: {
name: state.group,
id: state.fullobject.group.id || 0,
},
distance_donations: state.fullobject.distanceDonations.map((s) => {
return {
id: s.id || 0,
amount: s.amount,
amount_per_distance: s.amountPerDistance,
donor: {
id: s.donor.id || 0,
first_name: s.donor.firstname,
middle_name: s.donor.middlename,
last_name: s.donor.lastname,
},
};
}),
}
]
};
axios
.post(url, postdata, {
responseType: "blob",
})
.then((response) => {
console.log(response);
if (response.status !== 200) {
toast.error(t('urkunde_konnte_nicht_generiert_werden'));
} else {
var fileURL = window.URL.createObjectURL(
new Blob([response.data], { type: "application/pdf" })
);
var fileLink = document.createElement("a");
fileLink.href = fileURL;
fileLink.setAttribute("download", "Certificate.pdf");
document.body.appendChild(fileLink);
fileLink.click();
fileLink.remove();
toast.clear();
toast(t('urkunde_generiert'), { type: TYPE.SUCCESS });
}
})
.catch((err) => {
console.error(err);
toast.clear();
toast.error(t('urkunde_konnte_nicht_generiert_werden'));
});
}
function get_registration() {
// toast.clear();
// toast(t('registrierungscode_wird_generiert'));
var a = document.createElement("a");
a.href = state.barcode;
a.download = `LfK25_Registrierungscode_${state.firstname}_${state.lastname}.png`;
a.click();
// toast.clear();
// toast(t('registrierungscode_generiert'), { type: TYPE.SUCCESS });
}
</script> </script>
+92 -1
View File
@@ -1 +1,92 @@
<template>You have not provided a valid access key...</template> <template>
<div class="min-h-screen flex items-center justify-center">
<div class="max-w-md w-full py-12 px-6">
<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! - {{
$t('profile')
}}</h1>
<p class="mx-auto leading-relaxed text-base text-center">
{{ $t('access_is_only_provided_via_your_email_link') }}
</p>
<div class="mt-6">
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white dark:bg-gray-900">{{ $t('lost_your_registration_mail') }}</span>
</div>
</div>
<div class="mt-4">
<label for="email_address" class="block font-medium">
{{ $t('e_mail_adress') }}
<span class="font-bold">*</span>
</label>
<input v-model="user_email" name="email_address" id="email_address" autocomplete="email"
:placeholder="[[$t('e_mail_adress')]]" type="email"
:class="{ 'border-red-500': (!isEmail(user_email)), 'border-green-300': (isEmail(user_email)) }"
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">{{
$t('please_provide_valid_mail')
}}</p>
</div>
<div class="mt-2">
<button :disabled="(!state.submit_enabled)"
:class="{ 'opacity-50': (!state.submit_enabled), 'cursor-not-allowed': (!state.submit_enabled) }"
@click="resendMail"
class="block w-full text-center py-2 px-3 border-2 border-gray-300 rounded-md p-1 dark:bg-gray-800 font-medium hover:border-gray-400 focus:outline-none focus:border-gray-400 sm:text-sm">{{
$t('resend_the_registration_mail') }}</button>
</div>
</div>
<div class="mt-12">
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white dark:bg-gray-900">{{ $t('not_registered_yet') }}</span>
</div>
</div>
<div class="mt-2">
<a href="/register/"
class="text-white block w-full text-center py-2 px-3 border-2 border-gray-300 rounded-md p-1 bg-blue-800 font-medium hover:border-gray-400 focus:outline-none focus:border-gray-400 sm:text-sm">{{
$t('register_now_small') }}</a>
</div>
</div>
</div>
</div>
<Footer />
</template>
<script setup>
import Footer from "@/components/Footer.vue";
import { runnerSelfServiceControllerRequestNewToken } from "@odit/lfk-client";
import isEmail from 'validator/es/lib/isEmail';
import { computed, reactive, ref } from "vue";
import { useI18n } from 'vue-i18n';
import { TYPE, useToast } from "vue-toastification";
const { t } = useI18n()
let user_email = ref("");
//
const state = reactive({
org_name: "",
org_teams: [],
submit_enabled: computed(() => isEmail(user_email.value))
})
const toast = useToast();
function resendMail() {
if (isEmail(user_email.value)) {
toast(t('login_link_is_requested'));
const browserlocale = ((navigator.languages && navigator.languages[0]) || '').substr(0, 2);
runnerSelfServiceControllerRequestNewToken({ query: { locale: browserlocale, mail: user_email.value } }).then(({ data }) => {
console.log(data);
toast(t('login_link_gesendet_an_user_email_value') + user_email.value);
})
.catch((error) => {
console.log(error);
toast(t('error_requesting_the_login_link'), { type: TYPE.ERROR });
});
}
}
</script>
+492 -337
View File
@@ -1,338 +1,493 @@
<template> <template>
<div class="min-h-screen flex items-center justify-center"> <div class="min-h-screen flex items-center justify-center" v-if="registrationState === 'registered'">
<div class="max-w-md w-full py-12 px-6"> <div class="max-w-md w-full py-6 px-6">
<img class="mx-auto h-24 w-auto" src="/favicon.png" alt /> <img class="mx-auto h-24 w-auto" src="/favicon-lfk.png" alt />
<h1 <h1 class="sm:text-3xl text-2xl font-semibold title-font mb-4 text-center">
class="sm:text-3xl text-2xl font-medium title-font mb-4 text-center" Lauf für Kaya! - {{ $t('registriert') }}
>Lauf für Kaya! - {{ $t('registrieren') }}</h1> </h1>
<p class="mx-auto leading-relaxed text-base text-center">{{ $t('register.register_now') }}</p> <p class="mx-auto leading-relaxed text-base text-center">
<p Bitte klicken Sie zum Fortfahren auf den Link, den wir an
v-if="state.org_name !== ''" <b class="font-bold">{{ userdetails.mail }}</b> geschickt haben.
class="mx-auto leading-relaxed text-base text-center" </p>
>{{ $t('organization') }}: {{ state.org_name }}</p> </div>
<p </div>
v-if="state.org_name !== '' && state.org_teams.length > 0" <div class="min-h-screen flex items-center justify-center" v-else>
class="mx-auto leading-relaxed text-base text-center" <div class="max-w-md w-full py-6 px-6">
>Team:</p> <img class="mx-auto h-24 w-auto" src="/favicon-lfk.png" alt />
<select <h1 class="sm:text-3xl text-2xl font-semibold title-font text-center">
v-model="org_team" Lauf für Kaya!
v-if="state.org_name !== '' && state.org_teams.length > 0" </h1>
class="w-full border bg-white rounded px-3 py-2 outline-none block mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-select focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray" <p class="mx-auto leading-relaxed text-lg text-center font-medium mb-4">
> {{ $t("register.register_now") }}
<option v-for="t in state.org_teams" :key="t.id" :value="t.id">{{ t.name }}</option> </p>
</select> <div v-if="state.org_name !== ''" class="w-full text-center">
<p <span
v-if="state.org_name === ''" 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>
class="mx-auto leading-relaxed text-base text-center" </div>
>Bürgerlauf</p> <label v-if="state.org_name !== '' && state.org_teams.length > 0" for="select_team" class="block font-semibold mt-2">
<div class="mt-4"> Team:
<label for="first_name" class="block font-medium"> </label>
{{ $t('vorname') }} <select id="select_team" v-model="org_team" v-if="state.org_name !== '' && state.org_teams.length > 0" class="
<span class="font-bold">*</span> w-full
</label> border-2
<input bg-white
v-model="userdetails.firstname" rounded-md
name="firstname" px-3
id="first_name" py-2
autocomplete="off" outline-none
:placeholder="[[$t('vorname')]]" block
type="text" mt-1
:class="{ 'border-red-500': (!userdetails.firstname.trim()), 'border-green-300': (userdetails.firstname.trim()) }" text-sm
class="dark:bg-gray-800 mt-1 block w-full shadow-sm sm:text-sm border-gray-300 border-2 bg-gray-50 text-gray-500 rounded-md p-2" dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700
/> form-select
<!-- --> focus:border-purple-400 focus:outline-none focus:shadow-outline-purple
<label for="middle_name" class="block font-medium">{{ $t('mittelname') }}</label> dark:focus:shadow-outline-gray
<input ">
v-model="userdetails.middlename" <option v-for="t in state.org_teams" :key="t.id" :value="t.id">
name="middlename" {{ t.name }}
id="middle_name" </option>
autocomplete="off" </select>
:placeholder="[[$t('mittelname')]]" <div v-if="state.org_name === ''" class="w-full text-center">
type="text" <span
class="dark:bg-gray-800 mt-1 block w-full shadow-sm sm:text-sm border-gray-300 border-2 bg-gray-50 text-gray-500 rounded-md p-2" class="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>
<label for="last_name" class="block font-medium"> <div class="mt-4">
{{ $t('nachname') }} <label for="first_name" class="block font-semibold mt-2">
<span class="font-bold">*</span> {{ $t("vorname") }}
</label> <span class="font-bold">*</span>
<input </label>
v-model="userdetails.lastname" <input v-model="userdetails.firstname" name="firstname" id="first_name" autocomplete="off"
name="lastname" :placeholder="[[$t('ihr_vorname')]]" type="text" :class="{
id="last_name" '': !userdetails.firstname.trim(),
autocomplete="off" 'border-green-300': userdetails.firstname.trim(),
:placeholder="[[$t('nachname')]]" }" class="
type="text" dark:bg-gray-800
:class="{ 'border-red-500': (!userdetails.lastname.trim()), 'border-green-300': (userdetails.lastname.trim()) }" block
class="dark:bg-gray-800 mt-1 block w-full shadow-sm sm:text-sm border-gray-300 border-2 bg-gray-50 text-gray-500 rounded-md p-2" w-full
/> shadow-sm
<!-- --> sm:text-sm
<label for="email_address" class="block font-medium"> border-2 placeholder:text-gray-800
{{ $t('e_mail_adress') }} bg-gray-50
<span class="font-bold">*</span> text-gray-500
</label> rounded-md
<input p-2
v-model="userdetails.mail" " />
name="email_address" <!-- -->
id="email_address" <label for="last_name" class="block font-semibold mt-2">
autocomplete="off" {{ $t("nachname") }}
:placeholder="[[$t('e_mail_adress')]]" <span class="font-bold">*</span>
type="email" </label>
:class="{ 'border-red-500': (!isEmail(userdetails.mail)), 'border-green-300': (isEmail(userdetails.mail)) }" <input v-model="userdetails.lastname" name="lastname" id="last_name" autocomplete="off"
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" :placeholder="[[$t('ihr_nachname')]]" type="text" :class="{
/> '': !userdetails.lastname.trim(),
<p v-if="!isEmail(userdetails.mail)" class="text-sm">{{ $t('please_provide_valid_mail') }}</p> 'border-green-300': userdetails.lastname.trim(),
<!-- --> }" class="
<label for="phone" class="select-none block font-medium">{{ $t('phone_number') }}</label> dark:bg-gray-800
<input block
v-model="userdetails.phone" w-full
name="phone" shadow-sm
id="phone" sm:text-sm
autocomplete="off" border-2 placeholder:text-gray-800
:placeholder="[[$t('phone_number')]]" bg-gray-50
type="text" text-gray-500
:class="{ 'border-red-500': (!isMobilePhone(userdetails.phone) && userdetails.phone.trim()), 'border-green-300': (isMobilePhone(userdetails.phone) && userdetails.phone.trim()) }" rounded-md
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-2
/> " />
<p <!-- -->
v-if="(!isMobilePhone(userdetails.phone) && userdetails.phone.trim())" <label for="email_address" class="block font-semibold mt-2">
class="text-sm" {{ $t("e_mail_adress") }}
>{{ $t('this_is_not_a_valid_international_phone_number') }}</p> <span class="font-bold">*</span>
<!-- --> </label>
<div class="grid grid-cols-6 mt-6"> <input v-model="userdetails.mail" name="email_address" id="email_address" autocomplete="off"
<div class="col-span-6"></div> :placeholder="[[$t('ihre_e_mail_adresse')]]" type="email" :class="{
<div class="flex items-start col-span-6"> '': !isEmail(userdetails.mail),
<div class="flex items-center h-5"> 'border-green-300': isEmail(userdetails.mail),
<input }" class="
v-model="provide_address" dark:bg-gray-800
id="address_activated" block
name="address_activated" w-full
type="checkbox" shadow-sm
class="h-4 w-4 text-indigo-600 border-gray-300 rounded" sm:text-sm
/> border-2 placeholder:text-gray-800
</div> bg-gray-50
<div class="ml-3 text-sm"> text-gray-500
<label rounded-md
for="address_activated" p-2
class="font-medium text-gray-400 select-none" " />
>{{ $t('provide_address') }}</label> <p v-if="userdetails.mail !== '' && !isEmail(userdetails.mail)" class="text-sm">
</div> {{ $t("please_provide_valid_mail") }}
</div> </p>
<div v-if="provide_address === true" class="col-span-6"> <!-- -->
<div class="col-span-6"> <label for="phone" class="block font-semibold mt-2">{{
<label for="street" class="block font-medium"> $t("phone_number")
{{ $t('strasse') }} }}</label>
<span class="font-bold">*</span> <div v-if="userdetails.phone !== '' && !userdetails.phone.includes('+')"
</label> class="bg-blue-100 border border-blue-200 text-black rounded-lg p-4 mb-1" role="alert" tabindex="-1"
<input aria-labelledby="hs-actions-label">
v-model="userdetails.address.street" <div class="flex">
type="text" <div class="shrink-0">
name="street" <svg class="shrink-0 size-4 mt-1" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
:placeholder="[[$t('strasse')]]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
id="street" stroke-linejoin="round">
autocomplete="street-address" <circle cx="12" cy="12" r="10"></circle>
:class="{ 'border-red-500': (!userdetails.address.street.trim()), 'border-green-300': (userdetails.address.street.trim()) }" <path d="M12 16v-4"></path>
class="dark:bg-gray-800 mt-1 block w-full shadow-sm sm:text-sm border-gray-300 border-2 bg-gray-50 text-gray-500 rounded-md p-2" <path d="M12 8h.01"></path>
/> </svg>
</div> </div>
<div class="col-span-6"> <div class="ms-3">
<label for="address2" class="block font-medium">{{ $t('apartment_suite_etc') }}</label> <h3 id="hs-actions-label" class="font-semibold">
<input {{ $t('hinweis') }}
v-model="userdetails.address.address2" </h3>
type="text" <div class="mt-2 text-sm text-gray-800 font-medium">
name="address2" {{ $t('registration_local_phone_nr') }}
:placeholder="[[$t('apartment_suite_etc')]]" </div>
id="address2" </div>
autocomplete="street-address" </div>
class="dark:bg-gray-800 mt-1 block w-full shadow-sm sm:text-sm border-gray-300 border-2 bg-gray-50 text-gray-500 rounded-md p-2" </div>
/> <input v-model="userdetails.phone" name="phone" id="phone" autocomplete="off"
</div> :placeholder="[[$t('geben_sie_ihre_handynummer_an')]]" type="text" :class="{
<div class="col-span-6 sm:col-span-6 lg:col-span-2"> '':
<label for="city" class="block font-medium"> userdetails.phone === '',
{{ $t('ort') }} 'border-red-300':
<span class="font-bold">*</span> !isPhoneOkay(),
</label> }" class="
<input dark:bg-gray-800
v-model="userdetails.address.city" block
type="text" w-full
name="city" shadow-sm
:placeholder="[[$t('ort')]]" sm:text-sm
id="city" border-2 placeholder:text-gray-800
:class="{ 'border-red-500': (!userdetails.address.city.trim()), 'border-green-300': (userdetails.address.city.trim()) }" bg-gray-50
class="dark:bg-gray-800 mt-1 block w-full shadow-sm sm:text-sm border-gray-300 border-2 bg-gray-50 text-gray-500 rounded-md p-2" text-gray-500
/> rounded-md
</div> p-2
<div class="col-span-6 sm:col-span-3 lg:col-span-2"> " />
<label for="postal_code" class="block font-medium"> <p v-if="!isPhoneOkay()" class="text-sm">
{{ $t('plz') }} {{ $t("this_is_not_a_valid_international_phone_number") }}
<span class="font-bold">*</span> </p>
</label> <!-- -->
<input <div class="grid grid-cols-6 mt-6">
v-model="userdetails.address.zipcode" <div class="col-span-6"></div>
type="text" <div class="flex items-start col-span-6">
name="postal_code" <div class="flex items-center h-5">
:placeholder="[[$t('plz')]]" <input v-model="provide_address" id="address_activated" name="address_activated" type="checkbox"
id="postal_code" class="h-4 w-4 text-indigo-600 border-gray-300 rounded" />
autocomplete="postal-code" </div>
:class="{ 'border-red-500': (!isPostalCode(userdetails.address.zipcode, 'DE')), 'border-green-300': (isPostalCode(userdetails.address.zipcode, 'DE')) }" <div class="ml-3 text-sm">
class="dark:bg-gray-800 mt-1 block w-full shadow-sm sm:text-sm border-gray-300 border-2 bg-gray-50 text-gray-500 rounded-md p-2" <label for="address_activated" class="font-medium text-gray-600 select-none">{{ $t("provide_address")
/> }}</label>
</div> </div>
<p </div>
v-if="!isPostalCode(userdetails.address.zipcode, 'DE')" <div v-if="provide_address === true" class="col-span-6">
class="text-sm" <div class="col-span-6">
>{{ $t('please_provide_a_valid_zipcode') }}</p> <label for="street" class="block font-semibold mt-2">
</div> {{ $t("strasse") }}
</div> <span class="font-bold">*</span>
<div class="flex items-start mt-6"> </label>
<div class="flex items-center h-5"> <input v-model="userdetails.address.street" type="text" name="street" :placeholder="[[$t('strasse')]]"
<input id="street" autocomplete="street-address" :class="{
v-model="agb_accepted" 'border-red-500': !userdetails.address.street.trim(),
id="agb_accepted" 'border-green-300': userdetails.address.street.trim(),
name="agb_accepted" }" class="
type="checkbox" dark:bg-gray-800
class="h-4 w-4 text-indigo-600 border-gray-300 rounded" block
/> w-full
</div> shadow-sm
<div class="ml-3 text-sm"> sm:text-sm
<label for="agb_accepted" class="font-medium text-gray-400 select-none"> border-2 placeholder:text-gray-800
{{ $t('i_accept', { tos: $t('tos') }) }} bg-gray-50
<a text-gray-500
target="_blank" rounded-md
rel="noreferrer,noopener" p-2
href " />
class="underline" </div>
>{{ $t('tos') }}</a> <div class="col-span-6">
{{ $t('i_accept_end') }} <label for="address2" class="block font-semibold mt-2">{{
<span class="font-bold">*</span> $t("apartment_suite_etc")
</label> }}</label>
</div> <input v-model="userdetails.address.address2" type="text" name="address2"
</div> :placeholder="[[$t('apartment_suite_etc')]]" id="address2" autocomplete="street-address" class="
<div class="flex items-start mt-6"> dark:bg-gray-800
<div class="flex items-center h-5"> block
<input w-full
v-model="data_confirmed" shadow-sm
id="data_confirmed" sm:text-sm
name="data_confirmed" border-2 placeholder:text-gray-800
type="checkbox" bg-gray-50
class="h-4 w-4 text-indigo-600 border-gray-300 rounded" text-gray-500
/> rounded-md
</div> p-2
<div class="ml-3 text-sm"> " />
<label for="data_confirmed" class="font-medium text-gray-400 select-none"> </div>
{{ $t('confirm_personal_data') }} <div class="col-span-6 sm:col-span-6 lg:col-span-2">
<span class="font-bold">*</span> <label for="city" class="block font-semibold mt-2">
</label> {{ $t("ort") }}
</div> <span class="font-bold">*</span>
</div> </label>
<div class="mt-6"> <input v-model="userdetails.address.city" type="text" name="city" :placeholder="[[$t('ort')]]" id="city"
<button :class="{
@click="login" 'border-red-500': !userdetails.address.city.trim(),
:disabled="(!state.submit_enabled)" 'border-green-300': userdetails.address.city.trim(),
:class="{ 'opacity-50': (!state.submit_enabled), 'cursor-not-allowed': (!state.submit_enabled) }" }" class="
class="text-white block w-full text-center py-2 px-3 border-2 border-gray-300 rounded-md p-1 bg-blue-800 font-medium hover:border-gray-400 focus:outline-none focus:border-gray-400 sm:text-sm" dark:bg-gray-800
>{{ $t('registrieren') }}</button> block
</div> w-full
</div> shadow-sm
<div class="mt-6"> sm:text-sm
<div class="relative"> border-2 placeholder:text-gray-800
<div class="absolute inset-0 flex items-center"> bg-gray-50
<div class="w-full border-t border-gray-300"></div> text-gray-500
</div> rounded-md
<div class="relative flex justify-center text-sm"> p-2
<span class="px-2 bg-white dark:bg-gray-900">{{ $t('already_have_an_account') }}</span> " />
</div> </div>
</div> <div class="col-span-6 sm:col-span-3 lg:col-span-2">
<div class="mt-6"> <label for="postal_code" class="block font-semibold mt-2">
<a {{ $t("plz") }}
href="./login" <span class="font-bold">*</span>
class="block w-full text-center py-2 px-3 border-2 border-gray-300 rounded-md p-1 dark:bg-gray-800 font-medium hover:border-gray-400 focus:outline-none focus:border-gray-400 sm:text-sm" </label>
>{{ $t('go_to_login') }}</a> <input v-model="userdetails.address.zipcode" type="text" name="postal_code" :placeholder="[[$t('plz')]]"
</div> id="postal_code" autocomplete="postal-code" :class="{
</div> 'border-red-500': !isPostalCode(
</div> userdetails.address.zipcode,
</div> 'DE'
</template> ),
'border-green-300': isPostalCode(
<script setup> userdetails.address.zipcode,
import { computed, ref, reactive, defineProps } from "vue"; 'DE'
import axios from "redaxios"; ),
import isEmail from 'validator/es/lib/isEmail'; }" class="
import isMobilePhone from 'validator/es/lib/isMobilePhone'; dark:bg-gray-800
import isPostalCode from 'validator/es/lib/isPostalCode'; block
import { useToast } from "vue-toastification"; w-full
// import { router } from '../router'; shadow-sm
import { i18n } from '../language'; sm:text-sm
border-2 placeholder:text-gray-800
const props = defineProps({ bg-gray-50
token: String text-gray-500
}) rounded-md
if (props.token) { p-2
axios.get(`${config.baseurl}api/organizations/selfservice/${props.token}`) " />
.then(({ data }) => { </div>
state.org_name = data.name; <p v-if="!isPostalCode(userdetails.address.zipcode, 'DE')" class="text-sm">
state.org_teams = data.teams; {{ $t("please_provide_a_valid_zipcode") }}
org_team.value = data.teams[0]?.id; </p>
}) </div>
.catch((error) => { </div>
console.log(error); <div class="flex items-start mt-6">
}); <div class="flex items-center h-5">
} <input v-model="agb_accepted" id="agb_accepted" name="agb_accepted" type="checkbox"
class="h-4 w-4 text-indigo-600 border-gray-300 rounded" />
let userdetails = ref({ firstname: "", lastname: "", middlename: "", mail: "", phone: "", address: { street: "", address2: "", city: "", zipcode: "" } }); </div>
let provide_address = ref(false); <div class="ml-3 text-sm">
let agb_accepted = ref(false); <label for="agb_accepted" class="font-medium text-gray-600 select-none">
let data_confirmed = ref(false); {{ $t("i_accept", { tos: $t("privacy_policy") }) }}
let org_team = ref(""); <a target="_blank" rel="noreferrer,noopener" href="https://lauf-fuer-kaya.de/datenschutz/"
// class="underline">{{ $t("privacy_policy") }}</a>
const state = reactive({ {{ $t("i_accept_end") }}
org_name: "", <span class="font-bold">*</span>
org_teams: [], </label>
submit_enabled: computed(() => agb_accepted.value === true && data_confirmed.value === true && (isMobilePhone(userdetails.value.phone) || !userdetails.value.phone.trim()) && isEmail(userdetails.value.mail) </div>
&& userdetails.value.firstname </div>
&& userdetails.value.lastname && (provide_address.value === false || provide_address.value === true && (userdetails.value.address.street.trim() && userdetails.value.address.city.trim() && isPostalCode(userdetails.value.address.zipcode, "DE")))) <div class="flex items-start mt-6">
}) <div class="flex items-center h-5">
const toast = useToast(); <input v-model="data_confirmed" id="data_confirmed" name="data_confirmed" type="checkbox"
function login() { class="h-4 w-4 text-indigo-600 border-gray-300 rounded" />
userdetails = userdetails.value; </div>
if (userdetails.phone === "" || isMobilePhone(userdetails.phone)) { <div class="ml-3 text-sm">
if (isEmail(userdetails.mail)) { <label for="data_confirmed" class="font-medium text-gray-600 select-none">
let postdata = { {{ $t("confirm_personal_data") }}
"email": userdetails.mail, <span class="font-bold">*</span>
"firstname": userdetails.firstname, </label>
"middlename": userdetails.middlename, </div>
"lastname": userdetails.lastname, </div>
"address": {} <div class="mt-6">
} <button @click="login" :disabled="!state.submit_enabled" :class="{
if (isMobilePhone(userdetails.phone)) { 'opacity-50': !state.submit_enabled,
postdata.phone = userdetails.phone; 'cursor-not-allowed': !state.submit_enabled,
} }" class="
if (provide_address.value === true) { text-white
postdata.address = { block
address1: userdetails.address.street, w-full
address2: userdetails.address.address2 || "", text-center
city: userdetails.address.city, py-2
postalcode: userdetails.address.zipcode, px-3
country: "DE", border-2 placeholder:text-gray-800 border-gray-300
} rounded-md
} p-1
if (state.org_name !== '' && state.org_teams.length > 0) { bg-blue-800
postdata.team = org_team.value; font-medium
} not-disabled:hover:border-gray-400
toast("registration in progress..."); not-disabled:hover:bg-blue-600
let url = `${config.baseurl}api/runners/register`; not-disabled:cursor-pointer
if (props.token) { not-disabled:focus:outline-none focus:border-gray-400
url = `${config.baseurl}api/runners/register/${props.token}` sm:text-sm
} ">
axios.post(url, postdata) {{ $t("registrieren") }}
.then(({ data }) => { </button>
const token = btoa(data.token); </div>
// router.push(`${config.baseurl_selfservice}/profile/${token}`); </div>
}) </div>
.catch((error) => { </div>
console.log(error); <div class="p-8">
}); <Footer />
} </div>
} </template>
}
<script setup>
import Footer from "@/components/Footer.vue";
import { runnerSelfServiceControllerGetSelfserviceOrg, runnerSelfServiceControllerRegisterOrganizationRunner, runnerSelfServiceControllerRegisterRunner } from "@odit/lfk-client";
import isEmail from "validator/es/lib/isEmail";
import isMobilePhone from "validator/es/lib/isMobilePhone";
import isPostalCode from "validator/es/lib/isPostalCode";
import { computed, reactive, ref } from "vue";
import { useI18n } from 'vue-i18n';
import { TYPE, useToast } from "vue-toastification";
const { t } = useI18n()
const props = defineProps({
token: String,
});
if (props.token) {
runnerSelfServiceControllerGetSelfserviceOrg({ path: { token: props.token } }).then(({ data }) => {
state.org_name = data.name;
state.org_teams = data.teams;
org_team.value = data.teams[0]?.id;
})
.catch((error) => {
console.log(error);
});
}
let userdetails = ref({
firstname: "",
lastname: "",
middlename: "",
mail: "",
phone: "",
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() {
if (userdetails.value.phone === "") {
return true
}
const formattedNumber = formatPhoneNumber(userdetails.value.phone)
if (isMobilePhone(formattedNumber)) {
return true
}
return false
}
let provide_address = ref(false);
let agb_accepted = ref(false);
let data_confirmed = ref(false);
let org_team = ref("");
let registrationState = ref("pending");
//
const state = reactive({
org_name: "",
org_teams: [],
submit_enabled: computed(
() =>
agb_accepted.value === true &&
data_confirmed.value === true &&
isPhoneOkay() &&
isEmail(userdetails.value.mail) &&
userdetails.value.firstname &&
userdetails.value.lastname &&
(provide_address.value === false ||
(provide_address.value === true &&
userdetails.value.address.street.trim() &&
userdetails.value.address.city.trim() &&
isPostalCode(userdetails.value.address.zipcode, "DE")))
),
});
const toast = useToast();
function login() {
// userdetails = userdetails.value;
if (isPhoneOkay()) {
if (isEmail(userdetails.value.mail)) {
let postdata = {
email: userdetails.value.mail,
firstname: userdetails.value.firstname,
middlename: userdetails.value.middlename,
lastname: userdetails.value.lastname,
address: {},
};
if (userdetails.value.phone !== "") {
postdata.phone = formatPhoneNumber(userdetails.value.phone)
}
if (provide_address.value === true) {
postdata.address = {
address1: userdetails.value.address.street,
address2: userdetails.value.address.address2 || "",
city: userdetails.value.address.city,
postalcode: userdetails.value.address.zipcode,
country: "DE",
};
}
if (state.org_name !== "" && state.org_teams.length > 0) {
postdata.team = org_team.value;
}
toast(t('registration_running'));
const browserlocale = (
(navigator.languages && navigator.languages[0]) ||
""
).substr(0, 2);
registrationState.value = "loading";
if (props.token) {
runnerSelfServiceControllerRegisterOrganizationRunner({ path: { token: props.token }, body: postdata, query: { locale: browserlocale } })
.then(() => {
registrationState.value = "registered";
})
.catch((error) => {
console.log(error);
if (error.data.message === "E-Mail already registered") {
toast(t('already_registered'), { type: TYPE.ERROR });
} else if (error.data.message === "Invalid body, check 'errors' property for more info.") {
error.data.errors.forEach(e => {
if (e.property === "phone") {
toast(t('invalid_input_phone_number_should_be_international_format'), { type: TYPE.ERROR });
}
});
}
});
} else {
runnerSelfServiceControllerRegisterRunner({ body: postdata, query: { locale: browserlocale } })
.then(() => {
registrationState.value = "registered";
})
.catch((error) => {
console.log(error);
if (error.data.message === "E-Mail already registered") {
toast(t('already_registered'), { type: TYPE.ERROR });
} else if (error.data.message === "Invalid body, check 'errors' property for more info.") {
error.data.errors.forEach(e => {
if (e.property === "phone") {
toast(t('invalid_input_phone_number_should_be_international_format'), { type: TYPE.ERROR });
}
});
}
});
}
}
}
}
</script> </script>
-11
View File
@@ -1,11 +0,0 @@
module.exports = {
purge: [ './index.html', './src/**/*.{vue,js,ts,jsx,tsx}' ],
darkMode: 'media', // or 'media' or 'class'
theme: {
extend: {}
},
variants: {
extend: {}
},
plugins: []
};
+10 -8
View File
@@ -1,13 +1,15 @@
import { defineConfig } from 'vite'; import { fileURLToPath, URL } from "node:url";
import vue from '@vitejs/plugin-vue';
import path from 'path'; import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import tailwindcss from "@tailwindcss/vite";
import vueDevTools from "vite-plugin-vue-devtools";
export default defineConfig({ export default defineConfig({
plugins: [ vue() ], plugins: [vue(), vueDevTools(), tailwindcss()],
base: './',
resolve: { resolve: {
alias: { alias: {
'@': path.resolve(__dirname, '/src') "@": fileURLToPath(new URL("./src", import.meta.url)),
} },
} },
}); });