From d7c9c27ec7a1fea1cbaf26914843d044bbae32fe Mon Sep 17 00:00:00 2001 From: Philipp Dormann Date: Tue, 8 Apr 2025 21:56:23 +0200 Subject: [PATCH] feat: add experimental ui for mobile card assignment --- package.json | 1 + pnpm-lock.yaml | 26 ++++++- src/App.svelte | 6 ++ src/components/general/CardAssignment.svelte | 72 ++++++++++++++++++ src/components/general/QrCodeScanner.svelte | 80 ++++++++++++++++++++ 5 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 src/components/general/CardAssignment.svelte create mode 100644 src/components/general/QrCodeScanner.svelte diff --git a/package.json b/package.json index 3aaa7448..7ac02a8b 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "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", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6fc7049b..beb64c0b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ 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 @@ -77,7 +80,7 @@ importers: version: 3.3.3(prettier@3.5.3)(svelte@3.58.0) release-it: specifier: 17.10.0 - version: 17.10.0 + version: 17.10.0(typescript@5.8.3) svelte-select: specifier: 3.17.0 version: 3.17.0 @@ -924,6 +927,9 @@ 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'} @@ -1794,6 +1800,11 @@ 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'} @@ -2439,12 +2450,14 @@ snapshots: graceful-fs: 4.2.11 xdg-basedir: 5.1.0 - cosmiconfig@9.0.0: + cosmiconfig@9.0.0(typescript@5.8.3): 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: {} @@ -2765,6 +2778,8 @@ snapshots: dependencies: function-bind: 1.1.2 + html5-qrcode@2.3.8: {} + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 @@ -3322,14 +3337,14 @@ snapshots: dependencies: rc: 1.2.8 - release-it@17.10.0: + release-it@17.10.0(typescript@5.8.3): 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 + cosmiconfig: 9.0.0(typescript@5.8.3) execa: 8.0.0 git-url-parse: 14.0.0 globby: 14.0.2 @@ -3607,6 +3622,9 @@ snapshots: type@2.7.2: {} + typescript@5.8.3: + optional: true + uglify-js@3.19.3: optional: true diff --git a/src/App.svelte b/src/App.svelte index d0a357b2..fb10e59a 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -41,6 +41,7 @@ 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"; @@ -141,6 +142,11 @@ + + + + + diff --git a/src/components/general/CardAssignment.svelte b/src/components/general/CardAssignment.svelte new file mode 100644 index 00000000..d2e4a2a4 --- /dev/null +++ b/src/components/general/CardAssignment.svelte @@ -0,0 +1,72 @@ + + +
+

Card Assignment for Mobile

+ {#if state === "done"} +

Assigned Card {cardInfo} ✅

+

(not really, needs to be implemented)

+ {:else} + + {#if state === "scan_runner"} +

Scan Runner (Selfservice QR)

+ {/if} + {#if state === "scan_card"} +

Runner Scanned

+

{runnerID}

+

Scan Card (Code 128 Barcode)

+ {/if} + { + console.log({ type: "DETECT", code: e.detail.decodedText }); + if (state === "scan_runner") { + if ( + e.detail.decodedText.includes( + "https://portal.lauf-fuer-kaya.de/profile/" + ) + ) { + runnerID = JSON.parse( + atob( + e.detail.decodedText + .replace("https://portal.lauf-fuer-kaya.de/profile/", "") + .split(".")[1] + ) + ).id; + state = "scan_card"; + } + } + if (state === "scan_card") { + if ( + !e.detail.decodedText.includes( + "https://portal.lauf-fuer-kaya.de/profile/" + ) + ) { + cardInfo = e.detail.decodedText; + state = "done"; + } + } + }} + width={320} + height={320} + class="w-full max-w-sm bg-neutral-300 rounded-lg overflow-hidden" + /> + {#if state === "scan_card"} + + {/if} + + {/if} +
diff --git a/src/components/general/QrCodeScanner.svelte b/src/components/general/QrCodeScanner.svelte new file mode 100644 index 00000000..a0ca28e9 --- /dev/null +++ b/src/components/general/QrCodeScanner.svelte @@ -0,0 +1,80 @@ + + +
+ +