Merge feature/scoreboard-freeze

This commit is contained in:
orosmatthew 2024-03-13 18:35:30 -04:00
parent 6d98f56385
commit aa1be3acb7
4 changed files with 89 additions and 2 deletions

View File

@ -101,4 +101,5 @@ model Contest {
activeTeams ActiveTeam[]
submissions Submission[]
startTime DateTime?
freezeTime DateTime?
}

View File

@ -109,5 +109,31 @@ export const actions = {
}
await createRepos(contestId);
return { success: true };
},
'freeze-time': async ({ params, request }) => {
if (!params.contestId) {
return { success: false, message: 'No contest Id specified' };
}
const contestId = parseInt(params.contestId);
if (isNaN(contestId)) {
return { success: false, message: 'Invalid contest Id' };
}
const form = await request.formData();
const formFreezeTime = form.get('freezeTime');
if (formFreezeTime === null) {
return { success: false, message: 'Invalid input' };
}
const freezeTime = new Date(formFreezeTime.toString());
const contest = await db.contest.findUnique({ where: { id: contestId } });
if (contest === null) {
return { success: false, message: 'Invalid contest' };
}
try {
await db.contest.update({ where: { id: contestId }, data: { freezeTime } });
} catch (e) {
console.error(`Database error: ${e}`);
return { success: false, message: `Database error: ${e}` };
}
return { success: true };
}
} satisfies Actions;

View File

@ -3,11 +3,18 @@
import { page } from '$app/stores';
import ConfirmModal from '$lib/ConfirmModal.svelte';
import FormAlert from '$lib/FormAlert.svelte';
import type { PageData } from './$types';
import Modal from '$lib/Modal.svelte';
import type { Actions, PageData } from './$types';
export let data: PageData;
export let form: Actions;
$: if (form) {
freezeModal.hide();
}
let confirmModal: ConfirmModal;
let freezeModal: Modal;
function enhanceConfirm(form: HTMLFormElement, text: string) {
enhance(form, async ({ cancel }) => {
@ -19,6 +26,12 @@
};
});
}
let freezeTimeInputLocal: string | undefined;
let freezeTimeInput: string | null = null;
$: if (freezeTimeInputLocal !== undefined) {
freezeTimeInput = new Date(freezeTimeInputLocal).toISOString();
}
</script>
<svelte:head>
@ -27,6 +40,31 @@
<ConfirmModal bind:this={confirmModal} />
<Modal title="Freeze Time" bind:this={freezeModal}>
<form action="?/freeze-time" method="POST" use:enhance>
<div class="modal-body">
<label class="form-label" for="freezeTimeInput">Freeze At</label>
<input
bind:value={freezeTimeInputLocal}
id="freezeTimeInput"
class="form-control"
type="datetime-local"
/>
<input type="hidden" name="freezeTime" value={freezeTimeInput} />
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-outline-secondary"
on:click={() => {
freezeModal.hide();
}}>Cancel</button
>
<button type="submit" class="btn btn-success">Set</button>
</div>
</form>
</Modal>
<h1 style="text-align:center" class="mb-4"><i class="bi bi-flag"></i> Contest - {data.name}</h1>
<FormAlert />
@ -40,6 +78,13 @@
<a href="/admin/contests" class="btn btn-outline-primary">All Contests</a>
</div>
<div class="col-6 text-end">
<button
type="button"
class="btn btn-outline-info"
on:click={() => {
freezeModal.show();
}}>Set Freeze Time</button
>
{#if data.activeTeams === 0}
<form
method="POST"

View File

@ -8,9 +8,24 @@ export const load = (async ({ params }) => {
throw redirect(302, '/public/scoreboard');
}
const timestamp = new Date();
const contestQuery = await db.contest.findUnique({ where: { id: contestId } });
if (contestQuery === null) {
throw redirect(302, '/public/scoreboard');
}
const contest = await db.contest.findUnique({
where: { id: contestId },
include: { problems: true, teams: { include: { submissions: true } } }
include: {
problems: true,
teams: {
include: {
submissions:
contestQuery.freezeTime === null
? true
: { where: { createdAt: { lt: contestQuery.freezeTime } } }
}
}
}
});
if (contest === null) {
throw redirect(302, '/public/scoreboard');