Compare commits
59 Commits
Author | SHA1 | Date | |
---|---|---|---|
ab422cb019 | |||
b7e3e59e7a | |||
509685497e | |||
016a86e188 | |||
ca98acd5bc | |||
a96551cdd0 | |||
6f144d42af | |||
408bd00288 | |||
5646fedd4e | |||
962307317f | |||
5d440d0a0c | |||
54114a6547 | |||
8a08e19e00 | |||
642434b9fd | |||
b0feae1719 | |||
cd8b98c624 | |||
be4b8df02b | |||
d3d0b356ac | |||
3fdd8c80d8 | |||
3e3846f1cb | |||
ed7242cc2a | |||
6152500652 | |||
6ecaae1b8d | |||
5f97c9d8da | |||
e32c2f3069 | |||
83826f966b | |||
1665fd67ae | |||
7516d3579f | |||
2c503f9b03 | |||
6a0b014d55 | |||
b7f792c6f9 | |||
528b025e55 | |||
368e97c6bb | |||
6acd8bb634 | |||
6dcdba6568 | |||
525c096f7a | |||
0de50822cd | |||
0177c50651 | |||
f7575f46e4 | |||
a8d90d4882 | |||
a2ffa5055e | |||
b969932582 | |||
72ace57cb3 | |||
16f9228390 | |||
16d15f7242 | |||
115767c656 | |||
bb3c801908 | |||
e512325115 | |||
aa7d2dbe1b | |||
01cd8d4b78 | |||
c7c1c6dc41 | |||
bf8b351b64 | |||
58830c5db3 | |||
066e67c64f | |||
5f5b03a8a0 | |||
cbfbd92d0e | |||
418fe7773f | |||
4b6e11d8d2 | |||
0698038523 |
131
.drone.yml
131
.drone.yml
@ -1,131 +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: npm_url
|
||||
get:
|
||||
path: odit-npm-cache
|
||||
name: url
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: build:latest
|
||||
|
||||
steps:
|
||||
- name: docker release
|
||||
image: registry.odit.services/library/drone-kaniko
|
||||
depends_on: [clone]
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
build_args:
|
||||
- NPM_REGISTRY_URL:
|
||||
from_secret: npm_url
|
||||
repo: lfk/kiosk
|
||||
tags:
|
||||
- latest
|
||||
cache: true
|
||||
registry: registry.odit.services
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: build:dev
|
||||
steps:
|
||||
- name: docker edge
|
||||
image: registry.odit.services/library/drone-kaniko
|
||||
depends_on: [clone]
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
build_args:
|
||||
- NPM_REGISTRY_URL:
|
||||
from_secret: npm_url
|
||||
repo: lfk/kiosk
|
||||
tags:
|
||||
- edge
|
||||
cache: true
|
||||
registry: registry.odit.services
|
||||
trigger:
|
||||
branch:
|
||||
- dev
|
||||
event:
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: build:tag
|
||||
steps:
|
||||
- name: docker release
|
||||
image: registry.odit.services/library/drone-kaniko
|
||||
depends_on: [clone]
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
build_args:
|
||||
- NPM_REGISTRY_URL:
|
||||
from_secret: npm_url
|
||||
repo: lfk/kiosk
|
||||
tags:
|
||||
- "${DRONE_TAG}"
|
||||
cache: true
|
||||
registry: registry.odit.services
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: check:pr
|
||||
steps:
|
||||
- name: type checks
|
||||
depends_on:
|
||||
- "clone"
|
||||
image: registry.odit.services/hub/library/node:19.9.0-alpine3.16
|
||||
commands:
|
||||
- npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8
|
||||
- pnpm i
|
||||
- pnpm check
|
||||
environment:
|
||||
NPM_REGISTRY_URL:
|
||||
from_secret: npm_url
|
||||
- name: build check
|
||||
depends_on:
|
||||
- "clone"
|
||||
image: registry.odit.services/hub/library/node:19.9.0-alpine3.16
|
||||
commands:
|
||||
- npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8
|
||||
- pnpm i
|
||||
- pnpm build
|
||||
environment:
|
||||
NPM_REGISTRY_URL:
|
||||
from_secret: npm_url
|
||||
trigger:
|
||||
event:
|
||||
- pull_request
|
27
.gitea/workflows/dev.yaml
Normal file
27
.gitea/workflows/dev.yaml
Normal file
@ -0,0 +1,27 @@
|
||||
name: Build latest image
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-container:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Login to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: registry.odit.services
|
||||
username: ${{ vars.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
tags: |
|
||||
${{ vars.REGISTRY }}/lfk/kiosk:latest
|
||||
platforms: linux/amd64,linux/arm64
|
27
.gitea/workflows/release.yaml
Normal file
27
.gitea/workflows/release.yaml
Normal 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/kiosk:${{ github.ref_name }}
|
||||
platforms: linux/amd64,linux/arm64
|
142
CHANGELOG.md
142
CHANGELOG.md
@ -2,8 +2,150 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [1.2.6](https://git.odit.services/lfk/kiosk/compare/1.2.5...1.2.6)
|
||||
|
||||
- fix(register): clear email [`b7e3e59`](https://git.odit.services/lfk/kiosk/commit/b7e3e59e7a948dae76786094743ff5aa679b9a0a)
|
||||
|
||||
#### [1.2.5](https://git.odit.services/lfk/kiosk/compare/1.2.4...1.2.5)
|
||||
|
||||
> 25 April 2025
|
||||
|
||||
- refactor(print): Adjusted size of elements when printed to avoid wasting paper [`a96551c`](https://git.odit.services/lfk/kiosk/commit/a96551cdd0c2e4285d74a064f9c352f1343e4b77)
|
||||
- chore(release): 1.2.5 [`5096854`](https://git.odit.services/lfk/kiosk/commit/509685497e2200f35fbd3d52a8dd7fc62988f246)
|
||||
- style: Refactor footer content for print visibility [`6f144d4`](https://git.odit.services/lfk/kiosk/commit/6f144d42afedd38722d73fde350ea924db2341ba)
|
||||
- fix: Disable selection [`016a86e`](https://git.odit.services/lfk/kiosk/commit/016a86e188c12e98113dd43a97dc0c25ea88e0d6)
|
||||
- fix(print): Disable edge image search [`ca98acd`](https://git.odit.services/lfk/kiosk/commit/ca98acd5bc2e0082398748b0e3a9bb35b2adeb3c)
|
||||
|
||||
#### [1.2.4](https://git.odit.services/lfk/kiosk/compare/1.2.3...1.2.4)
|
||||
|
||||
> 25 April 2025
|
||||
|
||||
- style(print): Adjust print styles for improved readability [`5646fed`](https://git.odit.services/lfk/kiosk/commit/5646fedd4e71b9fa25a5a80d03199f7897cda21c)
|
||||
- chore(release): 1.2.4 [`408bd00`](https://git.odit.services/lfk/kiosk/commit/408bd0028887cc27ee49aa0991ad1356f18d840a)
|
||||
|
||||
#### [1.2.3](https://git.odit.services/lfk/kiosk/compare/1.2.2...1.2.3)
|
||||
|
||||
> 25 April 2025
|
||||
|
||||
- feat(print): Updated content of prints [`5d440d0`](https://git.odit.services/lfk/kiosk/commit/5d440d0a0cba2f8f1470351ef740cfe957a0af47)
|
||||
- chore(release): 1.2.3 [`9623073`](https://git.odit.services/lfk/kiosk/commit/962307317fbb83543b65e1bb36b266a888b732e0)
|
||||
- fix: Hide print enabled debug message [`54114a6`](https://git.odit.services/lfk/kiosk/commit/54114a654733a9454a57a327bbf3f6dd1bf611f2)
|
||||
|
||||
#### [1.2.2](https://git.odit.services/lfk/kiosk/compare/1.2.1...1.2.2)
|
||||
|
||||
> 14 April 2025
|
||||
|
||||
- feat(register): Enable/disable print via query params [`642434b`](https://git.odit.services/lfk/kiosk/commit/642434b9fd4ecf985b160d4d87edad0e8bc106c6)
|
||||
- chore(release): 1.2.2 [`8a08e19`](https://git.odit.services/lfk/kiosk/commit/8a08e19e00658fb145bb7fff7553ca33d6424b21)
|
||||
|
||||
#### [1.2.1](https://git.odit.services/lfk/kiosk/compare/1.2.0...1.2.1)
|
||||
|
||||
> 8 April 2025
|
||||
|
||||
- chore:(deps): Bump client [`be4b8df`](https://git.odit.services/lfk/kiosk/commit/be4b8df02bed33b4755cdf81b8a843239b32bcc1)
|
||||
- chore(release): 1.2.1 [`b0feae1`](https://git.odit.services/lfk/kiosk/commit/b0feae1719c993eb351f1c36c35eedd8a5ffd7ea)
|
||||
- feat(register): Implement created_via [`cd8b98c`](https://git.odit.services/lfk/kiosk/commit/cd8b98c6249b84cb6d2c4f7eb1d403c1837bc151)
|
||||
|
||||
#### [1.2.0](https://git.odit.services/lfk/kiosk/compare/1.1.5...1.2.0)
|
||||
|
||||
> 8 April 2025
|
||||
|
||||
- refactor(svelte): Threw out workspace config [`5f97c9d`](https://git.odit.services/lfk/kiosk/commit/5f97c9d8da1a9002875d8fe35606c078c62c1d0a)
|
||||
- feat: Full printing support [`3e3846f`](https://git.odit.services/lfk/kiosk/commit/3e3846f1cb1fe281edce7c6ce3485f54ddbed3e2)
|
||||
- refactor(register): Switch to showing qr code [`ed7242c`](https://git.odit.services/lfk/kiosk/commit/ed7242cc2a6e1af22de8950a53b64e94459a2aee)
|
||||
- style(docs): Linting [`6ecaae1`](https://git.odit.services/lfk/kiosk/commit/6ecaae1b8dcce099b82cd257a22bd1d579d79ba2)
|
||||
- chore(release): 1.2.0 [`d3d0b35`](https://git.odit.services/lfk/kiosk/commit/d3d0b356ac6d0e6d0fa40a7390799d57a3e50f7a)
|
||||
- chore: Bump js lib [`6152500`](https://git.odit.services/lfk/kiosk/commit/61525006526ab5e237b0caf24a474618fc238372)
|
||||
- fix: Updated styling [`3fdd8c8`](https://git.odit.services/lfk/kiosk/commit/3fdd8c80d8d72bdc899739896fa379ff7a7b620d)
|
||||
|
||||
#### [1.1.5](https://git.odit.services/lfk/kiosk/compare/1.1.4...1.1.5)
|
||||
|
||||
> 7 April 2025
|
||||
|
||||
- chore(release): 1.1.5 [`e32c2f3`](https://git.odit.services/lfk/kiosk/commit/e32c2f3069e03584f3829a96e3fea94f98bf419b)
|
||||
- chore(deps): bump [`1665fd6`](https://git.odit.services/lfk/kiosk/commit/1665fd67ae7153ece759edbe3e74262eb207a2f6)
|
||||
- feat: clock widget, general cleanups [`83826f9`](https://git.odit.services/lfk/kiosk/commit/83826f966bb0de2402889d6574c6db7730831119)
|
||||
|
||||
#### [1.1.4](https://git.odit.services/lfk/kiosk/compare/1.1.3...1.1.4)
|
||||
|
||||
> 2 April 2025
|
||||
|
||||
- feat: improve registration flow [`2c503f9`](https://git.odit.services/lfk/kiosk/commit/2c503f9b0333b668730c4eb11deb5184ee49f295)
|
||||
- chore(release): 1.1.4 [`7516d35`](https://git.odit.services/lfk/kiosk/commit/7516d3579f31166f172cd5f5bcf071366d9c59ec)
|
||||
|
||||
#### [1.1.3](https://git.odit.services/lfk/kiosk/compare/1.1.2...1.1.3)
|
||||
|
||||
> 2 April 2025
|
||||
|
||||
- chore(release): 1.1.3 [`6a0b014`](https://git.odit.services/lfk/kiosk/commit/6a0b014d55b129eef17d70bb9a86203a272d3ad3)
|
||||
- fix: registration without email [`b7f792c`](https://git.odit.services/lfk/kiosk/commit/b7f792c6f99249acd0c8c1154800c4442ad5a8b0)
|
||||
|
||||
#### [1.1.2](https://git.odit.services/lfk/kiosk/compare/1.1.1...1.1.2)
|
||||
|
||||
> 2 April 2025
|
||||
|
||||
- fix: build [`368e97c`](https://git.odit.services/lfk/kiosk/commit/368e97c6bba238b605532aa9c598ace5f2bac592)
|
||||
- chore(release): 1.1.2 [`528b025`](https://git.odit.services/lfk/kiosk/commit/528b025e55ce6d4ab0dec32803d201d057725dac)
|
||||
|
||||
#### [1.1.1](https://git.odit.services/lfk/kiosk/compare/1.1.0...1.1.1)
|
||||
|
||||
> 2 April 2025
|
||||
|
||||
- refactor(ci): Switch to actions [`0177c50`](https://git.odit.services/lfk/kiosk/commit/0177c506516c5e21b4f73e1086b587ab2f1d8f50)
|
||||
- feat: improved registration [`6dcdba6`](https://git.odit.services/lfk/kiosk/commit/6dcdba6568def337dcd1e4e6db5c75df09c1f938)
|
||||
- 🚀Bumped version to 1.1.1 [`6acd8bb`](https://git.odit.services/lfk/kiosk/commit/6acd8bb6340f0d874e8ab8b9e1a93a5fd05fd3b6)
|
||||
- feat: disable chrome autocomplete [`525c096`](https://git.odit.services/lfk/kiosk/commit/525c096f7a757105947da62e8dac75a24e0aa757)
|
||||
|
||||
#### [1.1.0](https://git.odit.services/lfk/kiosk/compare/1.0.0...1.1.0)
|
||||
|
||||
> 16 December 2024
|
||||
|
||||
- chore(deps): bump all [`b969932`](https://git.odit.services/lfk/kiosk/commit/b9699325828dd9b3ed51997d7a72f43449f000cf)
|
||||
- 🚀Bumped version to 1.1.0 [`f7575f4`](https://git.odit.services/lfk/kiosk/commit/f7575f46e4197da893c002299f8e7fdefc5cb026)
|
||||
- feat(ci)!: Switch to woodpecker [`16f9228`](https://git.odit.services/lfk/kiosk/commit/16f92283904bc3a2825ebb0fb0c7f130ffa8f057)
|
||||
- feat: email [`a8d90d4`](https://git.odit.services/lfk/kiosk/commit/a8d90d48829fa708d1cdc5029d1e1ac2f28b1e4c)
|
||||
- 2025 [`a2ffa50`](https://git.odit.services/lfk/kiosk/commit/a2ffa5055e58445bbbc6f932495eb8c4952fec99)
|
||||
|
||||
### [1.0.0](https://git.odit.services/lfk/kiosk/compare/0.6.0...1.0.0)
|
||||
|
||||
> 19 April 2023
|
||||
|
||||
- feat: footer [`115767c`](https://git.odit.services/lfk/kiosk/commit/115767c656381336257c23ee30a130e7e9c60144)
|
||||
- refactor: drop footer [`e512325`](https://git.odit.services/lfk/kiosk/commit/e5123251155f58e83f36c091b671acc73167ce68)
|
||||
- 🚀Bumped version to 1.0.0 [`16d15f7`](https://git.odit.services/lfk/kiosk/commit/16d15f7242c738724121797cea1bd2868253fc6f)
|
||||
- feat: prevent F1 + F5 [`bb3c801`](https://git.odit.services/lfk/kiosk/commit/bb3c80190834be6d43f50cdb6eeb09ac75868259)
|
||||
|
||||
#### [0.6.0](https://git.odit.services/lfk/kiosk/compare/0.5.0...0.6.0)
|
||||
|
||||
> 19 April 2023
|
||||
|
||||
- feat!: move to single route application for kiosk mode [`bf8b351`](https://git.odit.services/lfk/kiosk/commit/bf8b351b644174a2dd39d38208a03a067de387be)
|
||||
- refactor!: cleanup userdata localstorage + components [`c7c1c6d`](https://git.odit.services/lfk/kiosk/commit/c7c1c6dc41afc6ca3e66b507fd1ff50185f4e1be)
|
||||
- 🚀Bumped version to 0.6.0 [`aa7d2db`](https://git.odit.services/lfk/kiosk/commit/aa7d2dbe1b67b33a59093bc53aa944cb6473ef03)
|
||||
- add chrome kiosk command to readme [`01cd8d4`](https://git.odit.services/lfk/kiosk/commit/01cd8d4b78b3898d2f74f2b27cdad9e9745c1e33)
|
||||
|
||||
#### [0.5.0](https://git.odit.services/lfk/kiosk/compare/0.4.4...0.5.0)
|
||||
|
||||
> 19 April 2023
|
||||
|
||||
- feat(registration): autofocus input fields + done button [`cbfbd92`](https://git.odit.services/lfk/kiosk/commit/cbfbd92d0e4f9735a2192125f267f651ed36c9b1)
|
||||
- 🚀Bumped version to 0.5.0 [`58830c5`](https://git.odit.services/lfk/kiosk/commit/58830c5db3d9903d590f535a4099ad93a8ff6519)
|
||||
- feat(registration): disabled done button for 7.5s [`5f5b03a`](https://git.odit.services/lfk/kiosk/commit/5f5b03a8a086799543cf675ccc3a973b781d1987)
|
||||
- feat(registration): support next input element with ENTER key [`066e67c`](https://git.odit.services/lfk/kiosk/commit/066e67c64f48b00673f2de7727acb230c94c3c13)
|
||||
- feat(registration): disable text select [`418fe77`](https://git.odit.services/lfk/kiosk/commit/418fe7773fbc981186909a1f7c262c3c1fa1ece2)
|
||||
|
||||
#### [0.4.4](https://git.odit.services/lfk/kiosk/compare/0.4.3...0.4.4)
|
||||
|
||||
> 19 April 2023
|
||||
|
||||
- 🚀Bumped version to 0.4.4 [`4b6e11d`](https://git.odit.services/lfk/kiosk/commit/4b6e11d8d271c638b3c2e4cd3dc887680023dd5e)
|
||||
- fix(registration): Added missing dark styling [`0698038`](https://git.odit.services/lfk/kiosk/commit/06980385230e32dffe1083ceb4f88e86a9197aef)
|
||||
|
||||
#### [0.4.3](https://git.odit.services/lfk/kiosk/compare/0.4.2...0.4.3)
|
||||
|
||||
> 19 April 2023
|
||||
|
||||
- 🚀Bumped version to 0.4.3 [`297b880`](https://git.odit.services/lfk/kiosk/commit/297b88016bce1619d55bd6dc05f993f59f86382a)
|
||||
- fix(href): replaced location.replace with goto [`8959223`](https://git.odit.services/lfk/kiosk/commit/8959223016b2bbe8ebae79f55a489cc0503b3c78)
|
||||
|
||||
#### [0.4.2](https://git.odit.services/lfk/kiosk/compare/0.4.1...0.4.2)
|
||||
|
@ -1,9 +1,9 @@
|
||||
FROM registry.odit.services/hub/library/node:19.9.0-alpine3.16 AS build
|
||||
ARG NPM_REGISTRY_URL=registry.npmjs.org
|
||||
FROM registry.odit.services/hub/library/node:23.10.0-alpine3.21 AS build
|
||||
# ARG NPM_REGISTRY_URL=registry.npmjs.org
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json *.config.cjs *.config.js *.config.ts tsconfig.json .npmrc ./
|
||||
RUN npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8
|
||||
RUN npm i -g pnpm@10.7
|
||||
RUN pnpm i
|
||||
|
||||
COPY src ./src
|
||||
@ -11,5 +11,5 @@ COPY static ./static
|
||||
RUN pnpm build
|
||||
|
||||
# final image
|
||||
FROM registry.odit.services/library/nginx-brotli:3.15 as final
|
||||
FROM registry.odit.services/library/nginx-brotli:3.15 AS final
|
||||
COPY --from=build /app/build /usr/share/nginx/html
|
23
README.md
23
README.md
@ -1,27 +1,38 @@
|
||||
# @lfk/kiosk
|
||||
|
||||
## Overview 👀
|
||||
|
||||
This is a simple kiosk style register form for the LfK runnersystem.
|
||||
The basic idea is:
|
||||
|
||||
1. Create a runnersystem user with only `RUNNER:CREATE` permissions.
|
||||
2. Login with this user under `/login`
|
||||
3. Runners can register via their firstnam and lastname
|
||||
4. The kiosk creates the runner via the backend and shows their id, firstname, lastname and a barcode containing their id
|
||||
3. Runners can register via their firstname and lastname
|
||||
4. The kiosk creates the runner via the backend and shows their id, firstname, lastname and a barcode containing their id along
|
||||
|
||||
## Development 🛠️
|
||||
```
|
||||
|
||||
```shell
|
||||
pnpm i
|
||||
pnpm dev --open
|
||||
```
|
||||
|
||||
## Build 🚀
|
||||
```
|
||||
|
||||
```shell
|
||||
pnpm i
|
||||
pnpm build
|
||||
```
|
||||
|
||||
## Docker 🐳
|
||||
```
|
||||
|
||||
```shell
|
||||
docker build .
|
||||
docker-compose up
|
||||
```
|
||||
```
|
||||
|
||||
## Kiosk Google Chrome
|
||||
|
||||
``` shell
|
||||
chrome https://run.lauf-fuer-kaya.de/kiosk/ -kiosk
|
||||
```
|
||||
|
8624
licenses.md
8624
licenses.md
File diff suppressed because it is too large
Load Diff
63
package.json
63
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@lfk/kiosk",
|
||||
"version": "0.4.3",
|
||||
"version": "1.2.6",
|
||||
"private": false,
|
||||
"license": "MIT",
|
||||
"repository": "https://git.odit.services/lfk/kiosk",
|
||||
@ -33,45 +33,44 @@
|
||||
"license:export": "license-exporter --markdown && git stage licenses.md"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@odit/license-exporter": "0.0.12",
|
||||
"@sveltejs/adapter-static": "2.0.2",
|
||||
"@sveltejs/kit": "1.15.7",
|
||||
"@types/bwip-js": "^3.2.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.59.0",
|
||||
"@typescript-eslint/parser": "5.59.0",
|
||||
"auto-changelog": "2.4.0",
|
||||
"autoprefixer": "10.4.14",
|
||||
"eslint": "8.38.0",
|
||||
"eslint-config-prettier": "8.8.0",
|
||||
"eslint-plugin-svelte3": "4.0.0",
|
||||
"postcss": "8.4.22",
|
||||
"postcss-load-config": "4.0.1",
|
||||
"prettier": "2.8.7",
|
||||
"prettier-plugin-svelte": "2.10.0",
|
||||
"release-it": "15.10.1",
|
||||
"svelte": "3.58.0",
|
||||
"svelte-check": "3.2.0",
|
||||
"svelte-preprocess": "5.0.3",
|
||||
"tailwindcss": "3.3.1",
|
||||
"tslib": "2.5.0",
|
||||
"typescript": "5.0.4",
|
||||
"vite": "4.2.2"
|
||||
"@odit/license-exporter": "0.2.0",
|
||||
"@philippdormann/release-it": "^1.0.0",
|
||||
"@sveltejs/adapter-static": "3.0.8",
|
||||
"@sveltejs/kit": "2.20.4",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||
"@types/bwip-js": "^3.2.3",
|
||||
"@typescript-eslint/eslint-plugin": "8.29.0",
|
||||
"@typescript-eslint/parser": "8.29.0",
|
||||
"auto-changelog": "2.5.0",
|
||||
"eslint": "9.24.0",
|
||||
"eslint-config-prettier": "10.1.1",
|
||||
"prettier": "3.5.3",
|
||||
"prettier-plugin-svelte": "3.3.3",
|
||||
"svelte": "5.25.7",
|
||||
"svelte-check": "4.1.5",
|
||||
"svelte-preprocess": "6.0.3",
|
||||
"tslib": "2.8.1",
|
||||
"typescript": "5.8.3",
|
||||
"vite": "6.2.5"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@fontsource/athiti": "^4.5.10",
|
||||
"@odit/lfk-client-js": "1.0.1",
|
||||
"bwip-js": "3.4.0"
|
||||
"@fontsource/athiti": "^5.2.5",
|
||||
"@odit/lfk-client-js": "1.2.2",
|
||||
"@tailwindcss/vite": "^4.1.3",
|
||||
"bwip-js": "4.5.3",
|
||||
"eslint-plugin-svelte": "^3.5.1",
|
||||
"tailwindcss": "^4.1.3"
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
"commit": true,
|
||||
"requireCleanWorkingDir": false,
|
||||
"commitMessage": "🚀Bumped version to ${version}",
|
||||
"commitMessage": "chore(release): ${version}",
|
||||
"requireBranch": "main",
|
||||
"push": true,
|
||||
"tag": true,
|
||||
"tagName": null,
|
||||
"tagName": "${version}",
|
||||
"tagAnnotation": "${version}"
|
||||
},
|
||||
"npm": {
|
||||
@ -80,11 +79,5 @@
|
||||
"hooks": {
|
||||
"after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && npm run license:export && git add CHANGELOG.md && git add licenses.md"
|
||||
}
|
||||
},
|
||||
"volta": {
|
||||
"node": "19.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"pnpm": "8"
|
||||
}
|
||||
}
|
||||
|
6948
pnpm-lock.yaml
generated
6948
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,13 +0,0 @@
|
||||
const tailwindcss = require('tailwindcss');
|
||||
const autoprefixer = require('autoprefixer');
|
||||
|
||||
const config = {
|
||||
plugins: [
|
||||
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
|
||||
tailwindcss(),
|
||||
//But others, like autoprefixer, need to run after,
|
||||
autoprefixer
|
||||
]
|
||||
};
|
||||
|
||||
module.exports = config;
|
4
src/app.css
Normal file
4
src/app.css
Normal file
@ -0,0 +1,4 @@
|
||||
@import 'tailwindcss';
|
||||
* {
|
||||
font-family: 'Athiti', sans-serif;
|
||||
}
|
@ -5,11 +5,6 @@
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
%sveltekit.head%
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Athiti', sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
|
@ -1,4 +0,0 @@
|
||||
/* Write your global styles here, in PostCSS syntax */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
@ -1,49 +0,0 @@
|
||||
<footer class="mt-auto w-full max-w-[85rem] py-10 px-4 sm:px-6 lg:px-8 mx-auto">
|
||||
<!-- Grid -->
|
||||
<div class="text-center">
|
||||
<div>
|
||||
<a
|
||||
class="flex-none text-xl font-semibold text-black dark:text-white"
|
||||
href="/"
|
||||
aria-label="Brand">LfK Kiosk</a
|
||||
>
|
||||
</div>
|
||||
<!-- End Col -->
|
||||
|
||||
<div class="mt-3">
|
||||
<p class="text-gray-500">
|
||||
Powered by <a
|
||||
class="font-semibold text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href="https://odit.services/?ref=lfks">ODIT.Services</a
|
||||
>
|
||||
</p>
|
||||
<p class="text-gray-500">© {new Date().getFullYear()} ODIT.Services</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 space-x-2">
|
||||
<a
|
||||
class="inline-flex justify-center items-center text-center text-gray-500 hover:bg-gray-100 rounded-full focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 focus:ring-offset-white transition dark:text-gray-500 dark:hover:text-gray-200 dark:hover:bg-gray-800"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href="https://lauf-fuer-kaya.de/impressum"
|
||||
>
|
||||
Impressum
|
||||
</a>
|
||||
<p
|
||||
class="inline-flex justify-center items-center text-center text-gray-500 hover:bg-gray-100 rounded-full focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 focus:ring-offset-white transition dark:text-gray-500 dark:hover:text-gray-200 dark:hover:bg-gray-800"
|
||||
>
|
||||
|
|
||||
</p>
|
||||
<a
|
||||
class="inline-flex justify-center items-center text-center text-gray-500 hover:bg-gray-100 rounded-full focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 focus:ring-offset-white transition dark:text-gray-500 dark:hover:text-gray-200 dark:hover:bg-gray-800"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href="https://lauf-fuer-kaya.de/datenschutz"
|
||||
>
|
||||
Datenschutz
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
@ -2,93 +2,69 @@ import { AuthService, OpenAPI, type ResponseAuth } from '@odit/lfk-client-js';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
type UserState = {
|
||||
access_token: string;
|
||||
refresh_token: string;
|
||||
isLoggedIn: boolean;
|
||||
refreshInterval: NodeJS.Timer | undefined
|
||||
access_token: string;
|
||||
refresh_token: string;
|
||||
isLoggedIn: boolean;
|
||||
refreshInterval: NodeJS.Timer | undefined;
|
||||
};
|
||||
|
||||
const userStore = () => {
|
||||
const state: UserState = {
|
||||
access_token: '',
|
||||
refresh_token: '',
|
||||
isLoggedIn: false,
|
||||
refreshInterval: undefined
|
||||
};
|
||||
|
||||
const { subscribe, set, update } = writable(state);
|
||||
|
||||
const methods = {
|
||||
async login(resAuth: ResponseAuth) {
|
||||
update((state: UserState) => {
|
||||
if (!resAuth) {
|
||||
return state;
|
||||
}
|
||||
|
||||
state.access_token = resAuth.access_token;
|
||||
state.refresh_token = resAuth.refresh_token;
|
||||
state.isLoggedIn = true;
|
||||
state.refreshInterval = setInterval(() => {
|
||||
this.refreshAuth();
|
||||
}, 2 * 60000)
|
||||
|
||||
localStorage.setItem('kiosk-userdata', JSON.stringify(state));
|
||||
localStorage.setItem('kiosk-access_token', state.access_token);
|
||||
OpenAPI.TOKEN = resAuth.access_token;
|
||||
return state;
|
||||
});
|
||||
},
|
||||
async refreshAuth() {
|
||||
try {
|
||||
const authRes = await AuthService.authControllerRefresh({ token: state.refresh_token }) as ResponseAuth;
|
||||
OpenAPI.TOKEN = authRes.access_token;
|
||||
} catch {
|
||||
this.logout();
|
||||
}
|
||||
},
|
||||
async loginFromStorage() {
|
||||
console.log('loginFromStorage');
|
||||
const access_token = localStorage.getItem('kiosk-access_token');
|
||||
if (!access_token) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
const storagedata = localStorage.getItem('kiosk-userdata');
|
||||
const userdata = JSON.parse(storagedata || '{}') as UserState;
|
||||
|
||||
update((state: UserState) => {
|
||||
state.access_token = access_token;
|
||||
state.refresh_token = userdata.refresh_token;
|
||||
state.isLoggedIn = true;
|
||||
state.refreshInterval = setInterval(() => {
|
||||
this.refreshAuth();
|
||||
}, 2 * 60000);
|
||||
OpenAPI.TOKEN = userdata.access_token;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
await this.refreshAuth();
|
||||
},
|
||||
async logout() {
|
||||
update((state: UserState) => {
|
||||
state.isLoggedIn = false;
|
||||
state.access_token = '';
|
||||
state.refresh_token = '';
|
||||
state.refreshInterval = undefined;
|
||||
localStorage.clear();
|
||||
return state;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
set,
|
||||
update,
|
||||
state,
|
||||
...methods
|
||||
};
|
||||
const state: UserState = {
|
||||
access_token: '',
|
||||
refresh_token: '',
|
||||
isLoggedIn: false,
|
||||
refreshInterval: undefined
|
||||
};
|
||||
const userState = writable(state);
|
||||
async function auth_login(resAuth: ResponseAuth) {
|
||||
if (!resAuth) {
|
||||
return state;
|
||||
}
|
||||
|
||||
export default userStore();
|
||||
state.access_token = resAuth.access_token;
|
||||
state.refresh_token = resAuth.refresh_token;
|
||||
state.isLoggedIn = true;
|
||||
state.refreshInterval = setInterval(() => {
|
||||
refreshAuth();
|
||||
}, 2 * 60000);
|
||||
|
||||
localStorage.setItem('kiosk-userdata', JSON.stringify(state));
|
||||
OpenAPI.TOKEN = resAuth.access_token;
|
||||
userState.set(state);
|
||||
return state;
|
||||
}
|
||||
async function refreshAuth() {
|
||||
try {
|
||||
const authRes = (await AuthService.authControllerRefresh({
|
||||
token: state.refresh_token
|
||||
})) as ResponseAuth;
|
||||
OpenAPI.TOKEN = authRes.access_token;
|
||||
} catch {
|
||||
logout();
|
||||
}
|
||||
}
|
||||
async function loginFromStorage() {
|
||||
const storagedata = localStorage.getItem('kiosk-userdata');
|
||||
const userdata = JSON.parse(storagedata || '{}') as UserState;
|
||||
if (!userdata.access_token) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
state.access_token = userdata.access_token;
|
||||
state.refresh_token = userdata.refresh_token;
|
||||
state.isLoggedIn = true;
|
||||
state.refreshInterval = setInterval(() => {
|
||||
refreshAuth();
|
||||
}, 2 * 60000);
|
||||
OpenAPI.TOKEN = userdata.access_token;
|
||||
userState.set(state);
|
||||
return state;
|
||||
}
|
||||
async function logout() {
|
||||
state.isLoggedIn = false;
|
||||
state.access_token = '';
|
||||
state.refresh_token = '';
|
||||
state.refreshInterval = undefined;
|
||||
localStorage.clear();
|
||||
return state;
|
||||
}
|
||||
|
||||
export { auth_login, logout, loginFromStorage, refreshAuth, userState };
|
||||
|
@ -1,15 +1,38 @@
|
||||
<script>
|
||||
import { OpenAPI } from '@odit/lfk-client-js';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import '../app.postcss';
|
||||
import "@fontsource/athiti"
|
||||
import Footer from '../components/footer.svelte';
|
||||
import '@fontsource/athiti';
|
||||
import '../app.css';
|
||||
import { onMount } from 'svelte';
|
||||
import lfkbackground from './background.png';
|
||||
|
||||
OpenAPI.BASE = env.PUBLIC_BASE_URL || 'https://run.lauf-fuer-kaya.de';
|
||||
OpenAPI.BASE = 'https://run.lauf-fuer-kaya.de';
|
||||
onMount(() => {
|
||||
window.addEventListener('keydown', (e) => {
|
||||
// F1
|
||||
if (e.keyCode === 112) e.preventDefault();
|
||||
// F5
|
||||
if (e.keyCode === 116) e.preventDefault();
|
||||
});
|
||||
});
|
||||
let time = new Date();
|
||||
$: hours = (time.getHours() + '').padStart(2, '0');
|
||||
$: minutes = (time.getMinutes() + '').padStart(2, '0');
|
||||
$: seconds = (time.getSeconds() + '').padStart(2, '0');
|
||||
setInterval(() => {
|
||||
time = new Date();
|
||||
}, 500);
|
||||
</script>
|
||||
|
||||
<div class="dark:bg-slate-900 flex flex-col h-screen">
|
||||
<div
|
||||
class="text-neutral-800 flex flex-col h-screen print:h-full select-none"
|
||||
style="background: url({lfkbackground});background-position: center center!important;background-size: contain!important;background-repeat: no-repeat!important;"
|
||||
>
|
||||
<main class="flex-grow">
|
||||
<div
|
||||
class="text-6xl font-semibold text-right text-gray-900 font-mono top-2 w-full fixed pr-4 xl:top-6 xl:pr-8 print:hidden"
|
||||
>
|
||||
{hours}:{minutes}:{seconds}
|
||||
</div>
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
|
@ -1,41 +1,53 @@
|
||||
<!-- Hero -->
|
||||
<div
|
||||
class="relative overflow-hidden before:absolute before:top-0 before:left-1/2 before:bg-[url('/assets/polygon.svg')] before:bg-no-repeat before:bg-top before:bg-cover before:w-full before:h-full before:-z-[1] before:transform before:-translate-x-1/2 dark:before:bg-[url('/assets/polygon-dark.svg')]"
|
||||
>
|
||||
<div class="max-w-[85rem] mx-auto px-4 sm:px-6 lg:px-8 pt-24 pb-10">
|
||||
<!-- Title -->
|
||||
<div class="mt-5 max-w-2xl text-center mx-auto">
|
||||
<h1 class="block font-bold text-gray-800 text-4xl md:text-5xl lg:text-6xl dark:text-gray-200">
|
||||
LfK! Selfservice
|
||||
<span class="bg-clip-text bg-gradient-to-tl from-blue-600 to-violet-600 text-transparent"
|
||||
>Kiosk</span
|
||||
>
|
||||
</h1>
|
||||
</div>
|
||||
<!-- End Title -->
|
||||
<script lang="ts">
|
||||
import { loginFromStorage, userState } from '$lib/userstore';
|
||||
import Register from './Register.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import Login from './Login.svelte';
|
||||
|
||||
<div class="mt-5 max-w-3xl text-center mx-auto">
|
||||
<p class="text-lg text-gray-600 dark:text-gray-400">Für die Anmeldung vor Ort</p>
|
||||
</div>
|
||||
$: printEnabled = false;
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="mt-8 grid gap-3 w-full sm:inline-flex sm:justify-center">
|
||||
<a
|
||||
class="inline-flex justify-center items-center gap-x-3 text-center bg-gradient-to-tl from-blue-600 to-violet-600 hover:from-violet-600 hover:to-blue-600 border border-transparent text-white text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 focus:ring-offset-white py-3 px-4 dark:focus:ring-offset-gray-800"
|
||||
href="./login"
|
||||
>
|
||||
Kiosk starten
|
||||
<svg class="w-3 h-3" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path
|
||||
d="M5.27921 2L10.9257 7.64645C11.1209 7.84171 11.1209 8.15829 10.9257 8.35355L5.27921 14"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<!-- End Buttons -->
|
||||
</div>
|
||||
onMount(() => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
if (params.get('print') === 'true') {
|
||||
printEnabled = true;
|
||||
}
|
||||
loginFromStorage();
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if $userState.isLoggedIn}
|
||||
<Register bind:printEnabled />
|
||||
{:else}
|
||||
<Login />
|
||||
{/if}
|
||||
<div class="fixed bottom-0 w-full text-center text-xl p-4 dark:text-white select-none print:absolute print:bottom-auto print:text-sm">
|
||||
{#if $userState.isLoggedIn}
|
||||
<span class="print:hidden">
|
||||
<b class="font-bold">LfK!2025</b> powered by
|
||||
<b class="font-bold">ODIT.Services</b>
|
||||
</span>
|
||||
<b class="font-bold hidden print:block"> LfK!2025 powered by ODIT.Services</b>
|
||||
{:else}
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href="https://lauf-fuer-kaya.de/datenschutz/"
|
||||
class="underline">Datenschutzerklärung</a
|
||||
>
|
||||
|
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href="https://lauf-fuer-kaya.de/impressum/"
|
||||
class="underline">Impressum</a
|
||||
>
|
||||
<br />
|
||||
<b class="font-bold">LfK!2025</b> powered by
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href="https://odit.services?ref=lfk"
|
||||
class="underline">ODIT.Services</a
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- End Hero -->
|
||||
|
109
src/routes/Login.svelte
Normal file
109
src/routes/Login.svelte
Normal file
@ -0,0 +1,109 @@
|
||||
<script lang="ts">
|
||||
import { auth_login, loginFromStorage } from '$lib/userstore';
|
||||
import { AuthService } from '@odit/lfk-client-js';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
$: username = '';
|
||||
$: password = '';
|
||||
$: loginError = false;
|
||||
|
||||
onMount(() => {
|
||||
loginFromStorage();
|
||||
});
|
||||
|
||||
async function login() {
|
||||
try {
|
||||
const auth = (await AuthService.authControllerLogin({
|
||||
username,
|
||||
password
|
||||
})) as import('@odit/lfk-client-js').ResponseAuth;
|
||||
loginError = false;
|
||||
auth_login(auth);
|
||||
} catch (error) {
|
||||
loginError = true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- -->
|
||||
<div class="relative overflow-hidden">
|
||||
<div class="max-w-md mx-auto px-4 sm:px-6 lg:px-8 pt-24 pb-10">
|
||||
<div class="text-center">
|
||||
<h1 class="block text-7xl font-bold">LfK!Kiosk</h1>
|
||||
<h1 class="block text-4xl font-bold">Login</h1>
|
||||
<!-- <p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Melde dich für den LfK an</p> -->
|
||||
</div>
|
||||
<!-- Title -->
|
||||
<!-- <div class="mt-5 max-w-2xl text-center mx-auto">
|
||||
<h1 class="block font-bold text-gray-800 text-4xl md:text-5xl lg:text-6xl dark:text-gray-200">
|
||||
LfK! Selfservice
|
||||
<span class="bg-clip-text bg-gradient-to-tl from-blue-600 to-violet-600 text-transparent"
|
||||
>Kiosk</span
|
||||
>
|
||||
</h1>
|
||||
</div> -->
|
||||
<!-- End Title -->
|
||||
|
||||
{#if loginError}
|
||||
<div
|
||||
class="bg-red-500 text-white text-center font-semibold rounded-md shadow-lg mb-8 mt-4"
|
||||
role="alert"
|
||||
>
|
||||
<div class="p-4">Falscher Nutzername oder falsches Passwort</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Form -->
|
||||
<form on:submit|preventDefault={login}>
|
||||
<div class="grid gap-y-4">
|
||||
<!-- Form Group -->
|
||||
<div>
|
||||
<label for="username" class="block font-semibold">Benutzername</label>
|
||||
<div class="relative">
|
||||
<input
|
||||
autofocus
|
||||
bind:value={username}
|
||||
autocomplete="one-time-code"
|
||||
type="username"
|
||||
id="username"
|
||||
name="username"
|
||||
placeholder="Benutzername"
|
||||
class="placeholder:text-neutral-800 py-3 px-4 block w-full rounded-md focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 border bg-white"
|
||||
required
|
||||
aria-describedby="username-error"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Form Group -->
|
||||
|
||||
<!-- Form Group -->
|
||||
<div>
|
||||
<div class="flex justify-between items-center">
|
||||
<label for="password" class="block font-semibold">Passwort</label>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<input
|
||||
bind:value={password}
|
||||
autocomplete="one-time-code"
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
placeholder="Passwort"
|
||||
class="placeholder:text-neutral-800 py-3 px-4 block w-full rounded-md focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 border bg-white"
|
||||
required
|
||||
aria-describedby="password-error"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Form Group -->
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="py-3 px-4 inline-flex justify-center items-center gap-2 rounded-md border border-transparent font-semibold bg-blue-500 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all dark:focus:ring-offset-gray-800"
|
||||
>Anmelden</button
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
<!-- End Form -->
|
||||
</div>
|
||||
</div>
|
371
src/routes/Register.svelte
Normal file
371
src/routes/Register.svelte
Normal file
@ -0,0 +1,371 @@
|
||||
<script lang="ts">
|
||||
import { RunnerService, type ResponseRunner } from '@odit/lfk-client-js';
|
||||
import bwipjs from 'bwip-js';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
$: firstname = '';
|
||||
$: lastname = '';
|
||||
$: email = '';
|
||||
$: doneButtonEnabled = false;
|
||||
$: showResult = false;
|
||||
|
||||
export let printEnabled = false;
|
||||
|
||||
let response: ResponseRunner;
|
||||
const group = 1; //Default to Bürgerlauf
|
||||
|
||||
function focusFirstName() {
|
||||
setTimeout(() => {
|
||||
document.getElementById('firstname')?.focus();
|
||||
}, 50);
|
||||
setTimeout(() => {
|
||||
document.getElementById('firstname')?.focus();
|
||||
}, 100);
|
||||
}
|
||||
function focusDoneButton() {
|
||||
setTimeout(() => {
|
||||
document.getElementById('done')?.focus();
|
||||
}, 50);
|
||||
setTimeout(() => {
|
||||
document.getElementById('done')?.focus();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
async function register() {
|
||||
try {
|
||||
let emailToSend = null;
|
||||
if (email !== '') {
|
||||
if (email.includes('@')) {
|
||||
emailToSend = email;
|
||||
}
|
||||
}
|
||||
response = (await RunnerService.runnerControllerPost({
|
||||
firstname,
|
||||
lastname,
|
||||
email: emailToSend,
|
||||
group,
|
||||
created_via: 'kiosk'
|
||||
})) as ResponseRunner;
|
||||
showResult = true;
|
||||
if (printEnabled) {
|
||||
setTimeout(() => {
|
||||
window.print();
|
||||
}, 200);
|
||||
}
|
||||
setTimeout(() => {
|
||||
doneButtonEnabled = true;
|
||||
setTimeout(() => {
|
||||
focusDoneButton();
|
||||
}, 25);
|
||||
}, 7500);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
showResult = false;
|
||||
localStorage.clear();
|
||||
location.reload();
|
||||
}
|
||||
email = '';
|
||||
firstname = '';
|
||||
lastname = '';
|
||||
}
|
||||
|
||||
function textToBase64Barcode(text: string, is_qrcode: boolean) {
|
||||
const canvas = document.createElement('canvas');
|
||||
if (is_qrcode) {
|
||||
bwipjs.toCanvas(canvas, {
|
||||
bcid: 'qrcode',
|
||||
text: `${text}`,
|
||||
scale: 10,
|
||||
includetext: false,
|
||||
textxalign: 'center',
|
||||
backgroundcolor: 'ffffff'
|
||||
});
|
||||
} else {
|
||||
bwipjs.toCanvas(canvas, {
|
||||
bcid: 'code128',
|
||||
text: `${text}`,
|
||||
scale: 10,
|
||||
includetext: true,
|
||||
textxalign: 'center',
|
||||
backgroundcolor: 'ffffff',
|
||||
height: 10
|
||||
});
|
||||
}
|
||||
return canvas.toDataURL('image/png');
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
focusFirstName();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex h-full items-center py-16 print:py-0 print:items-baseline">
|
||||
<div class="w-full max-w-md mx-auto p-6 print:p-0">
|
||||
<!-- <div
|
||||
class="mt-7 bg-white border border-gray-200 rounded-xl shadow-sm dark:bg-gray-800 dark:border-gray-200"
|
||||
> -->
|
||||
<div class="p-4 sm:p-7 print:p-0 print:sm:p-0">
|
||||
<div class="mt-5 print:mt-0">
|
||||
<!-- Form -->
|
||||
{#if !showResult}
|
||||
<div class="text-center">
|
||||
<h1 class="block text-7xl font-bold text-gray-800 dark:text-white">LfK!2025</h1>
|
||||
<h1 class="block text-4xl font-bold text-gray-800 dark:text-white">Registrierung</h1>
|
||||
<!-- <p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Melde dich für den LfK an</p> -->
|
||||
</div>
|
||||
<form class="mt-4 text-lg" on:submit|preventDefault={register}>
|
||||
<div class="grid gap-y-4">
|
||||
<!-- Form Group -->
|
||||
<div>
|
||||
<label for="firstname" class="block text-lg font-bold mb-2 sr-only">Vorname</label>
|
||||
<div class="relative">
|
||||
<input
|
||||
on:keydown={(e) => {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
document.getElementById('lastname')?.focus();
|
||||
}
|
||||
if (e.keyCode === 40) {
|
||||
document.getElementById('lastname')?.focus();
|
||||
}
|
||||
}}
|
||||
type="text"
|
||||
autocomplete="one-time-code"
|
||||
id="firstname"
|
||||
name="firstname"
|
||||
class="font-semibold placeholder:font-normal placeholder:text-black dark:placeholder:text-gray-200 py-3 px-4 block w-full border-gray-500 rounded-md focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-200 dark:text-white border bg-white"
|
||||
required
|
||||
placeholder="Vorname"
|
||||
bind:value={firstname}
|
||||
aria-describedby="firstname-error"
|
||||
/>
|
||||
<!-- <div
|
||||
class:hidden={firstname || firstname.length != 0}
|
||||
class="absolute inset-y-0 right-0 flex items-center pointer-events-none pr-3"
|
||||
>
|
||||
<svg
|
||||
class="h-5 w-5 text-red-500"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
||||
/>
|
||||
</svg>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- <p
|
||||
class:hidden={firstname || firstname.length != 0}
|
||||
class="text-xs text-red-600 mt-2"
|
||||
id="firstname-error"
|
||||
>
|
||||
Bitte gebe deinen Vornamen ein
|
||||
</p> -->
|
||||
</div>
|
||||
<!-- End Form Group -->
|
||||
|
||||
<!-- Form Group -->
|
||||
<div>
|
||||
<label for="lastname" class="block text-lg font-bold mb-2 sr-only">Nachname</label>
|
||||
<div class="relative">
|
||||
<input
|
||||
on:keydown={(e) => {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
document.getElementById('email')?.focus();
|
||||
}
|
||||
if (e.keyCode === 38) {
|
||||
document.getElementById('firstname')?.focus();
|
||||
}
|
||||
if (e.keyCode === 40) {
|
||||
document.getElementById('email')?.focus();
|
||||
}
|
||||
}}
|
||||
autocomplete="one-time-code"
|
||||
type="lastname"
|
||||
id="lastname"
|
||||
name="lastname"
|
||||
class="font-semibold placeholder:font-normal placeholder:text-black dark:placeholder:text-gray-200 py-3 px-4 block w-full border-gray-500 rounded-md focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-200 dark:text-white border bg-white"
|
||||
required
|
||||
placeholder="Nachname"
|
||||
aria-describedby="lastname-error"
|
||||
bind:value={lastname}
|
||||
/>
|
||||
<!-- <div
|
||||
class:hidden={lastname || lastname.length != 0}
|
||||
class="absolute inset-y-0 right-0 flex items-center pointer-events-none pr-3"
|
||||
>
|
||||
<svg
|
||||
class="h-5 w-5 text-red-500"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
||||
/>
|
||||
</svg>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- <p
|
||||
class:hidden={lastname || lastname.length != 0}
|
||||
class="text-xs text-red-600 mt-2"
|
||||
id="lastname-error"
|
||||
>
|
||||
Bitte gebe deinen Nachnamen ein
|
||||
</p> -->
|
||||
</div>
|
||||
<!-- End Form Group -->
|
||||
|
||||
<!-- Form Group -->
|
||||
<div>
|
||||
<label for="email" class="block text-lg font-bold mb-2 sr-only"
|
||||
>E-Mail (optional)</label
|
||||
>
|
||||
<div class="relative">
|
||||
<input
|
||||
on:keydown={(e) => {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
document.getElementById('submit')?.focus();
|
||||
}
|
||||
if (e.keyCode === 38) {
|
||||
document.getElementById('lastname')?.focus();
|
||||
}
|
||||
if (e.keyCode === 40) {
|
||||
document.getElementById('submit')?.focus();
|
||||
}
|
||||
}}
|
||||
autocomplete="one-time-code"
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
class="font-semibold placeholder:font-normal placeholder:text-black dark:placeholder:text-gray-200 py-3 px-4 block w-full border-gray-500 rounded-md focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-200 dark:text-white border bg-white"
|
||||
placeholder="E-Mail (optional)"
|
||||
aria-describedby="lastname-error"
|
||||
bind:value={email}
|
||||
/>
|
||||
<!-- <div
|
||||
class:hidden={lastname || lastname.length != 0}
|
||||
class="absolute inset-y-0 right-0 flex items-center pointer-events-none pr-3"
|
||||
>
|
||||
<svg
|
||||
class="h-5 w-5 text-red-500"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
||||
/>
|
||||
</svg>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- <p
|
||||
class:hidden={lastname || lastname.length != 0}
|
||||
class="text-xs text-red-600 mt-2"
|
||||
id="lastname-error"
|
||||
>
|
||||
Bitte gebe deinen Nachnamen ein
|
||||
</p> -->
|
||||
</div>
|
||||
<!-- End Form Group -->
|
||||
<p
|
||||
class="bg-white text-gray-800 dark:bg-gray-800 dark:text-gray-400 rounded border p-3"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="inline"
|
||||
><circle cx="12" cy="12" r="10" /><path d="M12 16v-4" /><path
|
||||
d="M12 8h.01"
|
||||
/></svg
|
||||
>
|
||||
Mit der Registrierung akzeptieren Sie die AGBs sowie die Datenschutzerklärung des Lauf
|
||||
für Kaya! 2025 sowie der ODIT.Services GmbH.
|
||||
</p>
|
||||
<button
|
||||
on:keydown={(e) => {
|
||||
if (e.keyCode === 38) {
|
||||
document.getElementById('email')?.focus();
|
||||
}
|
||||
}}
|
||||
id="submit"
|
||||
type="submit"
|
||||
disabled={!firstname || !lastname}
|
||||
class="py-3 px-4 inline-flex justify-center items-center gap-2 rounded-md border border-transparent font-semibold disabled:opacity-70 bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all dark:focus:ring-offset-gray-800 cursor-pointer"
|
||||
>Anmelden</button
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
<!-- End Form -->
|
||||
{:else}
|
||||
<div class="mb-2 text-center print:mb-0">
|
||||
<h3 class="text-4xl font-semibold dark:text-white print:text-2xl/tight">
|
||||
{response.firstname}
|
||||
{response.lastname}
|
||||
</h3>
|
||||
<h4 class="font-semibold dark:text-white hidden print:block print:text-lg/tight">
|
||||
{response.id}
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="mb-2 text-center print:mb-0">
|
||||
<h3 class="text-xl font-semibold dark:text-white print:hidden">
|
||||
Scanne diesen QR-Code, um zu unserem Selfservice zu gelangen. Hier findest du deine
|
||||
Rundenzeiten, Spenden und Urkunden.
|
||||
</h3>
|
||||
<h3 class="text-base/tight font-semibold dark:text-white hidden print:block">
|
||||
Zeige diesen QR-Code am Infozelt vor, um deine Läuferkarte zu erhalten.
|
||||
</h3>
|
||||
<img
|
||||
class="w-full md:w-auto mb-2 mx-auto bg-white p-4 print:w-3/5 print:p-0 pointer-events-none"
|
||||
alt="runner selfservice"
|
||||
src={textToBase64Barcode(response.selfserviceLink.toString(), true)}
|
||||
/>
|
||||
<h3 class="text-base/tight font-semibold dark:text-white hidden print:block">
|
||||
Scanne diesen QR-Code, um zu unserem Selfservice zu gelangen. Hier findest du deine
|
||||
Rundenzeiten, Spenden und Urkunden.
|
||||
</h3>
|
||||
{#if printEnabled}
|
||||
<h3 class="text-xl font-semibold dark:text-white print:hidden">
|
||||
Bitte nehm den Bon mit und zeige ihn am Infozelt vor, um deine Läuferkarte zu erhalten.
|
||||
Auf dem Bon findest auch nochmal den QR-Code.
|
||||
</h3>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="mx-auto text-center items-center print:hidden">
|
||||
<button
|
||||
class:opacity-50={!doneButtonEnabled}
|
||||
disabled={!doneButtonEnabled}
|
||||
id="done"
|
||||
on:click={() => {
|
||||
doneButtonEnabled = false;
|
||||
showResult = false;
|
||||
focusFirstName();
|
||||
}}
|
||||
class="w-full py-3 px-4 inline-flex justify-center items-center gap-2 rounded-md border border-transparent font-semibold bg-blue-500 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all text-sm dark:focus:ring-offset-gray-800 cursor-pointer"
|
||||
>Fertig</button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
@ -1,95 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import userstore from '$lib/userstore';
|
||||
import { AuthService } from '@odit/lfk-client-js';
|
||||
|
||||
$: username = '';
|
||||
$: password = '';
|
||||
$: loginError = false;
|
||||
|
||||
async function login() {
|
||||
try {
|
||||
const auth = (await AuthService.authControllerLogin({
|
||||
username,
|
||||
password
|
||||
})) as import('@odit/lfk-client-js').ResponseAuth;
|
||||
loginError=false;
|
||||
await userstore.login(auth);
|
||||
goto('./registration', {replaceState: true})
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
loginError = true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="dark:bg-slate-900 bg-gray-100 flex h-full items-center py-16">
|
||||
<div class="w-full max-w-md mx-auto p-6">
|
||||
<div
|
||||
class="mt-7 bg-white border border-gray-200 rounded-xl shadow-sm dark:bg-gray-800 dark:border-gray-700"
|
||||
>
|
||||
<div class="p-4 sm:p-7">
|
||||
<div class="text-center mb-8">
|
||||
<h1 class="block text-2xl font-bold text-gray-800 dark:text-white">Anmeldung</h1>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Hierfür wird ein LfK Läufersystem Account benötigt
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{#if loginError}
|
||||
<div class="bg-red-500 text-sm text-white text-center font-semibold rounded-md shadow-lg mb-8" role="alert">
|
||||
<div class="p-4">Falscher Nutzername oder falsches Passwort</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Form -->
|
||||
<form on:submit|preventDefault={login}>
|
||||
<div class="grid gap-y-4">
|
||||
<!-- Form Group -->
|
||||
<div>
|
||||
<label for="username" class="block text-sm mb-2 dark:text-white">Benutzername</label>
|
||||
<div class="relative">
|
||||
<input
|
||||
bind:value={username}
|
||||
type="username"
|
||||
id="username"
|
||||
name="username"
|
||||
class="py-3 px-4 block w-full border-gray-200 rounded-md text-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 border"
|
||||
required
|
||||
aria-describedby="username-error"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Form Group -->
|
||||
|
||||
<!-- Form Group -->
|
||||
<div>
|
||||
<div class="flex justify-between items-center">
|
||||
<label for="password" class="block text-sm mb-2 dark:text-white">Passwort</label>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<input
|
||||
bind:value={password}
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
class="py-3 px-4 block w-full border-gray-200 rounded-md text-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 border"
|
||||
required
|
||||
aria-describedby="password-error"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Form Group -->
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="py-3 px-4 inline-flex justify-center items-center gap-2 rounded-md border border-transparent font-semibold bg-blue-500 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all text-sm dark:focus:ring-offset-gray-800"
|
||||
>Anmelden</button
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
<!-- End Form -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,26 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import userstore from '$lib/userstore';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
$: loginRendered = false;
|
||||
|
||||
onMount(async () => {
|
||||
try {
|
||||
await userstore.loginFromStorage();
|
||||
loginRendered = true;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
userstore.logout();
|
||||
goto('./login', {replaceState: true})
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if loginRendered}
|
||||
<slot />
|
||||
{:else}
|
||||
<div class="mx-auto mt-20">
|
||||
<h1 class="block text-center text-2xl font-bold text-gray-800 dark:text-white">Lade Anmeldedaten...</h1>
|
||||
</div>
|
||||
{/if}
|
@ -1,217 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { RunnerService, type ResponseRunner } from '@odit/lfk-client-js';
|
||||
import bwipjs from 'bwip-js';
|
||||
import lfkbackground from './background.png';
|
||||
|
||||
$: firstname = '';
|
||||
$: lastname = '';
|
||||
$: showResult = false;
|
||||
$: showError = false;
|
||||
|
||||
let response: ResponseRunner;
|
||||
const group = 1; //Default to Bürgerlauf
|
||||
|
||||
async function register() {
|
||||
try {
|
||||
response = (await RunnerService.runnerControllerPost({
|
||||
firstname,
|
||||
lastname,
|
||||
group
|
||||
})) as ResponseRunner;
|
||||
showError = false;
|
||||
showResult = true;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
showError = true;
|
||||
showResult = false;
|
||||
}
|
||||
firstname = '';
|
||||
lastname = '';
|
||||
}
|
||||
|
||||
function textToBase64Barcode(text: string, is_qrcode: boolean) {
|
||||
const canvas = document.createElement('canvas');
|
||||
let bcid = 'code128';
|
||||
if (is_qrcode) {
|
||||
bcid = 'qrcode';
|
||||
}
|
||||
bwipjs.toCanvas(canvas, {
|
||||
bcid,
|
||||
text: `${text}`,
|
||||
scale: 10,
|
||||
includetext: true,
|
||||
textxalign: 'center',
|
||||
backgroundcolor: 'ffffff',
|
||||
height: 10
|
||||
});
|
||||
return canvas.toDataURL('image/png');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="dark:bg-slate-900 bg-gray-100 flex h-full items-center py-16"
|
||||
style="background: url({lfkbackground});background-position: center center!important;background-size: contain!important;background-repeat: no-repeat!important;"
|
||||
>
|
||||
<div class="w-full max-w-md mx-auto p-6">
|
||||
<!-- <div
|
||||
class="mt-7 bg-white border border-gray-200 rounded-xl shadow-sm dark:bg-gray-800 dark:border-gray-700"
|
||||
> -->
|
||||
<div class="p-4 sm:p-7">
|
||||
<div class="mt-5">
|
||||
<!-- Form -->
|
||||
{#if !showResult}
|
||||
<div class="text-center">
|
||||
<h1 class="block text-7xl font-bold text-gray-800 dark:text-white">LfK!2023</h1>
|
||||
<h1 class="block text-4xl font-bold text-gray-800 dark:text-white">Registrierung</h1>
|
||||
<!-- <p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Melde dich für den LfK an</p> -->
|
||||
</div>
|
||||
<form class="mt-4 text-lg" on:submit|preventDefault={register}>
|
||||
<div class="grid gap-y-4">
|
||||
<!-- Form Group -->
|
||||
<div>
|
||||
<label for="firstname" class="block text-lg font-bold mb-2 sr-only">Vorname</label>
|
||||
<div class="relative">
|
||||
<input
|
||||
type="text"
|
||||
id="firstname"
|
||||
name="firstname"
|
||||
class="py-3 px-4 block w-full border-gray-200 rounded-md focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 border"
|
||||
required
|
||||
placeholder="Vorname"
|
||||
bind:value={firstname}
|
||||
aria-describedby="firstname-error"
|
||||
/>
|
||||
<!-- <div
|
||||
class:hidden={firstname || firstname.length != 0}
|
||||
class="absolute inset-y-0 right-0 flex items-center pointer-events-none pr-3"
|
||||
>
|
||||
<svg
|
||||
class="h-5 w-5 text-red-500"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
||||
/>
|
||||
</svg>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- <p
|
||||
class:hidden={firstname || firstname.length != 0}
|
||||
class="text-xs text-red-600 mt-2"
|
||||
id="firstname-error"
|
||||
>
|
||||
Bitte gebe deinen Vornamen ein
|
||||
</p> -->
|
||||
</div>
|
||||
<!-- End Form Group -->
|
||||
|
||||
<!-- Form Group -->
|
||||
<div>
|
||||
<label for="lastname" class="block text-lg font-bold mb-2 sr-only">Nachname</label>
|
||||
<div class="relative">
|
||||
<input
|
||||
type="lastname"
|
||||
id="lastname"
|
||||
name="lastname"
|
||||
class="py-3 px-4 block w-full border-gray-200 rounded-md focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 border"
|
||||
required
|
||||
placeholder="Nachname"
|
||||
aria-describedby="lastname-error"
|
||||
bind:value={lastname}
|
||||
/>
|
||||
<!-- <div
|
||||
class:hidden={lastname || lastname.length != 0}
|
||||
class="absolute inset-y-0 right-0 flex items-center pointer-events-none pr-3"
|
||||
>
|
||||
<svg
|
||||
class="h-5 w-5 text-red-500"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
||||
/>
|
||||
</svg>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- <p
|
||||
class:hidden={lastname || lastname.length != 0}
|
||||
class="text-xs text-red-600 mt-2"
|
||||
id="lastname-error"
|
||||
>
|
||||
Bitte gebe deinen Nachnamen ein
|
||||
</p> -->
|
||||
</div>
|
||||
<!-- End Form Group -->
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!firstname || !lastname}
|
||||
class="py-3 px-4 inline-flex justify-center items-center gap-2 rounded-md border border-transparent font-semibold disabled:opacity-70 bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all dark:focus:ring-offset-gray-800"
|
||||
>Anmelden</button
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
<!-- End Form -->
|
||||
{:else}
|
||||
<div class="mb-2 text-center">
|
||||
<h3 class="text-4xl font-semibold dark:text-white">
|
||||
{response.firstname}
|
||||
{response.lastname}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div class="mb-2 text-center">
|
||||
<img
|
||||
class="w-full md:w-auto mb-2 mx-auto bg-white p-4"
|
||||
alt="runner id"
|
||||
src={textToBase64Barcode(response.id.toString(), false)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mx-auto text-center items-center">
|
||||
<button
|
||||
on:click={() => {
|
||||
showResult = false;
|
||||
}}
|
||||
class="w-full py-3 px-4 inline-flex justify-center items-center gap-2 rounded-md border border-transparent font-semibold bg-blue-500 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all text-sm dark:focus:ring-offset-gray-800"
|
||||
>Fertig</button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed bottom-0 w-full text-center text-xl p-4">
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href="https://lauf-fuer-kaya.de/datenschutz/"
|
||||
class="underline">Datenschutzerklärung</a
|
||||
>
|
||||
|
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href="https://lauf-fuer-kaya.de/impressum/"
|
||||
class="underline">Impressum</a
|
||||
>
|
||||
<br />
|
||||
<br />
|
||||
<b class="font-bold">LfK!2023</b> powered by
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href="https://odit.services?ref=lfk"
|
||||
class="underline">ODIT.Services</a
|
||||
>
|
||||
</div>
|
@ -1,13 +1,11 @@
|
||||
import preprocess from 'svelte-preprocess';
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: [
|
||||
vitePreprocess(),
|
||||
preprocess({
|
||||
postcss: true
|
||||
})
|
||||
|
@ -1,11 +0,0 @@
|
||||
const config = {
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
|
||||
theme: {
|
||||
extend: {}
|
||||
},
|
||||
|
||||
plugins: []
|
||||
};
|
||||
|
||||
module.exports = config;
|
@ -1,6 +1,9 @@
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()]
|
||||
});
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
sveltekit(),
|
||||
],
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user