PRODUCTION READY BOYS
This commit is contained in:
7450
package-lock.json
generated
Normal file
7450
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@libsql/client": "^0.17.2",
|
||||
"@sveltejs/adapter-auto": "^7.0.1",
|
||||
"@sveltejs/adapter-node": "^5.5.7",
|
||||
"@sveltejs/kit": "^2.57.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
||||
"@tailwindcss/forms": "^0.5.11",
|
||||
|
||||
@@ -22,7 +22,7 @@ export async function setSetting(key: string, value: string): Promise<void> {
|
||||
export async function getAllInitialInfo() {
|
||||
return {
|
||||
teams: await getTeams(),
|
||||
events: await getRegisteredEvents()
|
||||
events: await getRegisteredEventsWithPlayers()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { drizzle } from 'drizzle-orm/libsql';
|
||||
import { createClient } from '@libsql/client';
|
||||
import { createClient } from './libsql-wrapper';
|
||||
import { construct } from 'drizzle-orm/libsql/driver-core';
|
||||
import * as schema from './schema';
|
||||
import { env } from '$env/dynamic/private';
|
||||
|
||||
@@ -7,4 +7,4 @@ if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');
|
||||
|
||||
const client = createClient({ url: env.DATABASE_URL });
|
||||
|
||||
export const db = drizzle(client, { schema });
|
||||
export const db = construct(client, { schema });
|
||||
|
||||
7
src/lib/server/db/libsql-wrapper.ts
Normal file
7
src/lib/server/db/libsql-wrapper.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const libsql = require('@libsql/client');
|
||||
|
||||
export const createClient = libsql.createClient;
|
||||
export default libsql;
|
||||
@@ -9,8 +9,8 @@ import { flip } from 'svelte/animate';
|
||||
focusEventId?: number | null;
|
||||
} = $props();
|
||||
|
||||
let teams = $derived(data.teams.teams);
|
||||
let eventTable = $derived(data.events.events);
|
||||
let teams = $state(data.teams.teams);
|
||||
let eventTable = $state(data.events);
|
||||
|
||||
let scoreEndpoint: EventSource;
|
||||
let eventEndpoint: EventSource;
|
||||
@@ -64,7 +64,7 @@ import { flip } from 'svelte/animate';
|
||||
if (focusEventId == null) return;
|
||||
tick().then(() => {
|
||||
const el = eventRefs[focusEventId!];
|
||||
el.scrollIntoView({ alignToTop: true, behavior: 'instant', container: 'nearest' });
|
||||
el.scrollIntoView({ block: 'start', behavior: 'instant' });
|
||||
tick().then(() => {
|
||||
window.scrollTo(0, 0);
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ export async function POST({ request }: any) {
|
||||
return new Error('send a response dummy');
|
||||
} else {
|
||||
console.log(responseBody);
|
||||
startEvent(responseBody.eventId);
|
||||
await startEvent(responseBody.eventId);
|
||||
return new Response('ok');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { globalEmitter } from '$lib/server/globalEmitter';
|
||||
import { generateEndpoint } from '$lib/server/endpoint';
|
||||
|
||||
export async function POST({ request }: any) {
|
||||
globalEmitter.emit('incrementScores');
|
||||
globalEmitter.emit('scoreUpdate');
|
||||
return new Response('ok');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,25 @@
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { db } from '$lib/server/db';
|
||||
import { scorers } from '$lib/server/db/schema';
|
||||
import { getRegisteredEventsWithPlayers } from '$lib/server/databaseManager';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ locals }) => {
|
||||
if (!locals.user) return { user: null };
|
||||
export const load: PageServerLoad = async ({ locals, params }) => {
|
||||
const eventId = parseInt(params.eventId);
|
||||
const userInfo: { user: any } = { user: null };
|
||||
|
||||
const [row] = await db
|
||||
.select({ role: scorers.role })
|
||||
.from(scorers)
|
||||
.where(eq(scorers.id, locals.user.id));
|
||||
return { user: { ...locals.user, role: row?.role ?? 'scorer' } };
|
||||
if (locals.user) {
|
||||
const [row] = await db
|
||||
.select({ role: scorers.role })
|
||||
.from(scorers)
|
||||
.where(eq(scorers.id, locals.user.id));
|
||||
userInfo.user = { ...locals.user, role: row?.role ?? 'scorer' };
|
||||
}
|
||||
|
||||
const events = await getRegisteredEventsWithPlayers(eventId);
|
||||
|
||||
return {
|
||||
...userInfo,
|
||||
event: events[0] ?? null
|
||||
};
|
||||
};
|
||||
|
||||
@@ -31,59 +31,50 @@
|
||||
|
||||
let eventEndpoint: EventSource;
|
||||
|
||||
async function getEventData() {
|
||||
let response = await fetch('/api/registeredEvents', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
eventId: eventId
|
||||
}),
|
||||
headers: {
|
||||
'Content-type': 'application/json; charset=UTF-8'
|
||||
}
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data && data[0] && data[0].registeredPlayers) {
|
||||
data[0].registeredPlayers.forEach((bracket: any) => {
|
||||
bracket.items.sort((a: any, b: any) => {
|
||||
if (a.placement === 0 && b.placement === 0) return 0;
|
||||
if (a.placement === 0) return 1;
|
||||
if (b.placement === 0) return -1;
|
||||
return a.placement - b.placement;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
let eventDataPromise = getEventData();
|
||||
let eventData = $state<any>(data.event);
|
||||
|
||||
onMount(() => {
|
||||
eventEndpoint = new EventSource('/api/registeredEvents');
|
||||
eventEndpoint.onmessage = (e) => {
|
||||
const allEvents = JSON.parse(e.data);
|
||||
const updated = allEvents.find((ev: any) => ev.id == eventId);
|
||||
if (updated) {
|
||||
if (updated.registeredPlayers) {
|
||||
updated.registeredPlayers.forEach((bracket: any) => {
|
||||
bracket.items.sort((a: any, b: any) => {
|
||||
if (a.placement === 0 && b.placement === 0) return 0;
|
||||
if (a.placement === 0) return 1;
|
||||
if (b.placement === 0) return -1;
|
||||
return a.placement - b.placement;
|
||||
});
|
||||
});
|
||||
}
|
||||
eventData = updated;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
eventEndpoint?.close();
|
||||
});
|
||||
</script>
|
||||
|
||||
{#await eventDataPromise}
|
||||
<div class="page-container"><div>loading</div></div>
|
||||
{:then eventData}
|
||||
{@const event = eventData[0]}
|
||||
{#if eventData}
|
||||
<div class="page-container">
|
||||
<div class="event-card" class:ongoing-event={event.state == 1} class:completed-event={event.state == 2}
|
||||
style={event.state == 2 ? `--event-color: ${event.winner?.color ?? 'currentColor'}` : ''}>
|
||||
<div class="event-card" class:ongoing-event={eventData.state == 1} class:completed-event={eventData.state == 2}
|
||||
style={eventData.state == 2 ? `--event-color: ${eventData.winner?.color ?? 'currentColor'}` : ''}>
|
||||
<div class="event-header">
|
||||
<span class="event-name goldman">{event.name}</span>
|
||||
<span class="event-division">{event.division}</span>
|
||||
{#if event.state == 1}
|
||||
<span class="event-name goldman">{eventData.name}</span>
|
||||
<span class="event-division">{eventData.division}</span>
|
||||
{#if eventData.state == 1}
|
||||
<span class="event-status goldman">ONGOING</span>
|
||||
{:else if event.state == 2}
|
||||
{:else if eventData.state == 2}
|
||||
<span class="event-status goldman">FINISHED</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="brackets px-[5vw]">
|
||||
{#each event.registeredPlayers as bracket, bi}
|
||||
{#each eventData.registeredPlayers as bracket, bi}
|
||||
{#if bi > 0}
|
||||
<div class="bracket-sep" aria-hidden="true"></div>
|
||||
{/if}
|
||||
@@ -118,7 +109,7 @@
|
||||
<div class="flex flex-col justify-center">
|
||||
{#each player.playerScores as score}
|
||||
<div class="mx-1 my-0.5 rounded border px-1 text-xs" style="border-color:{player.teamColor}">
|
||||
Run {score.resultIndex + 1}: {score.result}{event.resultPresets[0].unit}
|
||||
Run {score.resultIndex + 1}: {score.result}{eventData.resultPresets[0].unit}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -141,4 +132,6 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/await}
|
||||
{:else}
|
||||
<div class="page-container"><div>loading</div></div>
|
||||
{/if}
|
||||
@@ -209,6 +209,9 @@
|
||||
eventId: eventId
|
||||
})
|
||||
});
|
||||
if (res.ok) {
|
||||
event = { ...event, state: 1 };
|
||||
}
|
||||
} catch {
|
||||
return new Error();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { ActionData, PageData } from './$types';
|
||||
export let data: PageData;
|
||||
export let form: ActionData;
|
||||
let { data, form }: { data: PageData; form: any } = $props();
|
||||
</script>
|
||||
|
||||
<div class="page-container">
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { PageData, ActionData } from './$types';
|
||||
export let data: PageData;
|
||||
export let form: ActionData;
|
||||
import type { PageData } from './$types';
|
||||
let { data, form }: { data: PageData; form: any } = $props();
|
||||
</script>
|
||||
|
||||
<div class="page-container">
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import adapter from '@sveltejs/adapter-auto';
|
||||
import adapter from '@sveltejs/adapter-node';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
compilerOptions: {
|
||||
// Force runes mode (except in node_modules). Remove when Svelte 6 makes it default.
|
||||
runes: ({ filename }) => (filename.split(/[/\\]/).includes('node_modules') ? undefined : true)
|
||||
},
|
||||
kit: {
|
||||
@@ -18,11 +17,6 @@ const config = {
|
||||
experimental: {
|
||||
remoteFunctions: true
|
||||
}
|
||||
},
|
||||
compilerOptions: {
|
||||
experimental: {
|
||||
async: true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user