From ce2d13e5e771fc8065e01969068c925e919364e7 Mon Sep 17 00:00:00 2001 From: Craig Kaiser Date: Sun, 28 Jul 2024 16:20:22 -0400 Subject: [PATCH 1/6] update when we pass Id --- src/components/Bracket.svelte | 32 ++++++++++--------- src/components/Teams.svelte | 18 ++++++----- src/lib/brackets/brackets.svelte.ts | 4 +-- .../database/{event.svelte.ts => event.ts} | 2 +- .../{matches.svelte.ts => matches.ts} | 2 +- ...e.svelte.ts => supabaseDatabaseService.ts} | 3 +- .../database/{teams.svelte.ts => teams.ts} | 5 +-- src/lib/event.svelte.ts | 19 ++++++----- src/lib/helper.svelte.ts | 21 +++++++----- src/lib/matches.svelte.ts | 15 ++++----- src/lib/teams.svelte.ts | 18 +++++++---- src/routes/+page.svelte | 7 ++-- src/routes/events/[slug]/+page.server.ts | 4 +-- src/routes/events/[slug]/+page.svelte | 15 +++++---- .../protected-routes/dashboard/+page.ts | 2 +- 15 files changed, 91 insertions(+), 76 deletions(-) rename src/lib/database/{event.svelte.ts => event.ts} (99%) rename src/lib/database/{matches.svelte.ts => matches.ts} (99%) rename src/lib/database/{supabaseDatabaseService.svelte.ts => supabaseDatabaseService.ts} (98%) rename src/lib/database/{teams.svelte.ts => teams.ts} (96%) diff --git a/src/components/Bracket.svelte b/src/components/Bracket.svelte index 5cc5227..72703f0 100644 --- a/src/components/Bracket.svelte +++ b/src/components/Bracket.svelte @@ -70,21 +70,23 @@ async function generateBracket() { try { - if (matchesSubscription) await matchesSubscription.unsubscribe(); - - const res = await bracket.createBracketMatches( - tournament, - teams.teams, - matches.matches || [] - ); - if (!res) { - error('Failed to create matches'); - } else { - // We need to wait to resub to the matches channel - await new Promise((r) => setTimeout(r, 1000)); - - matchesSubscription = await bracket.subscribeToMatches(); - await bracket.load(); + if (bracket.event_id) { + if (matchesSubscription) await matchesSubscription.unsubscribe(); + + const res = await bracket.createBracketMatches( + tournament, + teams.teams, + matches.matches || [] + ); + if (!res) { + error('Failed to create matches'); + } else { + // We need to wait to resub to the matches channel + await new Promise((r) => setTimeout(r, 1000)); + + matchesSubscription = await bracket.subscribeToMatches(); + await bracket.load(bracket.event_id); + } } } catch (err) { error((err as HttpError).toString()); diff --git a/src/components/Teams.svelte b/src/components/Teams.svelte index b049a72..8207de1 100644 --- a/src/components/Teams.svelte +++ b/src/components/Teams.svelte @@ -44,15 +44,17 @@ } async function loadEventTeams() { - try { - const res = await teams.load(); - // @ts-ignore - currentTeams = res; - } catch (err) { - if (isHttpError(err)) { - error(err.body.message); + if (teams.event_id) { + try { + const res = await teams.load(teams.event_id); + // @ts-ignore + currentTeams = res; + } catch (err) { + if (isHttpError(err)) { + error(err.body.message); + } + error('Something has gone very wrong'); } - error('Something has gone very wrong'); } } let newTeamName = $state(''); diff --git a/src/lib/brackets/brackets.svelte.ts b/src/lib/brackets/brackets.svelte.ts index de1e550..ac83d1e 100644 --- a/src/lib/brackets/brackets.svelte.ts +++ b/src/lib/brackets/brackets.svelte.ts @@ -7,9 +7,9 @@ export class Brackets extends Matches { type = 'bracket'; // Overload Matches load method to only load our bracket matches. - async load() { + async load(eventId: number): Promise { try { - const res = await this.databaseService.load(this.event_id, { + const res = await this.databaseService.load(eventId, { column: 'type', operator: 'eq', value: 'bracket' diff --git a/src/lib/database/event.svelte.ts b/src/lib/database/event.ts similarity index 99% rename from src/lib/database/event.svelte.ts rename to src/lib/database/event.ts index 5474a24..514be6e 100644 --- a/src/lib/database/event.svelte.ts +++ b/src/lib/database/event.ts @@ -1,4 +1,4 @@ -import { SupabaseDatabaseService } from '$lib/database/supabaseDatabaseService.svelte'; +import { SupabaseDatabaseService } from '$lib/database/supabaseDatabaseService'; import type { PostgrestResponse, PostgrestSingleResponse } from '@supabase/supabase-js'; import { z } from 'zod'; import { eventsRowSchema, eventsUpdateSchema } from '$schemas/supabase'; diff --git a/src/lib/database/matches.svelte.ts b/src/lib/database/matches.ts similarity index 99% rename from src/lib/database/matches.svelte.ts rename to src/lib/database/matches.ts index a99b239..9afd84c 100644 --- a/src/lib/database/matches.svelte.ts +++ b/src/lib/database/matches.ts @@ -1,4 +1,4 @@ -import { SupabaseDatabaseService } from '$lib/database/supabaseDatabaseService.svelte'; +import { SupabaseDatabaseService } from '$lib/database/supabaseDatabaseService'; import type { PostgrestResponse } from '@supabase/supabase-js'; import { z } from 'zod'; import { matchesRowSchema, matchesUpdateSchema, matchesInsertSchema } from '$schemas/supabase'; diff --git a/src/lib/database/supabaseDatabaseService.svelte.ts b/src/lib/database/supabaseDatabaseService.ts similarity index 98% rename from src/lib/database/supabaseDatabaseService.svelte.ts rename to src/lib/database/supabaseDatabaseService.ts index a95c446..b3f1dd9 100644 --- a/src/lib/database/supabaseDatabaseService.svelte.ts +++ b/src/lib/database/supabaseDatabaseService.ts @@ -113,7 +113,8 @@ export class SupabaseDatabaseService { .subscribe((status) => { // We call the load function to update in case our content is stale // when we re-connect to the web socket. - self.load(); + if (self.event_id) self.load(self.event_id); + self.subscriptionStatus = status; console.debug('Realtime status', status); }); diff --git a/src/lib/database/teams.svelte.ts b/src/lib/database/teams.ts similarity index 96% rename from src/lib/database/teams.svelte.ts rename to src/lib/database/teams.ts index 31bfcba..f5f527a 100644 --- a/src/lib/database/teams.svelte.ts +++ b/src/lib/database/teams.ts @@ -1,4 +1,4 @@ -import { SupabaseDatabaseService } from '$lib/database/supabaseDatabaseService.svelte'; +import { SupabaseDatabaseService } from '$lib/database/supabaseDatabaseService'; import type { PostgrestResponse } from '@supabase/supabase-js'; import { z } from 'zod'; import { teamsRowSchema } from '$schemas/supabase'; @@ -18,7 +18,7 @@ export class TeamsSupabaseDatabaseService extends SupabaseDatabaseService { .insert({ ...team }) .select(); - this.validateAndHandleErrors(res, TeamsRowSchemaArray); + this.validateAndHandleErrors(res, teamsRowSchema); // Return the newly created or updated team return res.data as unknown as TeamRow; @@ -43,6 +43,7 @@ export class TeamsSupabaseDatabaseService extends SupabaseDatabaseService { .select('*') .eq('event_id', event_id); + // @ts-ignore this.validateAndHandleErrors(res, TeamsRowSchemaArray); // Return the loaded teams diff --git a/src/lib/event.svelte.ts b/src/lib/event.svelte.ts index 35d933a..ea8bba7 100644 --- a/src/lib/event.svelte.ts +++ b/src/lib/event.svelte.ts @@ -1,4 +1,4 @@ -import type { EventSupabaseDatabaseService } from '$lib/database/event.svelte'; +import type { EventSupabaseDatabaseService } from '$lib/database/event'; import type { Infer } from 'sveltekit-superforms'; import { Base } from './base'; import type { FormSchema } from '$schemas/settingsSchema'; @@ -12,7 +12,7 @@ export class Event extends Base { private databaseService: EventSupabaseDatabaseService; // Event properties - id: number; + id?: number; name?: string; date?: string; pools?: number; @@ -25,17 +25,12 @@ export class Event extends Base { /** * The constructor for the Event class. - * @param {number} event_id - The ID of the event. * @param {EventSupabaseDatabaseService} databaseService - The service used to interact with the database. */ - constructor(event_id: number, databaseService: EventSupabaseDatabaseService) { + constructor(databaseService: EventSupabaseDatabaseService) { super(); - if (!event_id) { - this.handleError(400, 'Invalid event ID, are you sure your link is correct?'); - } this.databaseService = databaseService; - this.id = event_id; } /** @@ -81,9 +76,13 @@ export class Event extends Base { * Load the event (tournament settings) from the database. * @returns {Promise} - Returns a promise that resolves to the loaded event. */ - async load(): Promise { + async load(id: number): Promise { + if (!id) { + this.handleError(400, 'Invalid event ID, are you sure your link is correct?'); + } + try { - const eventResponse: EventRow | null = await this.databaseService.load(this.id); + const eventResponse: EventRow | null = await this.databaseService.load(id); if (eventResponse !== null) { Object.assign(this, eventResponse); diff --git a/src/lib/helper.svelte.ts b/src/lib/helper.svelte.ts index 42b9dd7..3120e03 100644 --- a/src/lib/helper.svelte.ts +++ b/src/lib/helper.svelte.ts @@ -2,9 +2,9 @@ import { Matches } from './matches.svelte'; import { pushState } from '$app/navigation'; import type { HttpError } from '@sveltejs/kit'; import { error, success } from '$lib/toast'; -import { EventSupabaseDatabaseService } from '$lib/database/event.svelte'; -import { MatchesSupabaseDatabaseService } from '$lib/database/matches.svelte'; -import { TeamsSupabaseDatabaseService } from '$lib/database/teams.svelte'; +import { EventSupabaseDatabaseService } from '$lib/database/event'; +import { MatchesSupabaseDatabaseService } from '$lib/database/matches'; +import { TeamsSupabaseDatabaseService } from '$lib/database/teams'; import { Brackets } from '$lib/brackets/brackets.svelte'; import { Event as EventInstance } from '$lib/event.svelte'; import { Pool } from '$lib/pool/pool.svelte'; @@ -50,18 +50,23 @@ export async function initiateEvent( bracket: Brackets; }> { const eventSupabaseDatabaseService = new EventSupabaseDatabaseService(supabase); - const tournament = $state(new EventInstance(eventId, eventSupabaseDatabaseService)); + const tournament = new EventInstance(eventSupabaseDatabaseService); const matchesSupabaseDatabaseService = new MatchesSupabaseDatabaseService(supabase); - const matches = $state(new Pool(eventId, matchesSupabaseDatabaseService)); + const matches = new Pool(matchesSupabaseDatabaseService); const teamsSupabaseDatabaseService = new TeamsSupabaseDatabaseService(supabase); - const teams = $state(new TeamsInstance(eventId, teamsSupabaseDatabaseService)); + const teams = new TeamsInstance(teamsSupabaseDatabaseService); - const bracket = $state(new Brackets(eventId, matchesSupabaseDatabaseService)); + const bracket = new Brackets(matchesSupabaseDatabaseService); try { - await Promise.all([tournament.load(), matches.load(), teams.load(), bracket.load()]); + await Promise.all([ + tournament.load(eventId), + matches.load(eventId), + teams.load(eventId), + bracket.load(eventId) + ]); } catch (err) { console.error('Error loading event data:', err); throw new Error( diff --git a/src/lib/matches.svelte.ts b/src/lib/matches.svelte.ts index 0360ad3..3ba3039 100644 --- a/src/lib/matches.svelte.ts +++ b/src/lib/matches.svelte.ts @@ -1,4 +1,4 @@ -import type { MatchesSupabaseDatabaseService } from '$lib/database/matches.svelte'; +import type { MatchesSupabaseDatabaseService } from '$lib/database/matches'; import { RoundRobin } from './brackets/roundRobin'; import type { RealtimeChannel, RealtimePostgresChangesPayload } from '@supabase/supabase-js'; import { Base } from './base'; @@ -7,20 +7,19 @@ import { Event } from '$lib/event.svelte'; export class Matches extends Base { public databaseService: MatchesSupabaseDatabaseService; - event_id: number; + event_id?: number; matches?: MatchRow[] = $state(); subscriptionStatus? = $state(); type = 'pool'; - constructor(event_id: number, databaseService: MatchesSupabaseDatabaseService) { + constructor(databaseService: MatchesSupabaseDatabaseService) { super(); this.databaseService = databaseService; - this.event_id = Number(event_id); } - async load() { + async load(id: number) { try { - const res = await this.databaseService.load(this.event_id, { + const res = await this.databaseService.load(id, { column: 'type', operator: 'eq', value: this.type @@ -44,12 +43,12 @@ export class Matches extends Base { if (self.type !== updated.type) return; if (self.type === 'bracket') { - await self.load(); + await self.load(self.event_id); (self as Brackets).nextRound(updated); } if (!self.matches) { - await self.load(); + await self.load(self.event_id); return; } diff --git a/src/lib/teams.svelte.ts b/src/lib/teams.svelte.ts index 1960228..550fcf4 100644 --- a/src/lib/teams.svelte.ts +++ b/src/lib/teams.svelte.ts @@ -1,9 +1,9 @@ -import type { TeamsSupabaseDatabaseService } from '$lib/database/teams.svelte'; +import type { TeamsSupabaseDatabaseService } from '$lib/database/teams'; import { Base } from './base'; export class Teams extends Base { private databaseService: TeamsSupabaseDatabaseService; - event_id: number; + event_id?: number; teams: TeamRow[] = $state([]); /** @@ -11,21 +11,25 @@ export class Teams extends Base { * @param {number} event_id - The ID of the event. * @param {TeamsSupabaseDatabaseService} databaseService - The service used to interact with the database. */ - constructor(event_id: number, databaseService: TeamsSupabaseDatabaseService) { + constructor(databaseService: TeamsSupabaseDatabaseService) { super(); this.databaseService = databaseService; - this.event_id = event_id; } /** * Load all teams for the current event. * @returns {Promise} - A promise that resolves to the loaded teams. */ - async load(): Promise { + async load(eventId: number): Promise { + if (!eventId) { + this.handleError(400, 'Invalid event ID'); + return undefined; + } + try { - const res = await this.databaseService.load(this.event_id); + const res = await this.databaseService.load(eventId); if (!res) { - console.warn('Failed to load teams for event', this.event_id); + console.warn('Failed to load teams for event', eventId); return undefined; } this.teams = res; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index ca97556..eb0af74 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,10 +1,9 @@
@@ -108,54 +109,56 @@ - {#each Array(rounds) as _, i} - {@const round = i + 1} - - {#each Array(tournament.courts) as _, court} - {@const match = matches.matches.find( - (m: MatchRow) => m.court === court && m.round.toString() === round.toString() - )} - {#if match} - {@const matchComplete = match.team1_score !== null && match.team2_score !== null} - {@const teamsForMatch = [ - match.public_matches_team1_fkey.name, - match.public_matches_team2_fkey.name - ]} - {@const hasDefaultTeam = defaultTeam ? teamsForMatch.includes(defaultTeam) : false} - {@const defaultTeamWin = - match.public_matches_team1_fkey.name == defaultTeam - ? (match.team1_score ?? 0) > (match.team2_score ?? 0) - : (match.team2_score ?? 0) > (match.team1_score ?? 0)} - {@const rowTdClass = defaultTeamWin - ? 'border-solid border-2 border-green-400 bg-green-200 dark:bg-green-700 dark:border-green-700' - : 'border-solid border-2 border-red-400 bg-red-200 dark:bg-red-700 dark:border-red-700'} + {#if rounds} + {#each Array(rounds) as _, i} + {@const round = i + 1} + + {#each Array(tournament.courts) as _, court} + {@const match = matches.matches.find( + (m: MatchRow) => m.court === court && m.round.toString() === round.toString() + )} + {#if match} + {@const matchComplete = match.team1_score !== null && match.team2_score !== null} + {@const teamsForMatch = [ + match.public_matches_team1_fkey.name, + match.public_matches_team2_fkey.name + ]} + {@const hasDefaultTeam = defaultTeam ? teamsForMatch.includes(defaultTeam) : false} + {@const defaultTeamWin = + match.public_matches_team1_fkey.name == defaultTeam + ? (match.team1_score ?? 0) > (match.team2_score ?? 0) + : (match.team2_score ?? 0) > (match.team1_score ?? 0)} + {@const rowTdClass = defaultTeamWin + ? 'border-solid border-2 border-green-400 bg-green-200 dark:bg-green-700 dark:border-green-700' + : 'border-solid border-2 border-red-400 bg-red-200 dark:bg-red-700 dark:border-red-700'} + + + + {:else} + + {/if} + {/each} + {#if tournament.refs === 'teams'} + {@const ref = matches.matches.find( + (m: MatchRow) => m.round.toString() === round.toString() + )?.public_matches_ref_fkey} - + {ref?.name} - {:else} - {/if} - {/each} - {#if tournament.refs === 'teams'} - {@const ref = matches.matches.find( - (m: MatchRow) => m.round.toString() === round.toString() - )?.public_matches_ref_fkey} - - {ref?.name} - - {/if} - - {/each} + + {/each} + {/if} {/if} diff --git a/src/components/Settings.svelte b/src/components/Settings.svelte index a255b70..42df0fb 100644 --- a/src/components/Settings.svelte +++ b/src/components/Settings.svelte @@ -31,7 +31,7 @@ import CalendarIcon from 'lucide-svelte/icons/calendar'; export let data; - export let event_id; + export let eventId; let form = superForm(data.form, { validators: zodClient(formSchema), @@ -41,6 +41,7 @@ onUpdated({ form }) { if (form.valid) { success(`Tournament settings updated`); + data.tournament.load(data.eventId); } } }); @@ -72,7 +73,7 @@
@@ -240,7 +241,7 @@
-{#if event_id !== 'create'} +{#if eventId !== 'create'}