105 lines
2.9 KiB
Svelte
105 lines
2.9 KiB
Svelte
|
<script lang="ts">
|
||
|
import { goto } from '$app/navigation';
|
||
|
import { getContext, onMount } from 'svelte';
|
||
|
import * as pb from '$lib/pb/all.pb';
|
||
|
import { withToken } from '$lib/pb/pbutil';
|
||
|
import Countdown from '$lib/components/Countdown.svelte';
|
||
|
import { auth } from '$lib/stores';
|
||
|
import QuestionListing from '$lib/components/QuestionListing.svelte';
|
||
|
import ErrorModal from '$lib/components/ErrorModal.svelte';
|
||
|
|
||
|
const { open } = getContext('simple-modal');
|
||
|
|
||
|
let questions: pb.Question[] = null;
|
||
|
|
||
|
let queried = false;
|
||
|
onMount(() => {
|
||
|
auth.subscribe((data) => {
|
||
|
if (queried) return;
|
||
|
if (!data.loggedIn()) return;
|
||
|
queried = true;
|
||
|
|
||
|
pb.QuestService.Questions({}, withToken(data.token))
|
||
|
.then((qs) => {
|
||
|
questions = qs.questions;
|
||
|
})
|
||
|
.catch((err) => {
|
||
|
questions = [];
|
||
|
open(ErrorModal, {
|
||
|
title: 'Could not fetch',
|
||
|
reason: err.message || 'Something went wrong',
|
||
|
btn: {
|
||
|
title: 'Go to dashboard',
|
||
|
do: () => {
|
||
|
goto('/dashboard');
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
</script>
|
||
|
|
||
|
<svelte:head>
|
||
|
<title>Puzzles | 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-indigo-700 hover:bg-indigo-50">
|
||
|
<span class="font-bold text-4xl text-indigo-700">Puzzles</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 $auth.info?.active}
|
||
|
{#each questions || [] as question}
|
||
|
<QuestionListing q={question} />
|
||
|
{/each}
|
||
|
{:else}
|
||
|
<dev class="box h-36 hover:bg-red-50 border-red-300 xl:col-span-2">
|
||
|
<span class="txt text-2xl text-red-600">The Contest is not Currently Active</span>
|
||
|
</dev>
|
||
|
{/if}
|
||
|
</div>
|
||
|
</main>
|
||
|
</div>
|
||
|
|
||
|
<style lang="postcss">
|
||
|
.box {
|
||
|
@apply flex items-center justify-center w-full rounded-md shadow-md border;
|
||
|
@apply cursor-pointer transition;
|
||
|
}
|
||
|
|
||
|
.txt {
|
||
|
@apply font-bold tracking-wider uppercase;
|
||
|
}
|
||
|
</style>
|