Compare commits
	
		
			5 Commits
		
	
	
		
			1.10.0
			...
			feature/sp
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						c3226c37c9
	
				 | 
					
					
						|||
| 
						
						
							
						
						210140fd67
	
				 | 
					
					
						|||
| 
						
						
							
						
						35e58d233e
	
				 | 
					
					
						|||
| 
						
						
							
						
						a09bf31e22
	
				 | 
					
					
						|||
| 
						
						
							
						
						7c31fba83a
	
				 | 
					
					
						
							
								
								
									
										35
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -2,44 +2,9 @@
 | 
			
		||||
 | 
			
		||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
 | 
			
		||||
 | 
			
		||||
#### [1.10.0](https://git.odit.services/lfk/frontend/compare/1.9.11...1.10.0)
 | 
			
		||||
 | 
			
		||||
- feat: working CardAssignment [`ac4ef8f`](https://git.odit.services/lfk/frontend/commit/ac4ef8fb6ded5c5d5678a651420e356b3ef45399)
 | 
			
		||||
 | 
			
		||||
#### [1.9.11](https://git.odit.services/lfk/frontend/compare/1.9.10...1.9.11)
 | 
			
		||||
 | 
			
		||||
> 8 April 2025
 | 
			
		||||
 | 
			
		||||
- feat(dash): add runnersViaKiosk [`5291f8a`](https://git.odit.services/lfk/frontend/commit/5291f8a4d1721cd0c745191ebc85f221c34a23c8)
 | 
			
		||||
- chore(release): 1.9.11 [`eae0afd`](https://git.odit.services/lfk/frontend/commit/eae0afda23a54020e25821c0188d8cbec3139593)
 | 
			
		||||
 | 
			
		||||
#### [1.9.10](https://git.odit.services/lfk/frontend/compare/1.9.9...1.9.10)
 | 
			
		||||
 | 
			
		||||
> 8 April 2025
 | 
			
		||||
 | 
			
		||||
- feat: add experimental ui for mobile card assignment [`d7c9c27`](https://git.odit.services/lfk/frontend/commit/d7c9c27ec7a1fea1cbaf26914843d044bbae32fe)
 | 
			
		||||
- chore(release): 1.9.10 [`e2d7de1`](https://git.odit.services/lfk/frontend/commit/e2d7de1e9e1fd134f54876fa80f19f94fbea3672)
 | 
			
		||||
 | 
			
		||||
#### [1.9.9](https://git.odit.services/lfk/frontend/compare/1.9.8...1.9.9)
 | 
			
		||||
 | 
			
		||||
> 4 April 2025
 | 
			
		||||
 | 
			
		||||
- chore(release): 1.9.9 [`153b1b3`](https://git.odit.services/lfk/frontend/commit/153b1b3c2badee4826be614c3dbaafc10e1fbfea)
 | 
			
		||||
- fix(CopyScanStationTokenModal): code sizes [`ec63c7c`](https://git.odit.services/lfk/frontend/commit/ec63c7c1c51ccaf25bdd1eacffda66c820003a4c)
 | 
			
		||||
 | 
			
		||||
#### [1.9.8](https://git.odit.services/lfk/frontend/compare/1.9.7...1.9.8)
 | 
			
		||||
 | 
			
		||||
> 2 April 2025
 | 
			
		||||
 | 
			
		||||
- feat(GenerateSponsoringContracts): show download progress [`e261d5e`](https://git.odit.services/lfk/frontend/commit/e261d5e345f3175672bf86646ed838dd23400e50)
 | 
			
		||||
- chore(release): 1.9.8 [`05c2535`](https://git.odit.services/lfk/frontend/commit/05c253569877a45f3c4759262255ca70aa9ee4a3)
 | 
			
		||||
 | 
			
		||||
#### [1.9.7](https://git.odit.services/lfk/frontend/compare/1.9.6...1.9.7)
 | 
			
		||||
 | 
			
		||||
> 2 April 2025
 | 
			
		||||
 | 
			
		||||
- fix: ImportRunnerModal scrolling & team select [`766eeab`](https://git.odit.services/lfk/frontend/commit/766eeab49fb3ca5715c19dbf9bc53cb71124d3df)
 | 
			
		||||
- chore(release): 1.9.7 [`c00497d`](https://git.odit.services/lfk/frontend/commit/c00497d7760a935965cc83213f72f35999a3c168)
 | 
			
		||||
 | 
			
		||||
#### [1.9.6](https://git.odit.services/lfk/frontend/compare/1.9.5...1.9.6)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 | 
			
		||||
  <body>
 | 
			
		||||
    <span style="display: none; visibility: hidden" id="buildinfo"
 | 
			
		||||
      >RELEASE_INFO-1.10.0-RELEASE_INFO</span
 | 
			
		||||
      >RELEASE_INFO-1.9.7-RELEASE_INFO</span
 | 
			
		||||
    >
 | 
			
		||||
    <noscript>You need to enable JavaScript to run this app.</noscript>
 | 
			
		||||
    <script src="/env.js"></script>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@odit/lfk-frontend",
 | 
			
		||||
  "version": "1.10.0",
 | 
			
		||||
  "version": "1.9.7",
 | 
			
		||||
  "type": "module",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "i18n-order": "node order.js",
 | 
			
		||||
@@ -43,13 +43,12 @@
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@fontsource/athiti": "^5.2.5",
 | 
			
		||||
    "@odit/lfk-client-js": "1.2.2",
 | 
			
		||||
    "@odit/lfk-client-js": "1.2.0",
 | 
			
		||||
    "@paralleldrive/cuid2": "2.2.2",
 | 
			
		||||
    "@tanstack/svelte-table": "8.9.1",
 | 
			
		||||
    "bwip-js": "3.4.0",
 | 
			
		||||
    "check-password-strength": "2.0.10",
 | 
			
		||||
    "csvtojson": "2.0.10",
 | 
			
		||||
    "html5-qrcode": "^2.3.8",
 | 
			
		||||
    "localforage": "1.10.0",
 | 
			
		||||
    "marked": "4.3.0",
 | 
			
		||||
    "svelte": "3.58.0",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										36
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@@ -12,8 +12,8 @@ importers:
 | 
			
		||||
        specifier: ^5.2.5
 | 
			
		||||
        version: 5.2.5
 | 
			
		||||
      '@odit/lfk-client-js':
 | 
			
		||||
        specifier: 1.2.2
 | 
			
		||||
        version: 1.2.2
 | 
			
		||||
        specifier: 1.2.0
 | 
			
		||||
        version: 1.2.0
 | 
			
		||||
      '@paralleldrive/cuid2':
 | 
			
		||||
        specifier: 2.2.2
 | 
			
		||||
        version: 2.2.2
 | 
			
		||||
@@ -29,9 +29,6 @@ importers:
 | 
			
		||||
      csvtojson:
 | 
			
		||||
        specifier: 2.0.10
 | 
			
		||||
        version: 2.0.10
 | 
			
		||||
      html5-qrcode:
 | 
			
		||||
        specifier: ^2.3.8
 | 
			
		||||
        version: 2.3.8
 | 
			
		||||
      localforage:
 | 
			
		||||
        specifier: 1.10.0
 | 
			
		||||
        version: 1.10.0
 | 
			
		||||
@@ -80,7 +77,7 @@ importers:
 | 
			
		||||
        version: 3.3.3(prettier@3.5.3)(svelte@3.58.0)
 | 
			
		||||
      release-it:
 | 
			
		||||
        specifier: 17.10.0
 | 
			
		||||
        version: 17.10.0(typescript@5.8.3)
 | 
			
		||||
        version: 17.10.0
 | 
			
		||||
      svelte-select:
 | 
			
		||||
        specifier: 3.17.0
 | 
			
		||||
        version: 3.17.0
 | 
			
		||||
@@ -355,8 +352,8 @@ packages:
 | 
			
		||||
  '@octokit/types@13.6.1':
 | 
			
		||||
    resolution: {integrity: sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==}
 | 
			
		||||
 | 
			
		||||
  '@odit/lfk-client-js@1.2.2':
 | 
			
		||||
    resolution: {integrity: sha512-6UflZ8T8rV3yaBCMGC/fbBbsQkcld2RijcGrtv48bTqHGoUUG8aXuMXU7741I+eucxfxcal2/JfHih/I87IX7A==}
 | 
			
		||||
  '@odit/lfk-client-js@1.2.0':
 | 
			
		||||
    resolution: {integrity: sha512-RR/Ij3PDMF840VJtphO51k+3voJcTlvRIxzTFBkvrwriBmLJwchBQxq40K4/kyVIFH7lLwO3uJy0PaxgEoTbFQ==}
 | 
			
		||||
 | 
			
		||||
  '@odit/license-exporter@0.2.0':
 | 
			
		||||
    resolution: {integrity: sha512-RRyfQzDLoyLQlGSd8ThJQ3h0fiCe4tkmm935AUvSVQWP+p88FcnI4iaktKBJJVBnIpDhkv/7sDSA5dFc/QMM5w==}
 | 
			
		||||
@@ -927,9 +924,6 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
 | 
			
		||||
    engines: {node: '>= 0.4'}
 | 
			
		||||
 | 
			
		||||
  html5-qrcode@2.3.8:
 | 
			
		||||
    resolution: {integrity: sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ==}
 | 
			
		||||
 | 
			
		||||
  http-proxy-agent@7.0.2:
 | 
			
		||||
    resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
 | 
			
		||||
    engines: {node: '>= 14'}
 | 
			
		||||
@@ -1800,11 +1794,6 @@ packages:
 | 
			
		||||
  type@2.7.2:
 | 
			
		||||
    resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==}
 | 
			
		||||
 | 
			
		||||
  typescript@5.8.3:
 | 
			
		||||
    resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
 | 
			
		||||
    engines: {node: '>=14.17'}
 | 
			
		||||
    hasBin: true
 | 
			
		||||
 | 
			
		||||
  uglify-js@3.19.3:
 | 
			
		||||
    resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==}
 | 
			
		||||
    engines: {node: '>=0.8.0'}
 | 
			
		||||
@@ -2176,7 +2165,7 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@octokit/openapi-types': 22.2.0
 | 
			
		||||
 | 
			
		||||
  '@odit/lfk-client-js@1.2.2': {}
 | 
			
		||||
  '@odit/lfk-client-js@1.2.0': {}
 | 
			
		||||
 | 
			
		||||
  '@odit/license-exporter@0.2.0':
 | 
			
		||||
    dependencies:
 | 
			
		||||
@@ -2450,14 +2439,12 @@ snapshots:
 | 
			
		||||
      graceful-fs: 4.2.11
 | 
			
		||||
      xdg-basedir: 5.1.0
 | 
			
		||||
 | 
			
		||||
  cosmiconfig@9.0.0(typescript@5.8.3):
 | 
			
		||||
  cosmiconfig@9.0.0:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      env-paths: 2.2.1
 | 
			
		||||
      import-fresh: 3.3.0
 | 
			
		||||
      js-yaml: 4.1.0
 | 
			
		||||
      parse-json: 5.2.0
 | 
			
		||||
    optionalDependencies:
 | 
			
		||||
      typescript: 5.8.3
 | 
			
		||||
 | 
			
		||||
  crc-32@1.2.2: {}
 | 
			
		||||
 | 
			
		||||
@@ -2778,8 +2765,6 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      function-bind: 1.1.2
 | 
			
		||||
 | 
			
		||||
  html5-qrcode@2.3.8: {}
 | 
			
		||||
 | 
			
		||||
  http-proxy-agent@7.0.2:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      agent-base: 7.1.1
 | 
			
		||||
@@ -3337,14 +3322,14 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      rc: 1.2.8
 | 
			
		||||
 | 
			
		||||
  release-it@17.10.0(typescript@5.8.3):
 | 
			
		||||
  release-it@17.10.0:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@iarna/toml': 2.2.5
 | 
			
		||||
      '@octokit/rest': 20.1.1
 | 
			
		||||
      async-retry: 1.3.3
 | 
			
		||||
      chalk: 5.3.0
 | 
			
		||||
      ci-info: 4.1.0
 | 
			
		||||
      cosmiconfig: 9.0.0(typescript@5.8.3)
 | 
			
		||||
      cosmiconfig: 9.0.0
 | 
			
		||||
      execa: 8.0.0
 | 
			
		||||
      git-url-parse: 14.0.0
 | 
			
		||||
      globby: 14.0.2
 | 
			
		||||
@@ -3622,9 +3607,6 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  type@2.7.2: {}
 | 
			
		||||
 | 
			
		||||
  typescript@5.8.3:
 | 
			
		||||
    optional: true
 | 
			
		||||
 | 
			
		||||
  uglify-js@3.19.3:
 | 
			
		||||
    optional: true
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								public/beep.mp3
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/beep.mp3
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -41,7 +41,6 @@
 | 
			
		||||
  import Settings from "./components/settings/Settings.svelte";
 | 
			
		||||
  import Transition from "./components/base/Transition.svelte";
 | 
			
		||||
  import Orgs from "./components/orgs/Orgs.svelte";
 | 
			
		||||
  import CardAssignment from "./components/general/CardAssignment.svelte";
 | 
			
		||||
  import Runners from "./components/runners/Runners.svelte";
 | 
			
		||||
  import Footer from "./components/general/Footer.svelte";
 | 
			
		||||
  import TracksOverview from "./components/tracks/TracksOverview.svelte";
 | 
			
		||||
@@ -142,11 +141,6 @@
 | 
			
		||||
            <RunnerDetail {params} />
 | 
			
		||||
          </Route>
 | 
			
		||||
        </Route>
 | 
			
		||||
        <Route path="/cardassignment/*">
 | 
			
		||||
          <Route path="/">
 | 
			
		||||
            <CardAssignment />
 | 
			
		||||
          </Route>
 | 
			
		||||
        </Route>
 | 
			
		||||
        <Route path="/teams/*">
 | 
			
		||||
          <Route path="/">
 | 
			
		||||
            <Teams />
 | 
			
		||||
 
 | 
			
		||||
@@ -41,27 +41,7 @@
 | 
			
		||||
				</svg>
 | 
			
		||||
				<span>{$_("dashboard-title")}</span>
 | 
			
		||||
			</a>
 | 
			
		||||
			{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:GET") && store.state.jwtinfo.userdetails.permissions.includes("CARD:GET")}
 | 
			
		||||
				<a
 | 
			
		||||
					class:activenav={$router.path.includes("/cardassignment/")}
 | 
			
		||||
					class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900 w-full font-semibold"
 | 
			
		||||
					href="/cardassignment/"
 | 
			
		||||
				>
 | 
			
		||||
					<svg
 | 
			
		||||
						xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
						viewBox="0 0 24 24"
 | 
			
		||||
						fill="currentColor"
 | 
			
		||||
						class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600"
 | 
			
		||||
					>
 | 
			
		||||
						<path
 | 
			
		||||
							fill-rule="evenodd"
 | 
			
		||||
							d="M14.615 1.595a.75.75 0 0 1 .359.852L12.982 9.75h7.268a.75.75 0 0 1 .548 1.262l-10.5 11.25a.75.75 0 0 1-1.272-.71l1.992-7.302H3.75a.75.75 0 0 1-.548-1.262l10.5-11.25a.75.75 0 0 1 .913-.143Z"
 | 
			
		||||
							clip-rule="evenodd"
 | 
			
		||||
						/>
 | 
			
		||||
					</svg>
 | 
			
		||||
 | 
			
		||||
					<span>Card Assignment</span>
 | 
			
		||||
				</a>
 | 
			
		||||
			{#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:GET")}
 | 
			
		||||
				<a
 | 
			
		||||
					class:activenav={$router.path.includes("/runners/")}
 | 
			
		||||
					class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900 w-full font-semibold"
 | 
			
		||||
 
 | 
			
		||||
@@ -234,23 +234,6 @@
 | 
			
		||||
					/></svg
 | 
			
		||||
				>
 | 
			
		||||
			</StatCard>
 | 
			
		||||
			<StatCard
 | 
			
		||||
				title={$_('runners_via_kiosk')}
 | 
			
		||||
				value={stats.runnersViaKiosk}
 | 
			
		||||
				href="/runners/"
 | 
			
		||||
			>
 | 
			
		||||
				<svg
 | 
			
		||||
					height="24"
 | 
			
		||||
					width="24"
 | 
			
		||||
					fill="currentColor"
 | 
			
		||||
					xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
					viewBox="0 0 24 24"
 | 
			
		||||
					><path d="M0 0h24v24H0z" fill="none" />
 | 
			
		||||
					<path
 | 
			
		||||
						d="M13.49 5.48c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-3.6 13.9l1-4.4 2.1 2v6h2v-7.5l-2.1-2 .6-3c1.3 1.5 3.3 2.5 5.5 2.5v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1l-5.2 2.2v4.7h2v-3.4l1.8-.7-1.6 8.1-4.9-1-.4 2 7 1.4z"
 | 
			
		||||
					/></svg
 | 
			
		||||
				>
 | 
			
		||||
			</StatCard>
 | 
			
		||||
		</div>
 | 
			
		||||
	{:catch error}
 | 
			
		||||
		<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,123 +0,0 @@
 | 
			
		||||
<script>
 | 
			
		||||
	import { RunnerCardService, RunnerService } from "@odit/lfk-client-js";
 | 
			
		||||
	import QrCodeScanner from "./QrCodeScanner.svelte";
 | 
			
		||||
	let state = "scan_runner";
 | 
			
		||||
	let runnerinfo = { id: 0, firstname: "", lastname: "" };
 | 
			
		||||
	let cardCode = "";
 | 
			
		||||
	$: scannerActive = state.includes("scan");
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<div class="p-4">
 | 
			
		||||
	<h3 class="text-3xl font-bold">Card Assignment for Mobile</h3>
 | 
			
		||||
	<!-- <p>state</p>
 | 
			
		||||
	<p>{state}</p>
 | 
			
		||||
	<p>scannerActive</p>
 | 
			
		||||
	<p>{scannerActive}</p> -->
 | 
			
		||||
	{#if state.includes("scan_")}
 | 
			
		||||
		<!--  -->
 | 
			
		||||
		{#if state === "scan_runner"}
 | 
			
		||||
			<h3 class="text-xl font-bold">Scan Runner (Selfservice QR)</h3>
 | 
			
		||||
		{/if}
 | 
			
		||||
		{#if state === "scan_card"}
 | 
			
		||||
			<h3 class="text-xl font-bold">Runner Scanned</h3>
 | 
			
		||||
			<p>{runnerinfo.firstname} {runnerinfo.lastname} [#{runnerinfo.id}]</p>
 | 
			
		||||
			<h3 class="text-xl font-bold">Scan Card (Code 128 Barcode)</h3>
 | 
			
		||||
		{/if}
 | 
			
		||||
		<QrCodeScanner
 | 
			
		||||
			paused={!scannerActive}
 | 
			
		||||
			on:detect={(e) => {
 | 
			
		||||
				console.log({ type: "DETECT", code: e.detail.decodedText });
 | 
			
		||||
				if (state === "scan_runner") {
 | 
			
		||||
					if (
 | 
			
		||||
						e.detail.decodedText.includes(
 | 
			
		||||
							"https://portal.lauf-fuer-kaya.de/profile/"
 | 
			
		||||
						)
 | 
			
		||||
					) {
 | 
			
		||||
						const runnerID = JSON.parse(
 | 
			
		||||
							atob(
 | 
			
		||||
								e.detail.decodedText
 | 
			
		||||
									.replace("https://portal.lauf-fuer-kaya.de/profile/", "")
 | 
			
		||||
									.split(".")[1]
 | 
			
		||||
							)
 | 
			
		||||
						).id;
 | 
			
		||||
						new Audio("/beep.mp3").play();
 | 
			
		||||
						RunnerService.runnerControllerGetOne(runnerID).then((runner) => {
 | 
			
		||||
							console.log(runner);
 | 
			
		||||
							runnerinfo = runner;
 | 
			
		||||
						});
 | 
			
		||||
						state = "scan_card";
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (state === "scan_card") {
 | 
			
		||||
					if (
 | 
			
		||||
						!e.detail.decodedText.includes(
 | 
			
		||||
							"https://portal.lauf-fuer-kaya.de/profile/"
 | 
			
		||||
						)
 | 
			
		||||
					) {
 | 
			
		||||
						cardCode = e.detail.decodedText;
 | 
			
		||||
						new Audio("/beep.mp3").play();
 | 
			
		||||
						state = "assigning";
 | 
			
		||||
						RunnerCardService.runnerCardControllerGetAll().then((cards) => {
 | 
			
		||||
							console.log(cards);
 | 
			
		||||
							const card = cards.find((c) => c.code === cardCode);
 | 
			
		||||
							if (card) {
 | 
			
		||||
								console.log("card found", card);
 | 
			
		||||
								RunnerCardService.runnerCardControllerPut(card.id, {
 | 
			
		||||
									enabled: true,
 | 
			
		||||
									id: card.id,
 | 
			
		||||
									runner: runnerinfo.id,
 | 
			
		||||
								}).then(() => {
 | 
			
		||||
									state = "done";
 | 
			
		||||
								});
 | 
			
		||||
							} else {
 | 
			
		||||
								state = "error_card_404";
 | 
			
		||||
							}
 | 
			
		||||
						});
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}}
 | 
			
		||||
			width={320}
 | 
			
		||||
			height={320}
 | 
			
		||||
			class="w-full max-w-sm bg-neutral-300 rounded-lg overflow-hidden"
 | 
			
		||||
		/>
 | 
			
		||||
		{#if state === "scan_card"}
 | 
			
		||||
			<button
 | 
			
		||||
				on:click={() => {
 | 
			
		||||
					state = "scan_runner";
 | 
			
		||||
					runnerinfo = { id: 0, firstname: "", lastname: "" };
 | 
			
		||||
					cardCode = "";
 | 
			
		||||
				}}
 | 
			
		||||
				type="button"
 | 
			
		||||
				class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-red-100 text-red-800 hover:bg-red-200 focus:outline-hidden focus:bg-red-200 disabled:opacity-50 disabled:pointer-events-none dark:text-red-500 dark:bg-red-800/30 dark:hover:bg-red-800/20 dark:focus:bg-red-800/20 w-full mt-2"
 | 
			
		||||
			>
 | 
			
		||||
				Cancel
 | 
			
		||||
			</button>
 | 
			
		||||
		{/if}
 | 
			
		||||
		<!--  -->
 | 
			
		||||
	{:else}
 | 
			
		||||
		<!--  -->
 | 
			
		||||
		{#if state === "assigning"}
 | 
			
		||||
			<p>Assigning Card {cardCode} ⌛</p>
 | 
			
		||||
			<p>Please wait a moment while we assign the card...</p>
 | 
			
		||||
		{/if}
 | 
			
		||||
		{#if state === "done"}
 | 
			
		||||
			<p>
 | 
			
		||||
				Assigned Card {cardCode} to {runnerinfo.firstname}
 | 
			
		||||
				{runnerinfo.lastname} [#{runnerinfo.id}] ✅
 | 
			
		||||
			</p>
 | 
			
		||||
			<button
 | 
			
		||||
				on:click={() => {
 | 
			
		||||
					// state = "scan_runner";
 | 
			
		||||
					// runnerinfo = { id: 0, firstname: "", lastname: "" };
 | 
			
		||||
					// cardCode = "";
 | 
			
		||||
					location.reload();
 | 
			
		||||
				}}
 | 
			
		||||
				type="button"
 | 
			
		||||
				class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-100 text-blue-800 hover:bg-blue-200 focus:outline-hidden focus:bg-blue-200 disabled:opacity-50 disabled:pointer-events-none dark:text-blue-500 dark:bg-blue-800/30 dark:hover:bg-blue-800/20 dark:focus:bg-blue-800/20 w-full mt-2"
 | 
			
		||||
			>
 | 
			
		||||
				Done
 | 
			
		||||
			</button>
 | 
			
		||||
		{/if}
 | 
			
		||||
		<!--  -->
 | 
			
		||||
	{/if}
 | 
			
		||||
</div>
 | 
			
		||||
@@ -1,84 +0,0 @@
 | 
			
		||||
<script>
 | 
			
		||||
	import { onMount, createEventDispatcher } from "svelte";
 | 
			
		||||
	import {
 | 
			
		||||
		Html5QrcodeScanner,
 | 
			
		||||
		Html5QrcodeScanType,
 | 
			
		||||
		Html5QrcodeSupportedFormats,
 | 
			
		||||
		Html5QrcodeScannerState,
 | 
			
		||||
	} from "html5-qrcode";
 | 
			
		||||
 | 
			
		||||
	export let width;
 | 
			
		||||
	export let height;
 | 
			
		||||
	export let paused = false;
 | 
			
		||||
 | 
			
		||||
	const dispatch = createEventDispatcher();
 | 
			
		||||
 | 
			
		||||
	function onScanSuccess(decodedText, decodedResult) {
 | 
			
		||||
		if (!paused) {
 | 
			
		||||
			dispatch("detect", { decodedText });
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// usually better to ignore and keep scanning
 | 
			
		||||
	function onScanFailure(message) {
 | 
			
		||||
		if (!paused) {
 | 
			
		||||
			dispatch("error", { message });
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	let scanner;
 | 
			
		||||
	onMount(() => {
 | 
			
		||||
		scanner = new Html5QrcodeScanner(
 | 
			
		||||
			"qr-scanner",
 | 
			
		||||
			{
 | 
			
		||||
				fps: 10,
 | 
			
		||||
				rememberLastUsedCamera: true,
 | 
			
		||||
				qrbox: { width, height },
 | 
			
		||||
				aspectRatio: 1,
 | 
			
		||||
				supportedScanTypes: [Html5QrcodeScanType.SCAN_TYPE_CAMERA],
 | 
			
		||||
				formatsToSupport: [
 | 
			
		||||
					Html5QrcodeSupportedFormats.CODE_39,
 | 
			
		||||
					Html5QrcodeSupportedFormats.EAN_8,
 | 
			
		||||
					Html5QrcodeSupportedFormats.EAN_13,
 | 
			
		||||
					Html5QrcodeSupportedFormats.QR_CODE,
 | 
			
		||||
					Html5QrcodeSupportedFormats.CODE_128,
 | 
			
		||||
				],
 | 
			
		||||
			},
 | 
			
		||||
			false // non-verbose
 | 
			
		||||
		);
 | 
			
		||||
		scanner.render(onScanSuccess, onScanFailure);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// pause/resume scanner to avoid unintended scans
 | 
			
		||||
	$: togglePause(paused);
 | 
			
		||||
	function togglePause(paused) {
 | 
			
		||||
		if (paused && scanner?.getState() === Html5QrcodeScannerState.SCANNING) {
 | 
			
		||||
			scanner?.pause();
 | 
			
		||||
		} else if (scanner?.getState() === Html5QrcodeScannerState.PAUSED) {
 | 
			
		||||
			scanner?.resume();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<div id="qr-scanner" class={$$props.class} />
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
	/* Hide unwanted icons */
 | 
			
		||||
	#qr-scanner :global(img[alt="Info icon"]),
 | 
			
		||||
	#qr-scanner :global(img[alt="Camera based scan"]) {
 | 
			
		||||
		display: none;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Change camera permission button text */
 | 
			
		||||
	#qr-scanner :global(#html5-qrcode-button-camera-permission) {
 | 
			
		||||
		visibility: hidden;
 | 
			
		||||
	}
 | 
			
		||||
	#qr-scanner :global(#html5-qrcode-button-camera-permission::after) {
 | 
			
		||||
		position: absolute;
 | 
			
		||||
		inset: auto 0 0;
 | 
			
		||||
		display: block;
 | 
			
		||||
		content: "Allow camera access";
 | 
			
		||||
		visibility: visible;
 | 
			
		||||
		padding: 10px 0;
 | 
			
		||||
	}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -170,7 +170,7 @@
 | 
			
		||||
						<img
 | 
			
		||||
							class:w-[50%]={is_qrcode}
 | 
			
		||||
							class:w-full={!is_qrcode}
 | 
			
		||||
							class="w-full lg:max-w-[50vw] lg:max-h-[10rem] object-contain mb-2 mx-auto"
 | 
			
		||||
							class="md:w-auto mb-2 mx-auto"
 | 
			
		||||
							alt="Registrierungscode"
 | 
			
		||||
							src={textToBase64Barcode(window.config.baseurl, is_qrcode)}
 | 
			
		||||
						/>
 | 
			
		||||
@@ -178,7 +178,7 @@
 | 
			
		||||
						<img
 | 
			
		||||
							class:w-[50%]={is_qrcode}
 | 
			
		||||
							class:w-full={!is_qrcode}
 | 
			
		||||
							class="w-full lg:max-w-[50vw] lg:max-h-[10rem] object-contain mb-2 mx-auto"
 | 
			
		||||
							class="md:w-auto mb-2 mx-auto"
 | 
			
		||||
							alt="Registrierungscode"
 | 
			
		||||
							src={barcode}
 | 
			
		||||
						/>
 | 
			
		||||
 
 | 
			
		||||
@@ -382,7 +382,6 @@
 | 
			
		||||
    "runners": "Läufer",
 | 
			
		||||
    "runners-are-being-imported": "Läufer werden importiert ...",
 | 
			
		||||
    "runners-are-being-loaded": "Läufer werden geladen ...",
 | 
			
		||||
    "runners_via_kiosk": "Läufer via Kiosk",
 | 
			
		||||
    "save": "Speichern",
 | 
			
		||||
    "save-changes": "Änderungen speichern",
 | 
			
		||||
    "scan-added": "Scan hinzugefügt",
 | 
			
		||||
 
 | 
			
		||||
@@ -382,7 +382,6 @@
 | 
			
		||||
    "runners": "Runners",
 | 
			
		||||
    "runners-are-being-imported": "Runners are being imported...",
 | 
			
		||||
    "runners-are-being-loaded": "runners are being loaded...",
 | 
			
		||||
    "runners_via_kiosk": "Runners via Kiosk",
 | 
			
		||||
    "save": "Save",
 | 
			
		||||
    "save-changes": "Save Changes",
 | 
			
		||||
    "scan-added": "Scan added",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user