Compare commits
	
		
			22 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						408bd00288
	
				 | 
					
					
						|||
| 
						
						
							
						
						5646fedd4e
	
				 | 
					
					
						|||
| 
						
						
							
						
						962307317f
	
				 | 
					
					
						|||
| 
						
						
							
						
						5d440d0a0c
	
				 | 
					
					
						|||
| 
						
						
							
						
						54114a6547
	
				 | 
					
					
						|||
| 
						
						
							
						
						8a08e19e00
	
				 | 
					
					
						|||
| 
						
						
							
						
						642434b9fd
	
				 | 
					
					
						|||
| 
						
						
							
						
						b0feae1719
	
				 | 
					
					
						|||
| 
						
						
							
						
						cd8b98c624
	
				 | 
					
					
						|||
| 
						
						
							
						
						be4b8df02b
	
				 | 
					
					
						|||
| 
						
						
							
						
						d3d0b356ac
	
				 | 
					
					
						|||
| 
						
						
							
						
						3fdd8c80d8
	
				 | 
					
					
						|||
| 
						
						
							
						
						3e3846f1cb
	
				 | 
					
					
						|||
| 
						
						
							
						
						ed7242cc2a
	
				 | 
					
					
						|||
| 
						
						
							
						
						6152500652
	
				 | 
					
					
						|||
| 
						
						
							
						
						6ecaae1b8d
	
				 | 
					
					
						|||
| 
						
						
							
						
						5f97c9d8da
	
				 | 
					
					
						|||
| 
						
						
							
						
						e32c2f3069
	
				 | 
					
					
						|||
| 
						
						
							
						
						83826f966b
	
				 | 
					
					
						|||
| 
						
						
							
						
						1665fd67ae
	
				 | 
					
					
						|||
| 
						
						
							
						
						7516d3579f
	
				 | 
					
					
						|||
| 
						
						
							
						
						2c503f9b03
	
				 | 
					
					
						
							
								
								
									
										57
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -2,8 +2,65 @@
 | 
			
		||||
 | 
			
		||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
 | 
			
		||||
 | 
			
		||||
#### [1.2.4](https://git.odit.services/lfk/kiosk/compare/1.2.3...1.2.4)
 | 
			
		||||
 | 
			
		||||
