130 lines
3.4 KiB
Svelte
130 lines
3.4 KiB
Svelte
|
<script lang="ts" context="module">
|
||
|
export const prerender = false;
|
||
|
</script>
|
||
|
|
||
|
<script lang="ts">
|
||
|
import { goto } from '$app/navigation';
|
||
|
import { getContext, onMount } from 'svelte';
|
||
|
import { type LeaderboardResponse, QuestService } from '$lib/pb/all.pb';
|
||
|
import { withToken } from '$lib/pb/pbutil';
|
||
|
import Countdown from '$lib/components/Countdown.svelte';
|
||
|
import { auth } from '$lib/stores';
|
||
|
import ErrorModal from '$lib/components/ErrorModal.svelte';
|
||
|
|
||
|
const { open } = getContext('simple-modal');
|
||
|
|
||
|
let ranking: LeaderboardResponse = null;
|
||
|
|
||
|
let queried = false;
|
||
|
onMount(() => {
|
||
|
auth.subscribe((data) => {
|
||
|
if (queried) return;
|
||
|
if (!data.loggedIn()) return;
|
||
|
queried = true;
|
||
|
|
||
|
QuestService.Leaderboard({}, withToken(data.token))
|
||
|
.then((lr) => {
|
||
|
ranking = lr;
|
||
|
})
|
||
|
.catch((err) => {
|
||
|
open(ErrorModal, {
|
||
|
title: 'Could not fetch',
|
||
|
reason: err.message || 'Something went wrong',
|
||
|
btn: {
|
||
|
title: 'Go to dashboard',
|
||
|
do: () => {
|
||
|
goto('/dashboard');
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
</script>
|
||
|
|
||
|
<svelte:head>
|
||
|
<title>Questions | CodeQuest</title>
|
||
|
</svelte:head>
|
||
|
|
||
|
<div class="relative flex min-h-[calc(100vh-164px)] pb-8 mx-2">
|
||
|
<main class="container mx-auto pt-4 flex flex-col gap-4">
|
||
|
<div class="grid grid-cols-1 gap-4">
|
||
|
<div class="box h-24 border-2 border-sky-600 hover:bg-sky-50">
|
||
|
<span class="font-bold text-4xl text-sky-600">Leaderboard</span>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-3 xl:grid-cols-5">
|
||
|
<a class="box h-12 hover:bg-neutral-200 border-neutral-300" href="/dashboard">
|
||
|
<span class="txt text-neutral-600 flex items-center gap-1">
|
||
|
<!-- prettier-ignore -->
|
||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||
|
</svg>
|
||
|
Dashboard
|
||
|
</span>
|
||
|
</a>
|
||
|
|
||
|
<div class="box h-12 border-indigo-600 col-span-1 md:col-end-4 xl:col-end-6">
|
||
|
<span class="txt text-indigo-600">
|
||
|
{#if !$auth.info}
|
||
|
|
||
|
{:else if $auth.info?.active}
|
||
|
<Countdown end={String($auth.info.endTime)} />
|
||
|
{:else if new Date(String($auth.info.endTime)) < new Date()}
|
||
|
Contest Over
|
||
|
{:else}
|
||
|
Starting Soon
|
||
|
{/if}
|
||
|
</span>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="grid grid-cols-1 xl:grid-cols-2 gap-6">
|
||
|
{#if ranking}
|
||
|
{#each ranking.leaderboard as item, i}
|
||
|
<div class="ranking h-24 xl:col-span-2">
|
||
|
<div class="inline-flex items-end gap-2">
|
||
|
<span class="txt text-4xl">{i + 1}.</span>
|
||
|
<span class="txt text-2xl">{item.username}</span>
|
||
|
</div>
|
||
|
<div>
|
||
|
<span class="txt text-2xl">{item.points} points</span>
|
||
|
</div>
|
||
|
</div>
|
||
|
{/each}
|
||
|
{/if}
|
||
|
</div>
|
||
|
</main>
|
||
|
</div>
|
||
|
|
||
|
<style lang="postcss">
|
||
|
.box {
|
||
|
@apply flex items-center justify-center w-full rounded-md shadow-md border;
|
||
|
@apply transition;
|
||
|
}
|
||
|
|
||
|
.ranking {
|
||
|
@apply flex items-center justify-between w-full rounded-md shadow-md border;
|
||
|
@apply px-8;
|
||
|
@apply transition;
|
||
|
@apply text-gray-400 border-gray-400 hover:bg-sky-50;
|
||
|
}
|
||
|
|
||
|
.ranking:nth-child(1) {
|
||
|
@apply text-yellow-500 border-yellow-500 hover:bg-amber-50;
|
||
|
}
|
||
|
|
||
|
.ranking:nth-child(2) {
|
||
|
@apply text-zinc-700 border-zinc-700 hover:bg-zinc-50;
|
||
|
}
|
||
|
|
||
|
.ranking:nth-child(3) {
|
||
|
@apply text-amber-600 border-amber-600 hover:bg-amber-50;
|
||
|
}
|
||
|
|
||
|
.txt {
|
||
|
@apply font-bold tracking-wider uppercase;
|
||
|
}
|
||
|
</style>
|