Compare commits

...

3 Commits

6 changed files with 77 additions and 29 deletions

View File

@@ -37,6 +37,7 @@ async function seed() {
await db.delete(schema.registeredEvents); await db.delete(schema.registeredEvents);
await db.delete(schema.eventTypes); await db.delete(schema.eventTypes);
await db.delete(schema.scoringPresets); await db.delete(schema.scoringPresets);
await db.delete(schema.brackets); // Added cleanup for brackets
await db.delete(schema.players); await db.delete(schema.players);
await db.delete(schema.divisions); await db.delete(schema.divisions);
await db.delete(schema.teams); await db.delete(schema.teams);
@@ -59,6 +60,13 @@ async function seed() {
console.log(` → Division: ${row.div_name}`); console.log(` → Division: ${row.div_name}`);
} }
// --- 2.5 Brackets (Added Section) ---
const bracketsCSV = readCSV('brackets.csv');
for (const row of bracketsCSV) {
await db.insert(schema.brackets).values({ name: row.bracket_name });
console.log(` → Bracket: ${row.bracket_name}`);
}
// --- 3. Scoring Presets --- // --- 3. Scoring Presets ---
const scoringPresetsCSV = readCSV('scoringPresets.csv'); const scoringPresetsCSV = readCSV('scoringPresets.csv');
for (const row of scoringPresetsCSV) { for (const row of scoringPresetsCSV) {
@@ -73,9 +81,12 @@ async function seed() {
// Maps for dynamic relational lookups // Maps for dynamic relational lookups
const dbTeams = await db.select().from(schema.teams); const dbTeams = await db.select().from(schema.teams);
const dbDivisions = await db.select().from(schema.divisions); const dbDivisions = await db.select().from(schema.divisions);
const dbBrackets = await db.select().from(schema.brackets); // Look up newly seeded brackets
const teamMap = new Map(dbTeams.map((t) => [t.name, t.id])); const teamMap = new Map(dbTeams.map((t) => [t.name, t.id]));
const divisionMap = new Map(dbDivisions.map((d) => [d.name, d.id])); const divisionMap = new Map(dbDivisions.map((d) => [d.name, d.id]));
const divisionNameMap = new Map([...divisionMap.entries()].map(([name, id]) => [id, name])); const divisionNameMap = new Map([...divisionMap.entries()].map(([name, id]) => [id, name]));
const bracketMap = new Map(dbBrackets.map((b) => [b.name, b.id])); // Map names to IDs
// --- 4. Players --- // --- 4. Players ---
const playersCSV = readCSV('players.csv'); const playersCSV = readCSV('players.csv');
@@ -109,7 +120,6 @@ async function seed() {
const eventTypeMap = new Map(dbEventTypes.map((et) => [et.name, et.id])); const eventTypeMap = new Map(dbEventTypes.map((et) => [et.name, et.id]));
// --- 6. Registered Events --- // --- 6. Registered Events ---
// Change the Map key type to a string (the event name)
const eventNameMap = new Map<string, number>(); const eventNameMap = new Map<string, number>();
const registeredEventsCSV = readCSV('registeredEvents.csv'); const registeredEventsCSV = readCSV('registeredEvents.csv');
@@ -145,19 +155,24 @@ async function seed() {
const divisionName = divisionNameMap.get(player?.division ?? -1); const divisionName = divisionNameMap.get(player?.division ?? -1);
const actualEventId = eventNameMap.get(`${row.event_registered}|${divisionName}`); const actualEventId = eventNameMap.get(`${row.event_registered}|${divisionName}`);
// Dynamic look up of the bracket row's primary key ID using the CSV text
const bracketId = bracketMap.get(row.bracket);
if (!player) throw new Error(`Player "${row.player_registered}" not found`); if (!player) throw new Error(`Player "${row.player_registered}" not found`);
if (!actualEventId) if (!actualEventId)
throw new Error( throw new Error(
`Registered Event "${row.event_registered}" for division "${divisionName}" not found` `Registered Event "${row.event_registered}" for division "${divisionName}" not found`
); );
if (!bracketId) throw new Error(`Bracket "${row.bracket}" not found in database`);
await db.insert(schema.registeredPlayers).values({ await db.insert(schema.registeredPlayers).values({
playerID: player.id, playerID: player.id,
registeredEventID: actualEventId, registeredEventID: actualEventId,
bracket: bracketId, // Using the real relational ID instead of raw value
placement: row.player_placement || 0 placement: row.player_placement || 0
}); });
console.log( console.log(
` → Registered Player: ${row.player_registered}${row.event_registered} (division: ${divisionName}) [eventId:${actualEventId}]` ` → Registered Player: ${row.player_registered}${row.event_registered} (division: ${divisionName}, bracket: ${row.bracket} [id:${bracketId}]) [eventId:${actualEventId}]`
); );
} }

View File

@@ -22,6 +22,11 @@ export const divisions = sqliteTable('divisions', {
name: text('div_name').notNull() name: text('div_name').notNull()
}); });
export const brackets = sqliteTable('brackets', {
id: integer('brackets_id').primaryKey({ autoIncrement: true }),
name: text('bracket_name').notNull()
});
export const scoringPresets = sqliteTable('scoringPresets', { export const scoringPresets = sqliteTable('scoringPresets', {
id: integer('scoringPresets_id').primaryKey({ autoIncrement: true }), id: integer('scoringPresets_id').primaryKey({ autoIncrement: true }),
presetID: integer('preset').notNull(), presetID: integer('preset').notNull(),
@@ -57,6 +62,9 @@ export const registeredPlayers = sqliteTable('registeredPlayers', {
registeredEventID: integer('event_registered') registeredEventID: integer('event_registered')
.references(() => registeredEvents.id) .references(() => registeredEvents.id)
.notNull(), .notNull(),
bracket: integer('bracket_registered')
.references(() => brackets.id)
.notNull(),
placement: integer('player_placement').notNull().default(0) placement: integer('player_placement').notNull().default(0)
}); });
@@ -115,6 +123,7 @@ export const registeredEventPlayersView = sqliteView('registeredEventPlayersView
firstName: players.firstName, firstName: players.firstName,
lastName: players.lastName, lastName: players.lastName,
placement: registeredPlayers.placement, placement: registeredPlayers.placement,
bracket: brackets.name,
eventId: registeredEvents.id, eventId: registeredEvents.id,
eventName: eventTypes.name, eventName: eventTypes.name,
teamId: teams.id, teamId: teams.id,
@@ -123,6 +132,7 @@ export const registeredEventPlayersView = sqliteView('registeredEventPlayersView
}) })
.from(registeredPlayers) .from(registeredPlayers)
.innerJoin(registeredEvents, eq(registeredPlayers.registeredEventID, registeredEvents.id)) .innerJoin(registeredEvents, eq(registeredPlayers.registeredEventID, registeredEvents.id))
.innerJoin(brackets, eq(registeredPlayers.bracket, brackets.id))
.innerJoin(eventTypes, eq(registeredEvents.eventType, eventTypes.id)) .innerJoin(eventTypes, eq(registeredEvents.eventType, eventTypes.id))
.innerJoin(players, eq(registeredPlayers.playerID, players.id)) .innerJoin(players, eq(registeredPlayers.playerID, players.id))
.innerJoin(teams, eq(players.team, teams.id)); .innerJoin(teams, eq(players.team, teams.id));

View File

@@ -57,13 +57,19 @@ export async function getAllRegisteredEventPlayers(eventId: number) {
const eventPlayers = await db const eventPlayers = await db
.select() .select()
.from(schema.registeredEventPlayersView) .from(schema.registeredEventPlayersView)
.where(eq(schema.registeredEventPlayersView.eventId, eventId)); .where(eq(schema.registeredEventPlayersView.eventId, eventId))
.orderBy(
schema.registeredEventPlayersView.bracket,
schema.registeredEventPlayersView.placement,
schema.registeredEventPlayersView.teamName
);
return { return {
eventPlayers: eventPlayers.map((players) => ({ eventPlayers: eventPlayers.map((players) => ({
id: players.playerId, id: players.playerId,
firstName: players.firstName, firstName: players.firstName,
lastName: players.lastName, lastName: players.lastName,
placement: players.placement, placement: players.placement,
bracket: players.bracket,
eventId: players.eventId, eventId: players.eventId,
eventName: players.eventName, eventName: players.eventName,
teamId: players.teamId, teamId: players.teamId,
@@ -72,3 +78,11 @@ export async function getAllRegisteredEventPlayers(eventId: number) {
})) }))
}; };
} }
export async function getAllBrackets() {
const brackets = await db.select().from(schema.brackets);
return {
brackets: brackets
};
}

View File

@@ -56,19 +56,21 @@
<td>{d.name}</td> <td>{d.name}</td>
<td>{d.division}</td> <td>{d.division}</td>
<td> <td>
<div class="flex justify-center"> <div class="">
{#each d.registeredPlayers as player} {#each d.registeredPlayers as bracket}
<div <div class="flex justify-center">
style="--theme-color: {player.teamColor};" {#each bracket.items as player}
class="player-box w-min-0 m-1 flex aspect-square h-[100px] flex-col rounded-md border-2" <div
> style="--theme-color: {player.teamColor};"
<div>{player.firstName} {player.lastName}</div> class="player-box w-min-0 m-1 flex-1 flex-col rounded-md border-2"
<div></div> >
<div>pic</div> <div>{player.firstName} {player.lastName}</div>
{#if player.placement != 0} <div></div>
<div>{player.placement}</div> {#if player.placement != 0}
{/if} <div>{player.placement}</div>
<div>{player.teamName}</div> {/if}
</div>
{/each}
</div> </div>
{/each} {/each}
</div> </div>
@@ -76,6 +78,7 @@
{/snippet} {/snippet}
<svelte:window onbeforeunload={() => scoreEndpoint?.close()} /> <svelte:window onbeforeunload={() => scoreEndpoint?.close()} />
<Table data={eventTable} {header} {row} />
<div class="p-[2vw]"> <div class="p-[2vw]">
{#each leaderboard as team (team.name)} {#each leaderboard as team (team.name)}
@@ -100,8 +103,6 @@
Send update Send update
</button> </button>
<Table data={eventTable} {header} {row} />
<style> <style>
@import url('https://cdn.jsdelivr.net/npm/@catppuccin/palette/css/catppuccin.css'); @import url('https://cdn.jsdelivr.net/npm/@catppuccin/palette/css/catppuccin.css');
.score-box { .score-box {

View File

@@ -5,13 +5,13 @@
<table class="w-full table-auto"> <table class="w-full table-auto">
{#if header} {#if header}
<thead> <thead>
<tr>{@render header()}</tr> <tr class="justify-content-center">{@render header()}</tr>
</thead> </thead>
{/if} {/if}
<tbody> <tbody>
{#each data as d} {#each data as d}
<tr>{@render row(d)}</tr> <tr class="text-center">{@render row(d)}</tr>
{/each} {/each}
</tbody> </tbody>
</table> </table>

View File

@@ -1,7 +1,8 @@
import { import {
globalEmitter, globalEmitter,
getRegisteredEvents, getRegisteredEvents,
getAllRegisteredEventPlayers getAllRegisteredEventPlayers,
getAllBrackets
} from '$lib/server/eventManager'; } from '$lib/server/eventManager';
import { generateEndpoint } from '$lib/server/endpoint'; import { generateEndpoint } from '$lib/server/endpoint';
@@ -13,6 +14,10 @@ export async function GET() {
let newEvents = await getRegisteredEvents(); let newEvents = await getRegisteredEvents();
let registeredEventList = newEvents['events']; let registeredEventList = newEvents['events'];
// Get all possible brackets from the database
let brackets = await getAllBrackets();
// Initilise the final eventList
let fullEventList: any[] = []; let fullEventList: any[] = [];
// For every event // For every event
@@ -22,17 +27,20 @@ export async function GET() {
// Get all players for the event // Get all players for the event
let registeredPlayers = await getAllRegisteredEventPlayers(event.id); let registeredPlayers = await getAllRegisteredEventPlayers(event.id);
// Some nonsense to extract the players into a better object // Map the players into an [] with structure {id: number, name: string, items: any[]}
let registeredPlayersVec: any[] = []; // So that the players are sorted by bracket for the frontend
for (let player in registeredPlayers.eventPlayers) { const bracketOrder = brackets.brackets.map((category) => {
let currentPlayer = registeredPlayers.eventPlayers[player]; return {
registeredPlayersVec.push(currentPlayer); ...category,
} // Filter the items that match the current bracket name
items: registeredPlayers.eventPlayers.filter((item) => item.bracket === category.name)
};
});
// add registeredPlayers as part of the event object // append the player info to the event object
let eventWithPlayers = { let eventWithPlayers = {
...event, ...event,
registeredPlayers: registeredPlayersVec registeredPlayers: bracketOrder
}; };
// combine all of the events into one array // combine all of the events into one array
fullEventList.push(eventWithPlayers); fullEventList.push(eventWithPlayers);