diff --git a/web/src/routes/admin/reviews/+page.server.ts b/web/src/routes/admin/reviews/+page.server.ts
index a32fcc9..47e3059 100644
--- a/web/src/routes/admin/reviews/+page.server.ts
+++ b/web/src/routes/admin/reviews/+page.server.ts
@@ -38,6 +38,15 @@ export const actions = {
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({
diff --git a/web/src/routes/admin/submissions/+page.server.ts b/web/src/routes/admin/submissions/+page.server.ts
new file mode 100644
index 0000000..a31b7a6
--- /dev/null
+++ b/web/src/routes/admin/submissions/+page.server.ts
@@ -0,0 +1,25 @@
+import { db } from '$lib/server/prisma';
+import type { PageServerLoad } from './$types';
+
+export const load = (async () => {
+ const submissions = await db.submission.findMany();
+ const problems = await db.problem.findMany();
+ const teams = await db.team.findMany();
+ return {
+ submissions: submissions.map((row) => {
+ return {
+ id: row.id,
+ createdAt: row.createdAt,
+ gradedAt: row.gradedAt,
+ message: row.message,
+ state: row.state,
+ problemName: problems.find((problem) => {
+ return problem.id == row.problemId;
+ })?.friendlyName,
+ teamName: teams.find((team) => {
+ return team.id == row.teamId;
+ })?.name
+ };
+ })
+ };
+}) satisfies PageServerLoad;
diff --git a/web/src/routes/admin/submissions/+page.svelte b/web/src/routes/admin/submissions/+page.svelte
new file mode 100644
index 0000000..b405ff1
--- /dev/null
+++ b/web/src/routes/admin/submissions/+page.svelte
@@ -0,0 +1,77 @@
+
+
+
+ Submissions
+
+
+
Submissions
+
+
Rows are color coded: Red - Incorrect, Green - Correct, Yellow - In Review
+
+
+
+
+ Team |
+ Problem |
+ Submit Time |
+ Graded Time |
+ Message |
+
+
+
+ {#each data.submissions as submission}
+ {
+ goto('/admin/submissions/' + submission.id.toString());
+ }}
+ class={(submission.state == SubmissionState.InReview
+ ? 'table-warning'
+ : submission.state == SubmissionState.Correct
+ ? 'table-success'
+ : submission.state == SubmissionState.Incorrect
+ ? 'table-danger'
+ : '') + ' submission-row'}
+ >
+
+ {#if submission.teamName}
+ {submission.teamName}
+ {/if}
+ |
+
+ {#if submission.problemName}
+ {submission.problemName}
+ {/if}
+ |
+ {submission.createdAt.toLocaleDateString() +
+ ' ' +
+ submission.createdAt.toLocaleTimeString()} |
+
+ {#if submission.gradedAt}
+ {submission.gradedAt.toLocaleDateString() +
+ ' ' +
+ submission.gradedAt.toLocaleTimeString()}
+ {/if}
+ |
+ {submission.message ? submission.message : ''} |
+
+ {/each}
+
+
+
+
diff --git a/web/src/routes/admin/submissions/[submissionId]/+page.server.ts b/web/src/routes/admin/submissions/[submissionId]/+page.server.ts
new file mode 100644
index 0000000..871c6ac
--- /dev/null
+++ b/web/src/routes/admin/submissions/[submissionId]/+page.server.ts
@@ -0,0 +1,44 @@
+import { error, redirect } from '@sveltejs/kit';
+import type { PageServerLoad } from './$types';
+import { db } from '$lib/server/prisma';
+import Diff from 'diff';
+import { SubmissionState } from '@prisma/client';
+
+export const load = (async ({ params }) => {
+ const submissionId = parseInt(params.submissionId);
+ if (isNaN(submissionId)) {
+ throw error(400, 'Invalid submission');
+ }
+ const submission = await db.submission.findUnique({ where: { id: submissionId } });
+ if (!submission) {
+ throw redirect(302, '/admin/submissions');
+ }
+ const team = await db.team.findUnique({ where: { id: submission.teamId } });
+ if (!team) {
+ throw error(500, 'Invalid team');
+ }
+ const problem = await db.problem.findUnique({ where: { id: submission.problemId } });
+ 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,
+ teamName: team.name,
+ problemName: problem.friendlyName,
+ submitTime: submission.createdAt,
+ gradedTime: submission.gradedAt,
+ message: submission.message,
+ diff: diff
+ };
+}) satisfies PageServerLoad;
diff --git a/web/src/routes/admin/submissions/[submissionId]/+page.svelte b/web/src/routes/admin/submissions/[submissionId]/+page.svelte
new file mode 100644
index 0000000..c149cd0
--- /dev/null
+++ b/web/src/routes/admin/submissions/[submissionId]/+page.svelte
@@ -0,0 +1,83 @@
+
+
+
+ Submission
+
+
+
Submission
+
+
All Submissions
+
+
+
+
+ Team |
+ Problem |
+ Submit Time |
+ Graded Time |
+ Message |
+
+
+
+
+
+ {#if data.teamName}
+ {data.teamName}
+ {/if}
+ |
+
+ {#if data.problemName}
+ {data.problemName}
+ {/if}
+ |
+ {data.submitTime.toLocaleDateString() + ' ' + data.submitTime.toLocaleTimeString()} |
+
+ {#if data.gradedTime}
+ {data.gradedTime.toLocaleDateString() + ' ' + data.gradedTime.toLocaleTimeString()}
+ {/if}
+ |
+ {data.message ? data.message : ''} |
+
+
+
+
+{#if data.state == SubmissionState.InReview}
+
+{:else if data.state == SubmissionState.Incorrect}
+
Diff
+
+{/if}