diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 5f777a2..16f72cc 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -58,7 +58,9 @@ registrations events import - settings + players + users + settings {/if} diff --git a/src/routes/manage-players/+page.server.ts b/src/routes/manage-players/+page.server.ts new file mode 100644 index 0000000..37f4789 --- /dev/null +++ b/src/routes/manage-players/+page.server.ts @@ -0,0 +1,136 @@ +import { error, redirect, fail } from '@sveltejs/kit'; +import { eq } from 'drizzle-orm'; +import { db } from '$lib/server/db'; +import { scorers, players, teams, divisions } from '$lib/server/db/schema'; +import type { PageServerLoad, Actions } from './$types'; + +export const load: PageServerLoad = async ({ locals }) => { + if (!locals.user) throw redirect(303, '/login'); + + const [row] = await db + .select({ role: scorers.role }) + .from(scorers) + .where(eq(scorers.id, locals.user.id)); + + if (row?.role !== 'admin') throw error(403, 'Forbidden'); + + const playerList = await db + .select({ + id: players.id, + firstName: players.firstName, + lastName: players.lastName, + teamId: players.team, + teamName: teams.name, + divisionId: players.division, + divisionName: divisions.name + }) + .from(players) + .leftJoin(teams, eq(players.team, teams.id)) + .leftJoin(divisions, eq(players.division, divisions.id)) + .orderBy(players.firstName, players.lastName); + + const teamList = await db.select().from(teams).orderBy(teams.name); + const divisionList = await db.select().from(divisions).orderBy(divisions.name); + + return { players: playerList, teams: teamList, divisions: divisionList }; +}; + +export const actions: Actions = { + createPlayer: async ({ locals, request }) => { + if (!locals.user) throw error(401, 'Unauthorized'); + + const [row] = await db + .select({ role: scorers.role }) + .from(scorers) + .where(eq(scorers.id, locals.user.id)); + + if (row?.role !== 'admin') throw error(403, 'Forbidden'); + + const data = await request.formData(); + const firstName = (data.get('firstName') as string)?.trim(); + const lastName = (data.get('lastName') as string)?.trim(); + const teamId = data.get('teamId') as string; + const divisionId = data.get('divisionId') as string; + + if (!firstName || !lastName || !teamId) { + return fail(400, { createMessage: 'First name, last name, and team are required' }); + } + + await db + .insert(players) + .values({ + firstName, + lastName, + team: parseInt(teamId), + division: divisionId ? parseInt(divisionId) : null + }); + + return { success: true }; + }, + + editPlayer: async ({ locals, request }) => { + if (!locals.user) throw error(401, 'Unauthorized'); + + const [row] = await db + .select({ role: scorers.role }) + .from(scorers) + .where(eq(scorers.id, locals.user.id)); + + if (row?.role !== 'admin') throw error(403, 'Forbidden'); + + const data = await request.formData(); + const playerId = data.get('playerId') as string; + const firstName = (data.get('firstName') as string)?.trim(); + const lastName = (data.get('lastName') as string)?.trim(); + const teamId = data.get('teamId') as string; + const divisionId = data.get('divisionId') as string; + + if (!playerId || !firstName || !lastName || !teamId) { + return fail(400, { editMessage: 'First name, last name, and team are required' }); + } + + const [existing] = await db.select().from(players).where(eq(players.id, parseInt(playerId))); + if (!existing) { + return fail(404, { editMessage: 'Player not found' }); + } + + await db + .update(players) + .set({ + firstName, + lastName, + team: parseInt(teamId), + division: divisionId ? parseInt(divisionId) : null + }) + .where(eq(players.id, parseInt(playerId))); + + return { success: true }; + }, + + deletePlayer: async ({ locals, request }) => { + if (!locals.user) throw error(401, 'Unauthorized'); + + const [row] = await db + .select({ role: scorers.role }) + .from(scorers) + .where(eq(scorers.id, locals.user.id)); + + if (row?.role !== 'admin') throw error(403, 'Forbidden'); + + const data = await request.formData(); + const playerId = data.get('playerId') as string; + + if (!playerId) { + return fail(400, { deleteMessage: 'Player ID required' }); + } + + const [existing] = await db.select().from(players).where(eq(players.id, parseInt(playerId))); + if (!existing) { + return fail(404, { deleteMessage: 'Player not found' }); + } + + await db.delete(players).where(eq(players.id, parseInt(playerId))); + + return { success: true }; + } +}; diff --git a/src/routes/manage-players/+page.svelte b/src/routes/manage-players/+page.svelte new file mode 100644 index 0000000..fe094eb --- /dev/null +++ b/src/routes/manage-players/+page.svelte @@ -0,0 +1,383 @@ + + +
| First Name | +Last Name | +Team | +Division | +Actions | + {/snippet} + {#snippet row(player: (typeof data.players)[number])} +{player.firstName} | +{player.lastName} | +{player.teamName} | +{player.divisionName ?? '-'} | ++ + + | + {/snippet} +
|---|
{deleteMessage}
+ {/if} +| Username | +Role | + {/snippet} + {#snippet row(user: (typeof data.users)[number])} +{user.username} | +{user.role} | + {/snippet} +
|---|