wip
This commit is contained in:
		@@ -4,86 +4,157 @@
 | 
			
		||||
	let state = "scan_runner";
 | 
			
		||||
	let runnerinfo = { id: 0, firstname: "", lastname: "" };
 | 
			
		||||
	let cardCode = "";
 | 
			
		||||
	$: scannerActive = state.includes("scan");
 | 
			
		||||
	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>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";
 | 
			
		||||
							}
 | 
			
		||||
						});
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
	<!-- <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();
 | 
			
		||||
			}}
 | 
			
		||||
			width={320}
 | 
			
		||||
			height={320}
 | 
			
		||||
			class="w-full max-w-sm bg-neutral-300 rounded-lg overflow-hidden"
 | 
			
		||||
		/>
 | 
			
		||||
		{#if state === "scan_card"}
 | 
			
		||||
			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 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 = "scan_error_runner_404";
 | 
			
		||||
										resetAll();
 | 
			
		||||
									});
 | 
			
		||||
							} else {
 | 
			
		||||
								const runnerID = parseInt(e.detail.decodedText);
 | 
			
		||||
								RunnerService.runnerControllerGetOne(runnerID)
 | 
			
		||||
									.then((runner) => {
 | 
			
		||||
										runnerinfo = runner;
 | 
			
		||||
									})
 | 
			
		||||
									.catch((e) => {
 | 
			
		||||
										console.error(e);
 | 
			
		||||
										state = "scan_error_runner_404";
 | 
			
		||||
										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(() => {
 | 
			
		||||
													scannerActive = true;
 | 
			
		||||
												});
 | 
			
		||||
										} 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 = "";
 | 
			
		||||
				}}
 | 
			
		||||
@@ -94,30 +165,5 @@
 | 
			
		||||
			</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>
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,25 @@
 | 
			
		||||
 | 
			
		||||
	const dispatch = createEventDispatcher();
 | 
			
		||||
 | 
			
		||||
	const debounceFunc = (func, delay) => {
 | 
			
		||||
		let timer;
 | 
			
		||||
		return function (...args) {
 | 
			
		||||
			const context = this;
 | 
			
		||||
			clearTimeout(timer);
 | 
			
		||||
			timer = setTimeout(() => {
 | 
			
		||||
				func.apply(context, args);
 | 
			
		||||
			}, delay);
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const debouncedDispatch = debounceFunc(function (decodedText) {
 | 
			
		||||
		console.log("dispatchEvent");
 | 
			
		||||
		dispatch("detect", { decodedText });
 | 
			
		||||
	}, 500);
 | 
			
		||||
 | 
			
		||||
	function onScanSuccess(decodedText, decodedResult) {
 | 
			
		||||
		if (!paused) {
 | 
			
		||||
			dispatch("detect", { decodedText });
 | 
			
		||||
			debouncedDispatch(decodedText);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -32,6 +48,7 @@
 | 
			
		||||
			"qr-scanner",
 | 
			
		||||
			{
 | 
			
		||||
				fps: 10,
 | 
			
		||||
				showTorchButtonIfSupported: true,
 | 
			
		||||
				rememberLastUsedCamera: true,
 | 
			
		||||
				qrbox: { width, height },
 | 
			
		||||
				aspectRatio: 1,
 | 
			
		||||
@@ -48,16 +65,6 @@
 | 
			
		||||
		);
 | 
			
		||||
		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} />
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user