Compare commits

..

2 Commits

Author SHA1 Message Date
ed98690bb6 holy shit i can start events now 2026-06-25 13:12:27 +01:00
2f3005ba2a some changed 2026-06-25 12:39:58 +01:00
16 changed files with 1774 additions and 1680 deletions

View File

@@ -1 +1 @@
/nix/store/kap8myx3a7djmgsaaspb46azzkhyrnmn-devenv-shell
/nix/store/9dswnx96sj7qpqvah77lx8g25hsl1z1x-devenv-shell

View File

@@ -1 +1 @@
/nix/store/2f9x4skfyh2x0rkfacr2w0v3c2vm405w-tasks.json
/nix/store/gj888l55lxj0brzhkjrdcald7zw7pskj-tasks.json

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -23,7 +23,7 @@ autoload -Uz add-zsh-hook
__devenv_reload_apply() {
# Source new environment if a reload is pending
if [ -f "/tmp/nix-shell-28554-2490132097/devenv-reload-30583.sh" ]; then
if [ -f "/tmp/devenv-reload-274471.sh" ]; then
# Shell out to bash to handle the env diff (bash syntax)
local reload_output
reload_output=$(bash -c '
@@ -158,8 +158,8 @@ _before=$(mktemp)
__devenv_capture_env > "$_before"
# Source new devenv environment
source "/tmp/nix-shell-28554-2490132097/devenv-reload-30583.sh"
rm -f "/tmp/nix-shell-28554-2490132097/devenv-reload-30583.sh"
source "/tmp/devenv-reload-274471.sh"
rm -f "/tmp/devenv-reload-274471.sh"
# Compute new diff
__devenv_compute_diff "$_before"

1
.gitignore vendored
View File

@@ -26,3 +26,4 @@ vite.config.ts.timestamp-*
.session
local.db
/.devenv

View File

@@ -4,7 +4,8 @@ event_name,preset,resultPreset
500m Relay,1,race
750m Race,1,race
1000m Long Distance,1,race
Javelin, 2,default
Shotput, 2,default
Long Jump, 2,three
Triple Jump, 2,default
Javelin, 1,three
Shotput, 1,three
Long Jump, 1,three
High Jump, 1,three
Triple Jump, 1,three
1 event_name preset resultPreset
4 500m Relay 1 race
5 750m Race 1 race
6 1000m Long Distance 1 race
7 Javelin 2 1 default three
8 Shotput 2 1 default three
9 Long Jump 2 1 three
10 Triple Jump High Jump 2 1 default three
11 Triple Jump 1 three

View File

@@ -4,6 +4,3 @@ preset,placement,points
1,3,3
1,4,2
1,5,1
2,1,50
2,2,30
2,3,10
1 preset placement points
4 1 3 3
5 1 4 2
6 1 5 1
2 1 50
2 2 30
2 3 10

View File

@@ -1,6 +1,7 @@
import { db } from '$lib/server/db';
import { eq } from 'drizzle-orm';
import * as schema from '$lib/server/db/schema';
import { globalEmitter } from './globalEmitter';
// For page.server.ts so that it doesnt look weird before loading
export async function getAllInitialInfo() {
@@ -67,6 +68,28 @@ export async function getRegisteredEvents(eventId?: number) {
return { events };
}
export async function startEvent(eventId: number) {
let event = await db
.select()
.from(schema.registeredEventsView)
.where(eq(schema.registeredEventsView.eventId, eventId));
let requestedEvent = event[0];
console.log(requestedEvent);
if (requestedEvent.state != 0) {
console.log('not startable');
return false;
} else {
let replacedEvent = await db
.update(schema.registeredEvents)
.set({ state: 1 })
.where(eq(schema.registeredEvents.id, requestedEvent.eventId))
.returning();
console.log(replacedEvent);
globalEmitter.emit('eventUpdate');
return true;
}
}
// Get all players with an event id specified
export async function getAllRegisteredEventPlayers(eventId: number) {
const eventPlayers = await db

View File

@@ -7,11 +7,16 @@
<svelte:head><link rel="icon" href={favicon} /></svelte:head>
<div class="header goldman align-center flex h-15 w-full">
<div class="header goldman flex h-15 w-full">
<a
class="align-text-middle mx-3 my-1 h-auto content-center rounded-sm border-2 border-solid border-red-500 px-2"
class="align-text-middle justify-left mx-3 my-1 h-auto content-center rounded-sm border-2 border-solid border-red-500 px-2"
href="/">home</a
>
<div class="w-full"></div>
<a
class="align-text-middle justify-right mx-3 my-1 h-auto content-center rounded-sm border-2 border-solid border-red-500 px-2"
href="/login">login</a
>
</div>
{@render children()}

View File

@@ -94,7 +94,7 @@
{#if leaderboard[0]}
{@const team = leaderboard[0]}
<a
href="/team/{team.id}"
href="/"
class="score-box winner"
style="--c:{team.color}"
aria-label="{team.name}, 1st place, {team.points} points"
@@ -127,7 +127,7 @@
<div class="runners-grid" style="--runner-count:{Math.min(leaderboard.length - 1, 5)}">
{#each leaderboard.slice(1) as team, i (team.name)}
<a
href="/team/{team.id}"
href="/"
class="score-box runner"
style="--c:{team.color}"
aria-label="{team.name}, {ordinal(i + 2)} place, {team.points} points"

View File

@@ -0,0 +1,17 @@
import { globalEmitter } from '$lib/server/globalEmitter';
import { eq } from 'drizzle-orm';
import { db } from '$lib/server/db';
import * as schema from '$lib/server/db/schema';
import { startEvent } from '$lib/server/databaseManager';
export async function POST({ request }: any) {
let responseBody = await request.json();
if (!responseBody) {
return new Error('send a response dummy');
} else {
console.log(responseBody);
startEvent(responseBody.eventId);
return new Response('ok');
}
}

View File

@@ -62,9 +62,11 @@
{@const event = eventData[0]}
<div class="flex justify-center">
<div class="w-full flex-col px-[5vw] text-center">
{console.log(event)}
<div class="align-text-middle h-10 w-full bg-red-500">{event.name} - {event.division}</div>
div
<div
class="align-text-middle my-7 h-10 w-full rounded-2xl border-2 border-solid border-ctp-surface1"
>
{event.name} - {event.division}
</div>
{#each event.registeredPlayers as bracket, bi}
{#if bi > 0}
<div class="bracket-sep" aria-hidden="true"></div>
@@ -75,7 +77,7 @@
<div class="bracket-vertical-sep"></div>
</div>
{#each bracket.items as player}
<div class="player-box" style="--c:{player.teamColor}">
<div class="player-box h-30" style="--c:{player.teamColor}">
<div class="player-ghost" aria-hidden="true">
<svg viewBox="0 0.1 100 0.6" preserveAspectRatio="none" class="ghost-svg">
<text
@@ -90,7 +92,7 @@
</svg>
</div>
<div class="player-name-wrap" use:marquee>
<span class="marquee-inner">
<span class=" text-xl">
{player.firstName}
{player.lastName}
</span>
@@ -106,4 +108,10 @@
{/each}
</div>
</div>
<div class="mt-10 flex w-full justify-center">
<a
class="flex justify-center rounded border-2 border-solid border-white bg-ctp-surface2 p-4"
href="/event/scoring/{eventId}">Score This Event</a
>
</div>
{/await}

View File

@@ -126,7 +126,6 @@
for (let player in brackets[bracket].items) {
if (parseInt(player) > highestPlayer) {
highestPlayer = parseInt(player);
console.log(highestPlayer, 'high');
}
}
}
@@ -145,6 +144,15 @@
loading = false;
eventEndpoint = new EventSource('/api/registeredEvents');
eventEndpoint.onmessage = (e) => {
const data = JSON.parse(e.data)[eventId - 1];
console.log(data);
event = data;
brackets = data.registeredPlayers.map((b: any) => ({
...b,
items: [...b.items]
}));
};
});
onDestroy(() => {
@@ -176,6 +184,20 @@
dropTarget = null;
}
async function startEvent() {
try {
const res = await fetch('/api/eventStart', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
eventId: eventId
})
});
} catch {
return new Error();
}
}
async function submitResults() {
submitStatus = 'submitting';
try {
@@ -215,17 +237,29 @@
{:else}
<div class="flex justify-center">
<div class="w-full flex-col px-[2vw] text-center">
<div class="align-text-middle h-10 w-full bg-red-500">
{event.name} - {event.division} - scoring
<div
style:background-color={event.state == 1
? 'color-mix(in srgb, #fe640b 18%, transparent);'
: undefined}
class="align-text-middle my-7 h-10 w-full rounded-2xl border-2 border-solid border-ctp-surface1"
>
{event.name} - {event.division} - scoring {#if event.state == 1}- ONGOING
{/if}
</div>
<button onclick={() => (sortByScore = !sortByScore)}>
{sortByScore ? 'Sort: Score' : 'Sort: Manual'}
</button>
{#if event.state == 0}
<button onclick={startEvent} class="mb-4 rounded border-2 border-ctp-peach p-2"
>Start event</button
>
{/if}
<!-- <button onclick={() => (sortByScore = !sortByScore)}> -->
<!-- {sortByScore ? 'Sort: Score' : 'Sort: Manual'} -->
<!-- </button> -->
<div class="flex flex-row justify-center">
<div class="flex w-50 min-w-0 flex-col">
<div class="brackets-name text-bold">some</div>
<div class="brackets-name text-bold">=</div>
{#each Array.from({ length: highestPlayer + 1 }, (_, i) => i) as placement}
<div style="--player-color:white" class="scoring-player-card flex-1">
<div
@@ -289,6 +323,7 @@
<input
type="number"
placeholder="run {run + 1}"
disabled={event.state != 1}
value={pendingScores[player.id]?.[run] ?? ''}
oninput={(e) => {
const current = [
@@ -307,12 +342,13 @@
}}
/>
{/each}
{#if event.resultPresets[0].averageResults == 1}{/if}
</div>
</div>
<div class="text-sm opacity-60">
avg: {avgScore.toFixed(2)}
</div>
{#if event.resultPresets[0].averageResults == 1}
<div class="text-sm opacity-60">
avg: {avgScore.toFixed(2)}
</div>
{/if}
</div>
{/each}
</div>

View File

@@ -9,12 +9,18 @@
<form method="POST">
<label>
Username
<input name="username" type="text" autocomplete="username" required />
<input class="text-black" name="username" type="text" autocomplete="username" required />
</label>
<label>
Password
<input name="password" type="password" autocomplete="current-password" required />
<input
class="text-black"
name="password"
type="password"
autocomplete="current-password"
required
/>
</label>
{#if form?.message}
@@ -24,7 +30,7 @@
<button type="submit">Log in</button>
</form>
<p class="switch">No account? <a href="/signup">Sign up</a></p>
<!-- <p class="switch">No account? <a href="/signup">Sign up</a></p> -->
</div>
<style>