frontend/src/components/general/CardAssignment.svelte
2025-04-22 18:47:41 +02:00

195 lines
6.4 KiB
Svelte

<script>
import { RunnerCardService, RunnerService } from "@odit/lfk-client-js";
import QrCodeScanner from "./QrCodeScanner.svelte";
let state = "scan_runner";
let state_tmp = "";
let runnerinfo = { id: 0, firstname: "", lastname: "" };
let cardCode = "";
let scannerActive = true;
function resetAll() {
state = "scan_runner";
runnerinfo = { id: 0, firstname: "", lastname: "" };
cardCode = "";
scannerActive = true;
}
</script>
<div class="p-4">
<h3 class="text-3xl font-bold">Card Assignment for Mobile</h3>
<!-- <p class="p-4 bg-sky-200 rounded-lg mt-2 mb-2">state: {state}</p> -->
{#if state === "done"}
<h3 class="text-2xl font-bold">✅ Done</h3>
<h4 class="text-xl font-semibold">
Assigned Card {cardCode} to {runnerinfo.firstname}
{runnerinfo.lastname} [#{runnerinfo.id}]
</h4>
<button
on:click={() => {
resetAll();
}}
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"
>
Next Runner
</button>
{:else if state === "assigning"}
<p>Assigning Card {cardCode}</p>
<p>Please wait a moment while we assign the card...</p>
{:else if state === "error_runner"}
<p>Runner not found...</p>
<button
on:click={() => {
resetAll();
}}
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"
>
Try Again
</button>
{:else if state === "error_card"}
<p>Card not found...</p>
<button
on:click={() => {
state = "scan_card";
scannerActive = true;
}}
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"
>
Try Again
</button>
{:else}
<!-- -->
{#if runnerinfo.id === 0}
<h3 class="text-2xl font-bold">Scan Runner</h3>
<h4 class="text-xl font-semibold">
Selfservice QR/ Registration Barcode
</h4>
{:else}
<h3 class="text-2xl font-bold">
{runnerinfo.firstname}
{runnerinfo.lastname}
</h3>
<p>
ID: #{runnerinfo.id}<br />created_via: {runnerinfo.created_via}<br
/>{runnerinfo.group.name}
</p>
{/if}
<!-- -->
{/if}
{#if state === "scan_card"}
<h3 class="text-2xl font-bold">Scan Card</h3>
<h4 class="text-xl font-semibold">Code 128 Barcode</h4>
{/if}
{#if state.includes("scan_")}
{#if scannerActive}
<QrCodeScanner
:paused={!scannerActive}
on:detect={(e) => {
if (scannerActive) {
scannerActive = false;
console.log({ type: "DETECT", code: e.detail.decodedText });
if (runnerinfo.id === 0) {
new Audio("/beep.mp3").play();
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;
RunnerService.runnerControllerGetOne(runnerID)
.then((runner) => {
runnerinfo = runner;
})
.catch((e) => {
console.error(e);
state = "error_runner";
// resetAll();
});
} else {
const runnerID = parseInt(e.detail.decodedText);
RunnerService.runnerControllerGetOne(runnerID)
.then((runner) => {
runnerinfo = runner;
})
.catch((e) => {
console.error(e);
state = "error_runner";
// resetAll();
});
}
} else {
if (`${e.detail.decodedText}`.length > 10) {
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";
})
.catch(() => {
state = "error_card";
scannerActive = false;
});
} else {
scannerActive = true;
}
})
.catch(() => {
scannerActive = true;
});
}
}
}
}}
width={320}
height={320}
class="w-full max-w-sm bg-neutral-300 rounded-lg overflow-hidden"
/>
{/if}
{#if runnerinfo.id !== 0 && state !== "scan_card"}
<button
on:click={() => {
state = "scan_card";
scannerActive = true;
}}
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"
>
Scan Card
</button>
{/if}
{#if state === "scan_card" || runnerinfo.id !== 0}
<button
on:click={() => {
state = "scan_runner";
scannerActive = true;
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}
<!-- -->
{/if}
</div>