- style(print): Adjust print styles for improved readability [`5646fed`](https://git.odit.services/lfk/kiosk/commit/5646fedd4e71b9fa25a5a80d03199f7897cda21c)
 | 
			
		||||
 | 
			
		||||
#### [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)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								README.md
									
									
									
									
									
								
							@@ -1,32 +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
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										4552
									
								
								licenses.md
									
									
									
									
									
								
							
							
						
						
									
										4552
									
								
								licenses.md
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										42
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								package.json
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
	"name": "@lfk/kiosk",
 | 
			
		||||
	"version": "1.1.3",
 | 
			
		||||
	"version": "1.2.4",
 | 
			
		||||
	"private": false,
 | 
			
		||||
	"license": "MIT",
 | 
			
		||||
	"repository": "https://git.odit.services/lfk/kiosk",
 | 
			
		||||
@@ -35,34 +35,32 @@
 | 
			
		||||
	"devDependencies": {
 | 
			
		||||
		"@odit/license-exporter": "0.2.0",
 | 
			
		||||
		"@philippdormann/release-it": "^1.0.0",
 | 
			
		||||
		"@sveltejs/adapter-static": "3.0.6",
 | 
			
		||||
		"@sveltejs/kit": "2.12.0",
 | 
			
		||||
		"@sveltejs/vite-plugin-svelte": "^5.0.2",
 | 
			
		||||
		"@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.18.0",
 | 
			
		||||
		"@typescript-eslint/parser": "8.18.0",
 | 
			
		||||
		"@typescript-eslint/eslint-plugin": "8.29.0",
 | 
			
		||||
		"@typescript-eslint/parser": "8.29.0",
 | 
			
		||||
		"auto-changelog": "2.5.0",
 | 
			
		||||
		"autoprefixer": "10.4.20",
 | 
			
		||||
		"eslint": "9.17.0",
 | 
			
		||||
		"eslint-config-prettier": "9.1.0",
 | 
			
		||||
		"postcss": "8.4.49",
 | 
			
		||||
		"postcss-load-config": "6.0.1",
 | 
			
		||||
		"prettier": "3.4.2",
 | 
			
		||||
		"prettier-plugin-svelte": "3.3.2",
 | 
			
		||||
		"svelte": "5.14.0",
 | 
			
		||||
		"svelte-check": "4.1.1",
 | 
			
		||||
		"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",
 | 
			
		||||
		"tailwindcss": "3.4.16",
 | 
			
		||||
		"tslib": "2.8.1",
 | 
			
		||||
		"typescript": "5.7.2",
 | 
			
		||||
		"vite": "6.0.3"
 | 
			
		||||
		"typescript": "5.8.3",
 | 
			
		||||
		"vite": "6.2.5"
 | 
			
		||||
	},
 | 
			
		||||
	"type": "module",
 | 
			
		||||
	"dependencies": {
 | 
			
		||||
		"@fontsource/athiti": "^5.1.0",
 | 
			
		||||
		"@odit/lfk-client-js": "1.1.3",
 | 
			
		||||
		"bwip-js": "4.5.1",
 | 
			
		||||
		"eslint-plugin-svelte": "^2.46.1"
 | 
			
		||||
		"@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": {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2081
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2081
									
								
								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,8 +1,9 @@
 | 
			
		||||
<script>
 | 
			
		||||
	import { OpenAPI } from '@odit/lfk-client-js';
 | 
			
		||||
	import '../app.postcss';
 | 
			
		||||
	import '@fontsource/athiti';
 | 
			
		||||
	import '../app.css';
 | 
			
		||||
	import { onMount } from 'svelte';
 | 
			
		||||
	import lfkbackground from './background.png';
 | 
			
		||||
 | 
			
		||||
	OpenAPI.BASE = 'https://run.lauf-fuer-kaya.de';
 | 
			
		||||
	onMount(() => {
 | 
			
		||||
@@ -13,10 +14,25 @@
 | 
			
		||||
			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"
 | 
			
		||||
	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>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,20 +4,27 @@
 | 
			
		||||
	import { onMount } from 'svelte';
 | 
			
		||||
	import Login from './Login.svelte';
 | 
			
		||||
 | 
			
		||||
	$: printEnabled = false;
 | 
			
		||||
 | 
			
		||||
	onMount(() => {
 | 
			
		||||
		const params = new URLSearchParams(window.location.search);
 | 
			
		||||
		if (params.get('print') === 'true') {
 | 
			
		||||
			printEnabled = true;
 | 
			
		||||
		}
 | 
			
		||||
		loginFromStorage();
 | 
			
		||||
	});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{#if $userState.isLoggedIn}
 | 
			
		||||
	<Register />
 | 
			
		||||
	<Register bind:printEnabled />
 | 
			
		||||
{:else}
 | 
			
		||||
	<Login />
 | 
			
		||||
{/if}
 | 
			
		||||
<div class="fixed bottom-0 w-full text-center text-xl p-4 dark:text-white select-none">
 | 
			
		||||
<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-lg">
 | 
			
		||||
	{#if $userState.isLoggedIn}
 | 
			
		||||
		<b class="font-bold">LfK!2025</b> powered by
 | 
			
		||||
		<b class="font-bold">ODIT.Services</b>
 | 
			
		||||
		<b class="font-bold print:hidden">LfK!2025</b> powered by
 | 
			
		||||
		<b class="font-bold print:hidden">ODIT.Services</b>
 | 
			
		||||
		<b> LfK!2025 powered by ODIT.Services</b>
 | 
			
		||||
	{:else}
 | 
			
		||||
		<a
 | 
			
		||||
			rel="noopener noreferrer"
 | 
			
		||||
@@ -33,7 +40,6 @@
 | 
			
		||||
			class="underline">Impressum</a
 | 
			
		||||
		>
 | 
			
		||||
		<br />
 | 
			
		||||
		<br />
 | 
			
		||||
		<b class="font-bold">LfK!2025</b> powered by
 | 
			
		||||
		<a
 | 
			
		||||
			rel="noopener noreferrer"
 | 
			
		||||
 
 | 
			
		||||
@@ -26,39 +26,27 @@
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<!--  -->
 | 
			
		||||
<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">
 | 
			
		||||
<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">
 | 
			
		||||
		<!-- <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>
 | 
			
		||||
		</div> -->
 | 
			
		||||
		<!-- End Title -->
 | 
			
		||||
 | 
			
		||||
		<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>
 | 
			
		||||
		<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"
 | 
			
		||||
				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>
 | 
			
		||||
@@ -70,16 +58,17 @@
 | 
			
		||||
			<div class="grid gap-y-4">
 | 
			
		||||
				<!-- Form Group -->
 | 
			
		||||
				<div>
 | 
			
		||||
								<label for="username" class="block text-sm mb-2 dark:text-white">Benutzername</label
 | 
			
		||||
								>
 | 
			
		||||
					<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"
 | 
			
		||||
										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"
 | 
			
		||||
							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"
 | 
			
		||||
						/>
 | 
			
		||||
@@ -90,7 +79,7 @@
 | 
			
		||||
				<!-- Form Group -->
 | 
			
		||||
				<div>
 | 
			
		||||
					<div class="flex justify-between items-center">
 | 
			
		||||
									<label for="password" class="block text-sm mb-2 dark:text-white">Passwort</label>
 | 
			
		||||
						<label for="password" class="block font-semibold">Passwort</label>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="relative">
 | 
			
		||||
						<input
 | 
			
		||||
@@ -99,7 +88,8 @@
 | 
			
		||||
							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"
 | 
			
		||||
							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"
 | 
			
		||||
						/>
 | 
			
		||||
@@ -109,7 +99,7 @@
 | 
			
		||||
 | 
			
		||||
				<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"
 | 
			
		||||
					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>
 | 
			
		||||
@@ -117,6 +107,3 @@
 | 
			
		||||
		<!-- End Form -->
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import { RunnerService, type ResponseRunner } from '@odit/lfk-client-js';
 | 
			
		||||
	import bwipjs from 'bwip-js';
 | 
			
		||||
	import lfkbackground from './background.png';
 | 
			
		||||
	import { onMount } from 'svelte';
 | 
			
		||||
 | 
			
		||||
	$: firstname = '';
 | 
			
		||||
@@ -10,6 +9,8 @@
 | 
			
		||||
	$: doneButtonEnabled = false;
 | 
			
		||||
	$: showResult = false;
 | 
			
		||||
 | 
			
		||||
	export let printEnabled = false;
 | 
			
		||||
 | 
			
		||||
	let response: ResponseRunner;
 | 
			
		||||
	const group = 1; //Default to Bürgerlauf
 | 
			
		||||
 | 
			
		||||
@@ -42,9 +43,15 @@
 | 
			
		||||
				firstname,
 | 
			
		||||
				lastname,
 | 
			
		||||
				email: emailToSend,
 | 
			
		||||
				group
 | 
			
		||||
				group,
 | 
			
		||||
				created_via: 'kiosk'
 | 
			
		||||
			})) as ResponseRunner;
 | 
			
		||||
			showResult = true;
 | 
			
		||||
			if (printEnabled) {
 | 
			
		||||
				setTimeout(() => {
 | 
			
		||||
					window.print();
 | 
			
		||||
				}, 200);
 | 
			
		||||
			}
 | 
			
		||||
			setTimeout(() => {
 | 
			
		||||
				doneButtonEnabled = true;
 | 
			
		||||
				setTimeout(() => {
 | 
			
		||||
@@ -63,12 +70,18 @@
 | 
			
		||||
 | 
			
		||||
	function textToBase64Barcode(text: string, is_qrcode: boolean) {
 | 
			
		||||
		const canvas = document.createElement('canvas');
 | 
			
		||||
		let bcid = 'code128';
 | 
			
		||||
		if (is_qrcode) {
 | 
			
		||||
			bcid = 'qrcode';
 | 
			
		||||
		}
 | 
			
		||||
			bwipjs.toCanvas(canvas, {
 | 
			
		||||
			bcid,
 | 
			
		||||
				bcid: 'qrcode',
 | 
			
		||||
				text: `${text}`,
 | 
			
		||||
				scale: 10,
 | 
			
		||||
				includetext: false,
 | 
			
		||||
				textxalign: 'center',
 | 
			
		||||
				backgroundcolor: 'ffffff'
 | 
			
		||||
			});
 | 
			
		||||
		} else {
 | 
			
		||||
			bwipjs.toCanvas(canvas, {
 | 
			
		||||
				bcid: 'code128',
 | 
			
		||||
				text: `${text}`,
 | 
			
		||||
				scale: 10,
 | 
			
		||||
				includetext: true,
 | 
			
		||||
@@ -76,6 +89,7 @@
 | 
			
		||||
				backgroundcolor: 'ffffff',
 | 
			
		||||
				height: 10
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
		return canvas.toDataURL('image/png');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -84,16 +98,13 @@
 | 
			
		||||
	});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<div
 | 
			
		||||
	class="dark:bg-slate-900 bg-gray-100 flex h-full items-center py-16 select-none"
 | 
			
		||||
	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="flex h-full items-center py-16 select-none 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">
 | 
			
		||||
			<div class="mt-5">
 | 
			
		||||
		<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">
 | 
			
		||||
@@ -110,6 +121,7 @@
 | 
			
		||||
									<input
 | 
			
		||||
										on:keydown={(e) => {
 | 
			
		||||
											if (e.keyCode === 13) {
 | 
			
		||||
												e.preventDefault();
 | 
			
		||||
												document.getElementById('lastname')?.focus();
 | 
			
		||||
											}
 | 
			
		||||
											if (e.keyCode === 40) {
 | 
			
		||||
@@ -120,7 +132,7 @@
 | 
			
		||||
										autocomplete="one-time-code"
 | 
			
		||||
										id="firstname"
 | 
			
		||||
										name="firstname"
 | 
			
		||||
										class="placeholder:text-black dark:placeholder:text-white 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-gray-400 border"
 | 
			
		||||
										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}
 | 
			
		||||
@@ -160,8 +172,8 @@
 | 
			
		||||
								<div class="relative">
 | 
			
		||||
									<input
 | 
			
		||||
										on:keydown={(e) => {
 | 
			
		||||
											console.log(e.keyCode);
 | 
			
		||||
											if (e.keyCode === 13) {
 | 
			
		||||
												e.preventDefault();
 | 
			
		||||
												document.getElementById('email')?.focus();
 | 
			
		||||
											}
 | 
			
		||||
											if (e.keyCode === 38) {
 | 
			
		||||
@@ -175,7 +187,7 @@
 | 
			
		||||
										type="lastname"
 | 
			
		||||
										id="lastname"
 | 
			
		||||
										name="lastname"
 | 
			
		||||
										class="placeholder:text-black dark:placeholder:text-white 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-gray-400 border"
 | 
			
		||||
										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"
 | 
			
		||||
@@ -217,8 +229,8 @@
 | 
			
		||||
								<div class="relative">
 | 
			
		||||
									<input
 | 
			
		||||
										on:keydown={(e) => {
 | 
			
		||||
											console.log(e.keyCode);
 | 
			
		||||
											if (e.keyCode === 13) {
 | 
			
		||||
												e.preventDefault();
 | 
			
		||||
												document.getElementById('submit')?.focus();
 | 
			
		||||
											}
 | 
			
		||||
											if (e.keyCode === 38) {
 | 
			
		||||
@@ -232,7 +244,7 @@
 | 
			
		||||
										type="email"
 | 
			
		||||
										id="email"
 | 
			
		||||
										name="email"
 | 
			
		||||
										class="placeholder:text-black dark:placeholder:text-white 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-gray-400 border"
 | 
			
		||||
										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}
 | 
			
		||||
@@ -264,12 +276,37 @@
 | 
			
		||||
									</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"
 | 
			
		||||
								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>
 | 
			
		||||
@@ -277,21 +314,41 @@
 | 
			
		||||
					<!-- End Form -->
 | 
			
		||||
				{:else}
 | 
			
		||||
					<div class="mb-2 text-center">
 | 
			
		||||
						<h3 class="text-4xl font-semibold dark:text-white">
 | 
			
		||||
						<h3 class="text-4xl font-semibold dark:text-white print:text-3xl">
 | 
			
		||||
							{response.firstname}
 | 
			
		||||
							{response.lastname}
 | 
			
		||||
						</h3>
 | 
			
		||||
						<h4 class="font-semibold dark:text-white hidden print:block print:text-xl">
 | 
			
		||||
							{response.id}
 | 
			
		||||
						</h4>
 | 
			
		||||
					</div>
 | 
			
		||||
 | 
			
		||||
					<div class="mb-2 text-center">
 | 
			
		||||
						<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-lg 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"
 | 
			
		||||
							alt="runner id"
 | 
			
		||||
							src={textToBase64Barcode(response.id.toString(), false)}
 | 
			
		||||
						alt="runner selfservice"
 | 
			
		||||
						src={textToBase64Barcode(response.selfserviceLink.toString(), true)}
 | 
			
		||||
						/>
 | 
			
		||||
						<h3 class="text-lg 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">
 | 
			
		||||
					<div class="mx-auto text-center items-center print:hidden">
 | 
			
		||||
						<button
 | 
			
		||||
							class:opacity-50={!doneButtonEnabled}
 | 
			
		||||
							disabled={!doneButtonEnabled}
 | 
			
		||||
@@ -301,7 +358,7 @@
 | 
			
		||||
								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"
 | 
			
		||||
							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>
 | 
			
		||||
 
 | 
			
		||||
@@ -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(),
 | 
			
		||||
	],
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user