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() { __devenv_reload_apply() {
# Source new environment if a reload is pending # 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) # Shell out to bash to handle the env diff (bash syntax)
local reload_output local reload_output
reload_output=$(bash -c ' reload_output=$(bash -c '
@@ -158,8 +158,8 @@ _before=$(mktemp)
__devenv_capture_env > "$_before" __devenv_capture_env > "$_before"
# Source new devenv environment # Source new devenv environment
source "/tmp/nix-shell-28554-2490132097/devenv-reload-30583.sh" source "/tmp/devenv-reload-274471.sh"
rm -f "/tmp/nix-shell-28554-2490132097/devenv-reload-30583.sh" rm -f "/tmp/devenv-reload-274471.sh"
# Compute new diff # Compute new diff
__devenv_compute_diff "$_before" __devenv_compute_diff "$_before"

1
.gitignore vendored
View File

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

View File

@@ -4,7 +4,8 @@ event_name,preset,resultPreset
500m Relay,1,race 500m Relay,1,race
750m Race,1,race 750m Race,1,race
1000m Long Distance,1,race 1000m Long Distance,1,race
Javelin, 2,default Javelin, 1,three
Shotput, 2,default Shotput, 1,three
Long Jump, 2,three Long Jump, 1,three
Triple Jump, 2,default 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,3,3
1,4,2 1,4,2
1,5,1 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 { db } from '$lib/server/db';
import { eq } from 'drizzle-orm'; import { eq } from 'drizzle-orm';
import * as schema from '$lib/server/db/schema'; import * as schema from '$lib/server/db/schema';
import { globalEmitter } from './globalEmitter';
// For page.server.ts so that it doesnt look weird before loading // For page.server.ts so that it doesnt look weird before loading
export async function getAllInitialInfo() { export async function getAllInitialInfo() {
@@ -67,6 +68,28 @@ export async function getRegisteredEvents(eventId?: number) {
return { events }; 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 // Get all players with an event id specified
export async function getAllRegisteredEventPlayers(eventId: number) { export async function getAllRegisteredEventPlayers(eventId: number) {
const eventPlayers = await db const eventPlayers = await db

View File

@@ -7,11 +7,16 @@
<svelte:head><link rel="icon" href={favicon} /></svelte:head> <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 <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 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> </div>
{@render children()} {@render children()}

View File

@@ -94,7 +94,7 @@
{#if leaderboard[0]} {#if leaderboard[0]}
{@const team = leaderboard[0]} {@const team = leaderboard[0]}
<a <a
href="/team/{team.id}" href="/"
class="score-box winner" class="score-box winner"
style="--c:{team.color}" style="--c:{team.color}"
aria-label="{team.name}, 1st place, {team.points} points" 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)}"> <div class="runners-grid" style="--runner-count:{Math.min(leaderboard.length - 1, 5)}">
{#each leaderboard.slice(1) as team, i (team.name)} {#each leaderboard.slice(1) as team, i (team.name)}
<a <a
href="/team/{team.id}" href="/"
class="score-box runner" class="score-box runner"
style="--c:{team.color}" style="--c:{team.color}"
aria-label="{team.name}, {ordinal(i + 2)} place, {team.points} points" 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]} {@const event = eventData[0]}
<div class="flex justify-center"> <div class="flex justify-center">
<div class="w-full flex-col px-[5vw] text-center"> <div class="w-full flex-col px-[5vw] text-center">
{console.log(event)} <div
<div class="align-text-middle h-10 w-full bg-red-500">{event.name} - {event.division}</div> class="align-text-middle my-7 h-10 w-full rounded-2xl border-2 border-solid border-ctp-surface1"
div >
{event.name} - {event.division}
</div>
{#each event.registeredPlayers as bracket, bi} {#each event.registeredPlayers as bracket, bi}
{#if bi > 0} {#if bi > 0}
<div class="bracket-sep" aria-hidden="true"></div> <div class="bracket-sep" aria-hidden="true"></div>
@@ -75,7 +77,7 @@
<div class="bracket-vertical-sep"></div> <div class="bracket-vertical-sep"></div>
</div> </div>
{#each bracket.items as player} {#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"> <div class="player-ghost" aria-hidden="true">
<svg viewBox="0 0.1 100 0.6" preserveAspectRatio="none" class="ghost-svg"> <svg viewBox="0 0.1 100 0.6" preserveAspectRatio="none" class="ghost-svg">
<text <text
@@ -90,7 +92,7 @@
</svg> </svg>
</div> </div>
<div class="player-name-wrap" use:marquee> <div class="player-name-wrap" use:marquee>
<span class="marquee-inner"> <span class=" text-xl">
{player.firstName} {player.firstName}
{player.lastName} {player.lastName}
</span> </span>
@@ -106,4 +108,10 @@
{/each} {/each}
</div> </div>
</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} {/await}

View File

@@ -126,7 +126,6 @@
for (let player in brackets[bracket].items) { for (let player in brackets[bracket].items) {
if (parseInt(player) > highestPlayer) { if (parseInt(player) > highestPlayer) {
highestPlayer = parseInt(player); highestPlayer = parseInt(player);
console.log(highestPlayer, 'high');
} }
} }
} }
@@ -145,6 +144,15 @@
loading = false; loading = false;
eventEndpoint = new EventSource('/api/registeredEvents'); 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(() => { onDestroy(() => {
@@ -176,6 +184,20 @@
dropTarget = null; 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() { async function submitResults() {
submitStatus = 'submitting'; submitStatus = 'submitting';
try { try {
@@ -215,17 +237,29 @@
{:else} {:else}
<div class="flex justify-center"> <div class="flex justify-center">
<div class="w-full flex-col px-[2vw] text-center"> <div class="w-full flex-col px-[2vw] text-center">
<div class="align-text-middle h-10 w-full bg-red-500"> <div
{event.name} - {event.division} - scoring 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> </div>
<button onclick={() => (sortByScore = !sortByScore)}> {#if event.state == 0}
{sortByScore ? 'Sort: Score' : 'Sort: Manual'} <button onclick={startEvent} class="mb-4 rounded border-2 border-ctp-peach p-2"
</button> >Start event</button
>
{/if}
<!-- <button onclick={() => (sortByScore = !sortByScore)}> -->
<!-- {sortByScore ? 'Sort: Score' : 'Sort: Manual'} -->
<!-- </button> -->
<div class="flex flex-row justify-center"> <div class="flex flex-row justify-center">
<div class="flex w-50 min-w-0 flex-col"> <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} {#each Array.from({ length: highestPlayer + 1 }, (_, i) => i) as placement}
<div style="--player-color:white" class="scoring-player-card flex-1"> <div style="--player-color:white" class="scoring-player-card flex-1">
<div <div
@@ -289,6 +323,7 @@
<input <input
type="number" type="number"
placeholder="run {run + 1}" placeholder="run {run + 1}"
disabled={event.state != 1}
value={pendingScores[player.id]?.[run] ?? ''} value={pendingScores[player.id]?.[run] ?? ''}
oninput={(e) => { oninput={(e) => {
const current = [ const current = [
@@ -307,12 +342,13 @@
}} }}
/> />
{/each} {/each}
{#if event.resultPresets[0].averageResults == 1}{/if}
</div> </div>
</div> </div>
<div class="text-sm opacity-60"> {#if event.resultPresets[0].averageResults == 1}
avg: {avgScore.toFixed(2)} <div class="text-sm opacity-60">
</div> avg: {avgScore.toFixed(2)}
</div>
{/if}
</div> </div>
{/each} {/each}
</div> </div>

View File

@@ -9,12 +9,18 @@
<form method="POST"> <form method="POST">
<label> <label>
Username Username
<input name="username" type="text" autocomplete="username" required /> <input class="text-black" name="username" type="text" autocomplete="username" required />
</label> </label>
<label> <label>
Password Password
<input name="password" type="password" autocomplete="current-password" required /> <input
class="text-black"
name="password"
type="password"
autocomplete="current-password"
required
/>
</label> </label>
{#if form?.message} {#if form?.message}
@@ -24,7 +30,7 @@
<button type="submit">Log in</button> <button type="submit">Log in</button>
</form> </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> </div>
<style> <style>