Merge feature/scoreboard-freeze
This commit is contained in:
parent
6d98f56385
commit
aa1be3acb7
@ -101,4 +101,5 @@ model Contest {
|
|||||||
activeTeams ActiveTeam[]
|
activeTeams ActiveTeam[]
|
||||||
submissions Submission[]
|
submissions Submission[]
|
||||||
startTime DateTime?
|
startTime DateTime?
|
||||||
|
freezeTime DateTime?
|
||||||
}
|
}
|
||||||
|
@ -109,5 +109,31 @@ export const actions = {
|
|||||||
}
|
}
|
||||||
await createRepos(contestId);
|
await createRepos(contestId);
|
||||||
return { success: true };
|
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;
|
} satisfies Actions;
|
||||||
|
@ -3,11 +3,18 @@
|
|||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import ConfirmModal from '$lib/ConfirmModal.svelte';
|
import ConfirmModal from '$lib/ConfirmModal.svelte';
|
||||||
import FormAlert from '$lib/FormAlert.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 data: PageData;
|
||||||
|
export let form: Actions;
|
||||||
|
|
||||||
|
$: if (form) {
|
||||||
|
freezeModal.hide();
|
||||||
|
}
|
||||||
|
|
||||||
let confirmModal: ConfirmModal;
|
let confirmModal: ConfirmModal;
|
||||||
|
let freezeModal: Modal;
|
||||||
|
|
||||||
function enhanceConfirm(form: HTMLFormElement, text: string) {
|
function enhanceConfirm(form: HTMLFormElement, text: string) {
|
||||||
enhance(form, async ({ cancel }) => {
|
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>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@ -27,6 +40,31 @@
|
|||||||
|
|
||||||
<ConfirmModal bind:this={confirmModal} />
|
<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>
|
<h1 style="text-align:center" class="mb-4"><i class="bi bi-flag"></i> Contest - {data.name}</h1>
|
||||||
|
|
||||||
<FormAlert />
|
<FormAlert />
|
||||||
@ -40,6 +78,13 @@
|
|||||||
<a href="/admin/contests" class="btn btn-outline-primary">All Contests</a>
|
<a href="/admin/contests" class="btn btn-outline-primary">All Contests</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 text-end">
|
<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}
|
{#if data.activeTeams === 0}
|
||||||
<form
|
<form
|
||||||
method="POST"
|
method="POST"
|
||||||
|
@ -8,9 +8,24 @@ export const load = (async ({ params }) => {
|
|||||||
throw redirect(302, '/public/scoreboard');
|
throw redirect(302, '/public/scoreboard');
|
||||||
}
|
}
|
||||||
const timestamp = new Date();
|
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({
|
const contest = await db.contest.findUnique({
|
||||||
where: { id: contestId },
|
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) {
|
if (contest === null) {
|
||||||
throw redirect(302, '/public/scoreboard');
|
throw redirect(302, '/public/scoreboard');
|
||||||
|
Loading…
Reference in New Issue
Block a user