Slightly working
This commit is contained in:
17
src/app.d.ts
vendored
17
src/app.d.ts
vendored
@@ -1,13 +1,16 @@
|
|||||||
// See https://svelte.dev/docs/kit/types#app.d.ts
|
// src/app.d.ts
|
||||||
// for information about these interfaces
|
import { SupabaseClient, Session } from '@supabase/supabase-js'
|
||||||
declare global {
|
declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
|
interface Locals {
|
||||||
|
supabase: SupabaseClient
|
||||||
|
safeGetSession(): Promise<{ session: Session | null; user: User | null }>
|
||||||
|
}
|
||||||
|
interface PageData {
|
||||||
|
session: Session | null
|
||||||
|
user: User | null
|
||||||
|
}
|
||||||
// interface Error {}
|
// interface Error {}
|
||||||
// interface Locals {}
|
|
||||||
// interface PageData {}
|
|
||||||
// interface PageState {}
|
|
||||||
// interface Platform {}
|
// interface Platform {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
|
||||||
|
|||||||
53
src/hooks.server.ts
Normal file
53
src/hooks.server.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// src/hooks.server.ts
|
||||||
|
import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public'
|
||||||
|
import { createServerClient } from '@supabase/ssr'
|
||||||
|
import type { Handle } from '@sveltejs/kit'
|
||||||
|
|
||||||
|
export const handle: Handle = async ({ event, resolve }) => {
|
||||||
|
event.locals.supabase = createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
|
||||||
|
cookies: {
|
||||||
|
getAll: () => event.cookies.getAll(),
|
||||||
|
/**
|
||||||
|
* SvelteKit's cookies API requires `path` to be explicitly set in
|
||||||
|
* the cookie options. Setting `path` to `/` replicates previous/
|
||||||
|
* standard behavior.
|
||||||
|
*/
|
||||||
|
setAll: (cookiesToSet) => {
|
||||||
|
cookiesToSet.forEach(({ name, value, options }) => {
|
||||||
|
event.cookies.set(name, value, { ...options, path: '/' })
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlike `supabase.auth.getSession()`, which returns the session _without_
|
||||||
|
* validating the JWT, this function also calls `getUser()` to validate the
|
||||||
|
* JWT before returning the session.
|
||||||
|
*/
|
||||||
|
event.locals.safeGetSession = async () => {
|
||||||
|
const {
|
||||||
|
data: { session },
|
||||||
|
} = await event.locals.supabase.auth.getSession()
|
||||||
|
if (!session) {
|
||||||
|
return { session: null, user: null }
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: { user },
|
||||||
|
error,
|
||||||
|
} = await event.locals.supabase.auth.getUser()
|
||||||
|
if (error) {
|
||||||
|
// JWT validation has failed
|
||||||
|
return { session: null, user: null }
|
||||||
|
}
|
||||||
|
|
||||||
|
return { session, user }
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolve(event, {
|
||||||
|
filterSerializedResponseHeaders(name) {
|
||||||
|
return name === 'content-range' || name === 'x-supabase-api-version'
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
31
src/lib/types.ts
Normal file
31
src/lib/types.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
export enum ScanState {
|
||||||
|
scanning,
|
||||||
|
scan_successful,
|
||||||
|
scan_failed
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TicketData = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
surname: string;
|
||||||
|
email: string;
|
||||||
|
event: string;
|
||||||
|
created_at: string;
|
||||||
|
created_by: string | null;
|
||||||
|
scanned: boolean;
|
||||||
|
scanned_at: string | null;
|
||||||
|
scanned_by: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const defaultTicketData: TicketData = {
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
surname: '',
|
||||||
|
email: '',
|
||||||
|
event: '',
|
||||||
|
created_at: new Date().toISOString(),
|
||||||
|
created_by: null,
|
||||||
|
scanned: false,
|
||||||
|
scanned_at: null,
|
||||||
|
scanned_by: null,
|
||||||
|
};
|
||||||
10
src/routes/+layout.server.ts
Normal file
10
src/routes/+layout.server.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// src/routes/+layout.server.ts
|
||||||
|
import type { LayoutServerLoad } from './$types'
|
||||||
|
export const load: LayoutServerLoad = async ({ locals: { safeGetSession }, cookies }) => {
|
||||||
|
const { session, user } = await safeGetSession()
|
||||||
|
return {
|
||||||
|
session,
|
||||||
|
user,
|
||||||
|
cookies: cookies.getAll(),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
import '../app.css';
|
import '../app.css';
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{@render children()}
|
{@render children()}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export const load: LayoutLoad = async ({ fetch, data, depends }) => {
|
|||||||
? createBrowserClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
|
? createBrowserClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
|
||||||
global: {
|
global: {
|
||||||
fetch,
|
fetch,
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
: createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
|
: createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
|
||||||
global: {
|
global: {
|
||||||
@@ -16,7 +16,7 @@ export const load: LayoutLoad = async ({ fetch, data, depends }) => {
|
|||||||
},
|
},
|
||||||
cookies: {
|
cookies: {
|
||||||
getAll() {
|
getAll() {
|
||||||
return data?.cookies ?? []
|
return data.cookies ?? []
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
|
||||||
|
|
||||||
let data = $props();
|
|
||||||
|
|
||||||
onMount( async () => {
|
|
||||||
await handleClick();
|
|
||||||
});
|
|
||||||
|
|
||||||
async function handleClick() {
|
|
||||||
console.log( await data.data.supabase.from('qrcodes').select().eq('id', "4b461fd7-d7db-4739-8ca0-6e78cc299813"));
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
0
src/routes/login/+page.svelte
Normal file
0
src/routes/login/+page.svelte
Normal file
42
src/routes/private/scanner/+page.svelte
Normal file
42
src/routes/private/scanner/+page.svelte
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import QRScanner from './QRScanner.svelte';
|
||||||
|
import TicketDisplay from './TicketDisplay.svelte';
|
||||||
|
|
||||||
|
import type { TicketData } from '$lib/types';
|
||||||
|
import { ScanState, defaultTicketData } from '$lib/types';
|
||||||
|
|
||||||
|
let { data } = $props();
|
||||||
|
let scanned_id = $state<string>("");
|
||||||
|
let ticket_data = $state<TicketData>(defaultTicketData);
|
||||||
|
let scan_state = $state<ScanState>(ScanState.scanning);
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (scanned_id === "") return;
|
||||||
|
console.log('New QR code found:', scanned_id);
|
||||||
|
scan_state = ScanState.scanning;
|
||||||
|
|
||||||
|
data.supabase.from('qrcodes').select().eq('id', scanned_id).then( response => {
|
||||||
|
if (response.data && response.data.length > 0) {
|
||||||
|
ticket_data = response.data[0];
|
||||||
|
scan_state = ScanState.scan_successful;
|
||||||
|
} else {
|
||||||
|
ticket_data = defaultTicketData;
|
||||||
|
scan_state = ScanState.scan_failed;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<QRScanner bind:message={scanned_id} />
|
||||||
|
|
||||||
|
{#if scan_state === ScanState.scan_successful}
|
||||||
|
<TicketDisplay {ticket_data} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if scan_state === ScanState.scan_failed}
|
||||||
|
<p>Scan failed. Please try again.</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if scan_state === ScanState.scanning}
|
||||||
|
<p>Fetching data...</p>
|
||||||
|
{/if}
|
||||||
8
src/routes/private/scanner/TicketDisplay.svelte
Normal file
8
src/routes/private/scanner/TicketDisplay.svelte
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TicketData } from '$lib/types';
|
||||||
|
|
||||||
|
let { ticket_data }: { ticket_data: TicketData } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{ticket_data.name}</p>
|
||||||
|
<p>{ticket_data.surname}</p>
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
<script>
|
|
||||||
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>
|
|
||||||
Reference in New Issue
Block a user