From 03f55baf1c1e34f2668e5755d1ada58c1ccb446b Mon Sep 17 00:00:00 2001 From: orosmatthew Date: Sat, 29 Apr 2023 21:09:39 -0400 Subject: [PATCH] Add contests --- web/prisma/schema.prisma | 9 ++ web/src/routes/admin/+layout.svelte | 1 + web/src/routes/admin/contests/+page.server.ts | 11 ++ web/src/routes/admin/contests/+page.svelte | 26 ++++ .../contests/[contestId]/+page.server.ts | 26 ++++ .../admin/contests/[contestId]/+page.svelte | 36 ++++++ .../admin/contests/create/+page.server.ts | 47 +++++++ .../routes/admin/contests/create/+page.svelte | 115 ++++++++++++++++++ 8 files changed, 271 insertions(+) create mode 100644 web/src/routes/admin/contests/+page.server.ts create mode 100644 web/src/routes/admin/contests/+page.svelte create mode 100644 web/src/routes/admin/contests/[contestId]/+page.server.ts create mode 100644 web/src/routes/admin/contests/[contestId]/+page.svelte create mode 100644 web/src/routes/admin/contests/create/+page.server.ts create mode 100644 web/src/routes/admin/contests/create/+page.svelte diff --git a/web/prisma/schema.prisma b/web/prisma/schema.prisma index 890502d..23c8013 100644 --- a/web/prisma/schema.prisma +++ b/web/prisma/schema.prisma @@ -48,10 +48,19 @@ model Problem { realInput String realOutput String Submission Submission[] + contests Contest[] @relation("ProblemContestRelation") } model Team { id Int @id @default(autoincrement()) name String @unique Submission Submission[] + contests Contest[] @relation("TeamContestRelation") +} + +model Contest { + id Int @id @default(autoincrement()) + name String + teams Team[] @relation("TeamContestRelation") + problems Problem[] @relation("ProblemContestRelation") } diff --git a/web/src/routes/admin/+layout.svelte b/web/src/routes/admin/+layout.svelte index a0bcf6f..d652b4b 100644 --- a/web/src/routes/admin/+layout.svelte +++ b/web/src/routes/admin/+layout.svelte @@ -6,6 +6,7 @@
  • Problems
  • Scoreboard
  • Teams
  • +
  • Contests
  • Logout
  • diff --git a/web/src/routes/admin/contests/+page.server.ts b/web/src/routes/admin/contests/+page.server.ts new file mode 100644 index 0000000..9270b13 --- /dev/null +++ b/web/src/routes/admin/contests/+page.server.ts @@ -0,0 +1,11 @@ +import { db } from '$lib/server/prisma'; +import type { PageServerLoad } from './$types'; + +export const load = (async () => { + const contests = await db.contest.findMany(); + return { + contests: contests.map((contest) => { + return { id: contest.id, name: contest.name }; + }) + }; +}) satisfies PageServerLoad; diff --git a/web/src/routes/admin/contests/+page.svelte b/web/src/routes/admin/contests/+page.svelte new file mode 100644 index 0000000..cb51504 --- /dev/null +++ b/web/src/routes/admin/contests/+page.svelte @@ -0,0 +1,26 @@ + + + + Contests + + +

    Contests

    + +
    +
    + Create +
    +
    + +
    + {#each data.contests as contest} + {contest.name} + {/each} +
    diff --git a/web/src/routes/admin/contests/[contestId]/+page.server.ts b/web/src/routes/admin/contests/[contestId]/+page.server.ts new file mode 100644 index 0000000..3445ba7 --- /dev/null +++ b/web/src/routes/admin/contests/[contestId]/+page.server.ts @@ -0,0 +1,26 @@ +import { error, redirect } from '@sveltejs/kit'; +import type { PageServerLoad } from './$types'; +import { db } from '$lib/server/prisma'; + +export const load = (async ({ params }) => { + const contestId = parseInt(params.contestId); + if (isNaN(contestId)) { + throw error(400, 'Invalid request'); + } + const contest = await db.contest.findUnique({ + where: { id: contestId }, + include: { problems: true, teams: true } + }); + if (!contest) { + throw redirect(302, '/admin/contests'); + } + return { + name: contest.name, + problems: contest.problems.map((problem) => { + return { name: problem.friendlyName }; + }), + teams: contest.teams.map((team) => { + return { name: team.name }; + }) + }; +}) satisfies PageServerLoad; diff --git a/web/src/routes/admin/contests/[contestId]/+page.svelte b/web/src/routes/admin/contests/[contestId]/+page.svelte new file mode 100644 index 0000000..e7bf3b0 --- /dev/null +++ b/web/src/routes/admin/contests/[contestId]/+page.svelte @@ -0,0 +1,36 @@ + + + + {data.name} + + +

    {data.name}

    + +
    + +
    + +
    +
    +

    Teams

    +
    + {#each data.teams as team} +
    {team.name}
    + {/each} +
    +
    +
    +

    Problems

    +
    + {#each data.problems as problem} +
    {problem.name}
    + {/each} +
    +
    +
    diff --git a/web/src/routes/admin/contests/create/+page.server.ts b/web/src/routes/admin/contests/create/+page.server.ts new file mode 100644 index 0000000..93be169 --- /dev/null +++ b/web/src/routes/admin/contests/create/+page.server.ts @@ -0,0 +1,47 @@ +import { db } from '$lib/server/prisma'; +import type { Actions, PageServerLoad } from './$types'; + +export const load = (async () => { + const teams = await db.team.findMany(); + const problems = await db.problem.findMany(); + return { + teams: teams.map((row) => { + return { id: row.id, name: row.name }; + }), + problems: problems.map((row) => { + return { id: row.id, name: row.friendlyName }; + }) + }; +}) satisfies PageServerLoad; + +export const actions = { + create: async ({ request }) => { + const data = await request.formData(); + const name = data.get('name'); + const problems = (await db.problem.findMany()).filter((problem) => { + return data.get('problem_' + problem.id) !== null; + }); + const teams = (await db.team.findMany()).filter((team) => { + return data.get('team_' + team.id) !== null; + }); + if (!name) { + return { success: false }; + } + await db.contest.create({ + data: { + name: name.toString(), + teams: { + connect: teams.map((team) => { + return { id: team.id }; + }) + }, + problems: { + connect: problems.map((problem) => { + return { id: problem.id }; + }) + } + } + }); + return { success: true }; + } +} satisfies Actions; diff --git a/web/src/routes/admin/contests/create/+page.svelte b/web/src/routes/admin/contests/create/+page.svelte new file mode 100644 index 0000000..3fb99a7 --- /dev/null +++ b/web/src/routes/admin/contests/create/+page.svelte @@ -0,0 +1,115 @@ + + + + Create Contest + + +

    Create Contest

    + +Cancel + +{#if form && !form.success} +
    Invalid entry
    +{/if} + +
    +

    Name

    + + +
    +
    +

    Teams

    +
    +
    + + +
    +
    + {#each data.teams as team} +
    + + +
    + {/each} +
    +
    +

    Problems

    +
    +
    + + +
    +
    + {#each data.problems as problem} +
    + + +
    + {/each} +
    +
    +
    +
    + +
    +
    +