Basic functionality

This commit is contained in:
Roman Krček
2025-05-17 13:41:47 +02:00
parent 3c6ea4e0c5
commit 5d647112b3
4 changed files with 141 additions and 2 deletions

8
package-lock.json generated
View File

@@ -13,6 +13,7 @@
"@sveltejs/vite-plugin-svelte": "^5.0.0", "@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0", "@tailwindcss/vite": "^4.0.0",
"html5-qrcode": "^2.3.8",
"prettier": "^3.4.2", "prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3", "prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11", "prettier-plugin-tailwindcss": "^0.6.11",
@@ -1460,6 +1461,13 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/html5-qrcode": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.3.8.tgz",
"integrity": "sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/is-reference": { "node_modules/is-reference": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",

View File

@@ -19,6 +19,7 @@
"@sveltejs/vite-plugin-svelte": "^5.0.0", "@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0", "@tailwindcss/vite": "^4.0.0",
"html5-qrcode": "^2.3.8",
"prettier": "^3.4.2", "prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3", "prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11", "prettier-plugin-tailwindcss": "^0.6.11",

View File

@@ -1,2 +1,68 @@
<h1>Welcome to SvelteKit</h1> <script>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p> import { onMount, tick } from 'svelte';
import QRScanner from './QRScanner.svelte';
let scanned_id = $state('');
let scan_user = $state('Roman');
let scan_data = $state({});
let ticket_state = $state('not_scanned');
onMount(() => {reset_scan_data()});
function reset_scan_data() {
ticket_state = 'unknown';
scan_data = {
id: 0,
created_at: 'none',
name: 'none',
surname: 'none',
email: 'none@esnvutbrno.cz',
uuid: 'none',
scanned: 'none',
scanned_at: 'none',
event_name: 'none',
scanned_by: 'none'
};
}
$effect(() => {
if (scan_data.scanned === true) {
ticket_state = 'Already scanned';
} else if (scan_data.scanned === false) {
ticket_state = 'Good to go in 2';
console.log(scan_data.scanned);
} else {
ticket_state = 'Ticket invalid';
}
});
$effect(() => {
console.log('Message updated:', scanned_id);
reset_scan_data();
fetch('https://n8n.orebolt.cz/webhook/9d32752c-47c9-46db-be6d-f473e97a7c25', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ scanned_id, scan_user })
})
.then((response) => response.json())
.then((data) => {
scan_data = data;
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
ticket_state = "Ticket invalid";
});
});
</script>
<QRScanner bind:message={scanned_id} />
<p>CODE: {scanned_id}</p>
<p>Name: {scan_data.name} {scan_data.surname}</p>
<p>State: {ticket_state}</p>
<p>Event: {scan_data.event_name}</p>

View File

@@ -0,0 +1,64 @@
<script lang="ts">
import { onMount } from 'svelte';
import {
Html5QrcodeScanner,
type Html5QrcodeResult,
Html5QrcodeScanType,
Html5QrcodeSupportedFormats,
Html5QrcodeScannerState,
} from 'html5-qrcode';
let width: number = 300;
let height: number = 300;
let { message = $bindable() } = $props();
function onScanSuccess(decodedText: string, decodedResult: Html5QrcodeResult): void {
//console.log(`Code scanned = ${decodedText}`);
message = decodedText;
}
// usually better to ignore and keep scanning
function onScanFailure(message: string) {
//console.log(`Code scan error = ${message}`);
}
let scanner: Html5QrcodeScanner;
onMount(() => {
scanner = new Html5QrcodeScanner(
'qr-scanner',
{
fps: 5,
qrbox: { width, height },
aspectRatio: 1,
supportedScanTypes: [Html5QrcodeScanType.SCAN_TYPE_CAMERA],
formatsToSupport: [Html5QrcodeSupportedFormats.QR_CODE],
},
false // non-verbose
);
scanner.render(onScanSuccess, onScanFailure);
});
</script>
<div id="qr-scanner" class="w-full max-w-sm bg-slate-700 rounded-lg overflow-hidden"></div>
<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>