[web] Implement public scoreboard with updating

This commit is contained in:
orosmatthew 2024-02-26 19:52:47 -05:00
parent a4efcdd6e9
commit 1c78b90643

View File

@ -2,7 +2,103 @@
import { page } from '$app/stores'; import { page } from '$app/stores';
import type { PageData } from './$types'; import type { PageData } from './$types';
import { contestId } from '../stores'; import { contestId } from '../stores';
import { onDestroy, onMount } from 'svelte';
import { invalidateAll } from '$app/navigation';
$contestId = parseInt($page.params.contestId); $contestId = parseInt($page.params.contestId);
let data: PageData; export let data: PageData;
let updateInterval: ReturnType<typeof setInterval>;
let updating = false;
onMount(() => {
updateInterval = setInterval(async () => {
updating = true;
await invalidateAll();
updating = false;
}, 10000);
});
onDestroy(() => {
clearInterval(updateInterval);
});
</script> </script>
<h2 style="text-align:center">{data.selected.name}</h2>
<div class="row">
<div class="text-end" />
</div>
<div class="text-end mb-1">
{#if updating}
<div class="spinner-border spinner-border-sm text-secondary" />
{/if}
<strong>Last Updated: </strong>{data.timestamp.toLocaleTimeString()}
</div>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Place</th>
<th>Team Name</th>
<th>Solves</th>
<th>Time</th>
{#each data.selected.problems as problem}
<th>{problem.friendlyName}</th>
{/each}
</tr>
</thead>
<tbody>
{#each data.selected.teams as team, i}
<tr>
<td style="text-align:center; font-size:24px;"><strong>{i + 1}</strong></td>
<td style="font-size:18px">{team.name}</td>
<td style="font-size:18px">{team.solves}</td>
<td style="font-size:18px">{team.time.toFixed(0)}</td>
{#each data.selected.problems as problem}
<td>
<div class="row">
<div class="col-3">
{#if team.problems.find((p) => {
return p.id === problem.id;
})?.graphic !== null}
<img
src={team.problems.find((p) => {
return p.id === problem.id;
})?.graphic === 'correct'
? '/correct.png'
: '/incorrect.png'}
alt="check or X"
width="30px"
/>
{/if}
</div>
<div class="col-9">
{#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'}<br />{#if team.problems.find((p) => {
return p.id === problem.id;
})?.min}<span style="color:rgb(102,102,102)"
>{team.problems
.find((p) => {
return p.id === problem.id;
})
?.min?.toFixed(0)} min</span
>{/if}
{/if}
</div>
</div>
</td>
{/each}
</tr>
{/each}
</tbody>
</table>