From 544f5390cd768a6a86334d002b6f73318af34730 Mon Sep 17 00:00:00 2001 From: orosmatthew Date: Mon, 8 May 2023 21:21:53 -0400 Subject: [PATCH] [web] Working scoreboard --- web/prisma/ERD.svg | 2 +- web/prisma/schema.prisma | 13 ++- web/src/routes/admin/+layout.svelte | 2 +- web/src/routes/admin/contests/+page.server.ts | 4 +- web/src/routes/admin/contests/+page.svelte | 4 +- .../contests/[contestId]/+page.server.ts | 2 + .../admin/diff/[submissionId]/+page.server.ts | 12 +- .../admin/diff/[submissionId]/+page.svelte | 26 +++-- web/src/routes/admin/reviews/+page.server.ts | 43 +------ web/src/routes/admin/reviews/+page.svelte | 63 ----------- .../routes/admin/scoreboard/+page.server.ts | 89 +++++++++++++-- web/src/routes/admin/scoreboard/+page.svelte | 105 +++++++++++++----- .../[submissionId]/+page.server.ts | 28 ++--- .../submissions/[submissionId]/+page.svelte | 51 +++++++-- web/src/routes/api/submission/+server.ts | 4 +- web/static/correct.png | Bin 0 -> 11484 bytes web/static/incorrect.png | Bin 0 -> 24515 bytes 17 files changed, 247 insertions(+), 201 deletions(-) create mode 100644 web/static/correct.png create mode 100644 web/static/incorrect.png diff --git a/web/prisma/ERD.svg b/web/prisma/ERD.svg index 060ed3f..4196b62 100644 --- a/web/prisma/ERD.svg +++ b/web/prisma/ERD.svg @@ -1 +1 @@ -SubmissionStateQueuedQueuedInReviewInReviewCorrectCorrectIncorrectIncorrectUserIntid🗝️StringusernameStringpasswordSessionStringtoken🗝️DateTimecreatedAtSubmissionIntid🗝️DateTimecreatedAtDateTimegradedAtSubmissionStatestateStringactualOutputStringcommitHashStringdiffStringmessageProblemIntid🗝️StringfriendlyNameStringpascalNameStringsampleInputStringsampleOutputStringrealInputStringrealOutputTeamIntid🗝️StringnameStringpasswordActiveTeamIntid🗝️StringsessionTokenDateTimesessionCreatedAtContestIntid🗝️Stringnamesessionsuserenum:stateteamproblemcontestsubmissionscontestsSubmissioncontestsactiveTeamteamcontestteamsproblemsactiveTeamssubmissions \ No newline at end of file +SubmissionStateQueuedQueuedInReviewInReviewCorrectCorrectIncorrectIncorrectUserIntid🗝️StringusernameStringpasswordSessionStringtoken🗝️DateTimecreatedAtSubmissionIntid🗝️DateTimecreatedAtDateTimegradedAtSubmissionStatestateStringactualOutputStringcommitHashStringdiffStringmessageProblemIntid🗝️StringfriendlyNameStringpascalNameStringsampleInputStringsampleOutputStringrealInputStringrealOutputTeamIntid🗝️StringnameStringpasswordActiveTeamIntid🗝️StringsessionTokenDateTimesessionCreatedAtContestIntid🗝️StringnameDateTimestartTimesessionsuserenum:stateteamproblemcontestsubmissionscontestssubmissionscontestsactiveTeamteamcontestteamsproblemsactiveTeamssubmissions \ No newline at end of file diff --git a/web/prisma/schema.prisma b/web/prisma/schema.prisma index bfe14dd..67ea5bb 100644 --- a/web/prisma/schema.prisma +++ b/web/prisma/schema.prisma @@ -62,12 +62,12 @@ model Problem { } model Team { - id Int @id @default(autoincrement()) - name String @unique - Submission Submission[] - contests Contest[] @relation("TeamContestRelation") - password String - activeTeam ActiveTeam? + id Int @id @default(autoincrement()) + name String @unique + submissions Submission[] + contests Contest[] @relation("TeamContestRelation") + password String + activeTeam ActiveTeam? } model ActiveTeam { @@ -87,4 +87,5 @@ model Contest { problems Problem[] @relation("ProblemContestRelation") activeTeams ActiveTeam[] submissions Submission[] + startTime DateTime? } diff --git a/web/src/routes/admin/+layout.svelte b/web/src/routes/admin/+layout.svelte index d652b4b..4dec39b 100644 --- a/web/src/routes/admin/+layout.svelte +++ b/web/src/routes/admin/+layout.svelte @@ -4,7 +4,7 @@
  • Reviews
  • Submissions
  • Problems
  • -
  • Scoreboard
  • +
  • Scoreboards
  • Teams
  • Contests
  • Logout
  • diff --git a/web/src/routes/admin/contests/+page.server.ts b/web/src/routes/admin/contests/+page.server.ts index 9270b13..fe18bbf 100644 --- a/web/src/routes/admin/contests/+page.server.ts +++ b/web/src/routes/admin/contests/+page.server.ts @@ -2,10 +2,10 @@ import { db } from '$lib/server/prisma'; import type { PageServerLoad } from './$types'; export const load = (async () => { - const contests = await db.contest.findMany(); + const contests = await db.contest.findMany({ include: { activeTeams: true } }); return { contests: contests.map((contest) => { - return { id: contest.id, name: contest.name }; + return { id: contest.id, name: contest.name, activeTeams: contest.activeTeams.length }; }) }; }) satisfies PageServerLoad; diff --git a/web/src/routes/admin/contests/+page.svelte b/web/src/routes/admin/contests/+page.svelte index cb51504..8896a44 100644 --- a/web/src/routes/admin/contests/+page.svelte +++ b/web/src/routes/admin/contests/+page.svelte @@ -20,7 +20,9 @@ {#each data.contests as contest} {contest.name}{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 index 26e4f85..329635e 100644 --- a/web/src/routes/admin/contests/[contestId]/+page.server.ts +++ b/web/src/routes/admin/contests/[contestId]/+page.server.ts @@ -68,6 +68,8 @@ export const actions = { await db.activeTeam.create({ data: { teamId: team.id, contestId: contest.id } }); }); + await db.contest.update({ where: { id: contestId }, data: { startTime: new Date() } }); + return { success: true }; }, stop: async ({ params }) => { diff --git a/web/src/routes/admin/diff/[submissionId]/+page.server.ts b/web/src/routes/admin/diff/[submissionId]/+page.server.ts index fda6c42..f514f08 100644 --- a/web/src/routes/admin/diff/[submissionId]/+page.server.ts +++ b/web/src/routes/admin/diff/[submissionId]/+page.server.ts @@ -1,5 +1,4 @@ import type { Actions, PageServerLoad } from './$types'; -import * as Diff from 'diff'; import { error, redirect } from '@sveltejs/kit'; import { db } from '$lib/server/prisma'; import { SubmissionState } from '@prisma/client'; @@ -17,17 +16,8 @@ export const load = (async ({ params }) => { if (!problem) { throw error(500, 'Invalid problem'); } - let diff: string | undefined; - if (submission.actualOutput) { - diff = Diff.createTwoFilesPatch( - 'expected', - 'actual', - problem.realOutput, - submission.actualOutput - ); - } - return { diff: diff }; + return { diff: submission.diff, submissionId: submission.id }; }) satisfies PageServerLoad; export const actions = { diff --git a/web/src/routes/admin/diff/[submissionId]/+page.svelte b/web/src/routes/admin/diff/[submissionId]/+page.svelte index 1049cb1..74c8f0d 100644 --- a/web/src/routes/admin/diff/[submissionId]/+page.svelte +++ b/web/src/routes/admin/diff/[submissionId]/+page.svelte @@ -28,15 +28,17 @@ } onMount(() => { - const diff2htmlUi = new Diff2HtmlUI(document.getElementById('diff')!, data.diff, { - drawFileList: false, - matching: 'lines', - diffStyle: 'char', - outputFormat: 'side-by-side', - highlight: false, - fileContentToggle: false - }); - diff2htmlUi.draw(); + if (data.diff) { + const diff2htmlUi = new Diff2HtmlUI(document.getElementById('diff')!, data.diff, { + drawFileList: false, + matching: 'lines', + diffStyle: 'char', + outputFormat: 'side-by-side', + highlight: false, + fileContentToggle: false + }); + diff2htmlUi.draw(); + } incorrectBtn.addEventListener('change', () => { submitBtn.disabled = false; @@ -61,7 +63,11 @@
    Success!
    {/if} -All Reviews +
    + All Reviews + Go to Submission +
    +
    diff --git a/web/src/routes/admin/reviews/+page.server.ts b/web/src/routes/admin/reviews/+page.server.ts index 9487e6d..a328a89 100644 --- a/web/src/routes/admin/reviews/+page.server.ts +++ b/web/src/routes/admin/reviews/+page.server.ts @@ -1,6 +1,6 @@ import { db } from '$lib/server/prisma'; import { SubmissionState } from '@prisma/client'; -import type { Actions, PageServerLoad } from './$types'; +import type {PageServerLoad } from './$types'; export const load = (async () => { const submissions = await db.submission.findMany({ where: { state: SubmissionState.InReview } }); @@ -19,44 +19,3 @@ export const load = (async () => { }; }) satisfies PageServerLoad; -// export const actions = { -// submission: async ({ request }) => { -// const data = await request.formData(); -// const teamId = data.get('teamId'); -// const problemId = data.get('problemId'); -// const actual = data.get('actual'); -// if (!teamId || !problemId || !actual) { -// return { success: false }; -// } -// const problemIdInt = parseInt(problemId.toString()); -// const teamIdInt = parseInt(teamId.toString()); -// if (isNaN(problemIdInt) || isNaN(teamIdInt)) { -// return { success: false }; -// } -// const problem = await db.problem.findUnique({ where: { id: problemIdInt } }); -// if (!problem) { -// return { success: false }; -// } -// if (problem.realOutput === actual.toString()) { -// await db.submission.create({ -// data: { -// state: SubmissionState.Correct, -// actualOutput: actual.toString(), -// teamId: teamIdInt, -// problemId: problemIdInt, -// gradedAt: new Date() -// } -// }); -// return { success: true }; -// } -// await db.submission.create({ -// data: { -// state: SubmissionState.InReview, -// actualOutput: actual.toString(), -// teamId: teamIdInt, -// problemId: problemIdInt -// } -// }); -// return { success: true }; -// } -// } satisfies Actions; diff --git a/web/src/routes/admin/reviews/+page.svelte b/web/src/routes/admin/reviews/+page.svelte index bfea196..67ed3d3 100644 --- a/web/src/routes/admin/reviews/+page.svelte +++ b/web/src/routes/admin/reviews/+page.svelte @@ -20,66 +20,3 @@ > {/each} - - diff --git a/web/src/routes/admin/scoreboard/+page.server.ts b/web/src/routes/admin/scoreboard/+page.server.ts index f6a555c..c4fd0bb 100644 --- a/web/src/routes/admin/scoreboard/+page.server.ts +++ b/web/src/routes/admin/scoreboard/+page.server.ts @@ -3,15 +3,88 @@ import type { PageServerLoad } from './$types'; export const load = (async () => { const timestamp = new Date(); - const problems = await db.problem.findMany(); - const teams = await db.team.findMany(); - return { + const contests = await db.contest.findMany({ + include: { problems: true, teams: { include: { submissions: true } } } + }); + const data = { timestamp: timestamp, - problems: problems.map((row) => { - return { friendlyName: row.friendlyName }; - }), - teams: teams.map((row) => { - return { name: row.name }; + contests: contests.map((contest) => { + return { + name: contest.name, + problems: contest.problems.map((problem) => { + return { id: problem.id, friendlyName: problem.friendlyName }; + }), + teams: contest.teams.map((team) => { + return { + name: team.name, + solves: team.submissions.filter((submission) => { + return submission.contestId === contest.id && submission.state === 'Correct'; + }).length, + time: (() => { + const correctSubmissions = team.submissions.filter((submission) => { + return submission.contestId === contest.id && submission.state === 'Correct'; + }); + const penaltyTime = + team.submissions.filter((submission) => { + return ( + submission.contestId === contest.id && + submission.state === 'Incorrect' && + correctSubmissions.find((correct) => { + return correct.problemId === submission.problemId; + }) + ); + }).length * 10; + let time = penaltyTime; + correctSubmissions.forEach((correctSubmission) => { + const gradedAt = correctSubmission.gradedAt!.valueOf(); + const min = (gradedAt - contest.startTime!.valueOf()) / 60000; + time += min; + }); + return time; + })(), + problems: contest.problems.map((problem) => { + return { + id: problem.id, + attempts: team.submissions.filter((submission) => { + return ( + submission.contestId === contest.id && + submission.problemId === problem.id && + (submission.state === 'Correct' || submission.state === 'Incorrect') + ); + }).length, + graphic: team.submissions.find((submission) => { + return ( + submission.contestId === contest.id && + submission.problemId === problem.id && + (submission.state === 'Correct' || submission.state === 'Incorrect') + ); + }) + ? team.submissions.find((submission) => { + return submission.problemId === problem.id && submission.state === 'Correct'; + }) + ? 'correct' + : 'incorrect' + : null, + min: (() => { + const correctSubmission = team.submissions.find((submission) => { + return ( + submission.contestId === contest.id && + submission.problemId === problem.id && + submission.state === 'Correct' + ); + }); + if (correctSubmission) { + const gradedAt = correctSubmission.gradedAt!.valueOf(); + return (gradedAt - contest.startTime!.valueOf()) / 60000; + } + return undefined; + })() + }; + }) + }; + }) + }; }) }; + return data; }) satisfies PageServerLoad; diff --git a/web/src/routes/admin/scoreboard/+page.svelte b/web/src/routes/admin/scoreboard/+page.svelte index 62efbd3..ecc9b02 100644 --- a/web/src/routes/admin/scoreboard/+page.svelte +++ b/web/src/routes/admin/scoreboard/+page.svelte @@ -25,38 +25,85 @@ Admin Scoreboard -

    Admin Scoreboard

    +

    Admin Scoreboards

    -
    -
    - {#if updating} -
    - {/if} - Last Updated: {data.timestamp.toLocaleTimeString()} -
    +
    + {#if updating} +
    + {/if} + Last Updated: {data.timestamp.toLocaleTimeString()}
    - - - - - {#each data.problems as problem} - - {/each} - - - - - - {#each data.teams as team} +{#each data.contests as contest} +

    {contest.name}

    +
    +
    +
    + +
    Team Name{problem.friendlyName}Total CorrectTotal Points
    + - - {#each data.problems as _} - + + + + + {#each contest.problems as problem} + {/each} - - - {/each} - -
    {team.name}-/-PlaceTeam NameSolvesTime{problem.friendlyName}00
    + + + {#each contest.teams as team, i} + + {i + 1} + {team.name} + {team.solves} + {team.time.toFixed(0)} + {#each contest.problems as problem} + +
    +
    + {#if team.problems.find((p) => { + return p.id === problem.id; + })?.graphic !== null} + { + return p.id === problem.id; + })?.graphic === 'correct' + ? '/correct.png' + : '/incorrect.png'} + alt="check or X" + width="30px" + /> + {/if} +
    +
    + {#if team.problems.find((p) => { + return p.id === problem.id; + })?.attempts !== 0} + {team.problems.find((p) => { + return p.id === problem.id; + })?.attempts} + {team.problems.find((p) => { + return p.id === problem.id; + })?.attempts === 1 + ? 'Attempt' + : 'Attempts'}
    {#if team.problems.find((p) => { + return p.id === problem.id; + })?.min}{team.problems + .find((p) => { + return p.id === problem.id; + }) + ?.min?.toFixed(0)} min{/if} + {/if} +
    +
    + + {/each} + + {/each} + + +{/each} diff --git a/web/src/routes/admin/submissions/[submissionId]/+page.server.ts b/web/src/routes/admin/submissions/[submissionId]/+page.server.ts index 98b5202..4a86ec2 100644 --- a/web/src/routes/admin/submissions/[submissionId]/+page.server.ts +++ b/web/src/routes/admin/submissions/[submissionId]/+page.server.ts @@ -1,8 +1,6 @@ import { error, redirect } from '@sveltejs/kit'; -import type { PageServerLoad } from './$types'; +import type { Actions, PageServerLoad } from './$types'; import { db } from '$lib/server/prisma'; -import * as Diff from 'diff'; -import { SubmissionState } from '@prisma/client'; export const load = (async ({ params }) => { const submissionId = parseInt(params.submissionId); @@ -21,16 +19,6 @@ export const load = (async ({ params }) => { if (!problem) { throw error(500, 'Invalid problem'); } - let diff: string | null = null; - if (submission.state == SubmissionState.Incorrect) { - diff = Diff.createTwoFilesPatch( - 'expected', - 'actual', - problem.realOutput, - submission.actualOutput! - ); - } - return { id: submission.id, state: submission.state, @@ -39,6 +27,18 @@ export const load = (async ({ params }) => { submitTime: submission.createdAt, gradedTime: submission.gradedAt, message: submission.message, - diff: diff + diff: submission.diff }; }) satisfies PageServerLoad; + +export const actions = { + delete: async ({ params }) => { + const submissionId = parseInt(params.submissionId); + try { + await db.submission.delete({ where: { id: submissionId } }); + } catch { + return { success: false }; + } + throw redirect(302, '/admin/submissions'); + } +} satisfies Actions; diff --git a/web/src/routes/admin/submissions/[submissionId]/+page.svelte b/web/src/routes/admin/submissions/[submissionId]/+page.svelte index 4c39039..d009239 100644 --- a/web/src/routes/admin/submissions/[submissionId]/+page.svelte +++ b/web/src/routes/admin/submissions/[submissionId]/+page.svelte @@ -1,22 +1,27 @@ @@ -27,7 +32,31 @@

    Submission

    -All Submissions +{#if form && !form.success} +
    Error
    +{/if} + +
    + +
    + { + if (!confirm('Are you sure?')) { + cancel(); + } + return async ({ update }) => { + update(); + }; + }} + > + + +
    +
    diff --git a/web/src/routes/api/submission/+server.ts b/web/src/routes/api/submission/+server.ts index bb455e5..d52053c 100644 --- a/web/src/routes/api/submission/+server.ts +++ b/web/src/routes/api/submission/+server.ts @@ -64,8 +64,8 @@ export const POST = (async ({ request }) => { const diff = Diff.createTwoFilesPatch( 'expected', 'actual', - data.data.output, - submission.actualOutput! + submission.problem.realOutput, + data.data.output ); await db.submission.update({ where: { id: data.data.submissionId }, diff --git a/web/static/correct.png b/web/static/correct.png new file mode 100644 index 0000000000000000000000000000000000000000..02bea8a668c8ae6246108148c25904c671f3011f GIT binary patch literal 11484 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 TPf6*OkqoCO3zVsrGXL~Hz0X)g literal 0 HcmV?d00001 diff --git a/web/static/incorrect.png b/web/static/incorrect.png new file mode 100644 index 0000000000000000000000000000000000000000..67aa69ee1c5e9fecb319905ecf8d473e8082dbb5 GIT binary patch literal 24515 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