feat: daily puzzle #11
4 changed files with 92 additions and 13 deletions
59
src/routes/dashboard/+page.server.ts
Normal file
59
src/routes/dashboard/+page.server.ts
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import { API_URL } from '$env/static/private';
|
||||||
|
|
||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
|
import type { Chapter } from '$lib/types';
|
||||||
|
|
||||||
|
export const load = (async ({ parent, fetch, cookies }) => {
|
||||||
|
await parent();
|
||||||
|
|
||||||
|
const session = cookies.get('session');
|
||||||
|
|
||||||
|
let res = await fetch(`${API_URL}/chapters`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${session}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
return {
|
||||||
|
daily: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const chapters = (await res.json()) as Chapter[];
|
||||||
|
|
||||||
|
const lastChapter = chapters.filter((chapter) => chapter.show).pop();
|
||||||
|
|
||||||
|
if (!lastChapter) {
|
||||||
|
return {
|
||||||
|
daily: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
res = await fetch(`${API_URL}/chapter/${lastChapter.id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${session}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
return {
|
||||||
|
daily: {
|
||||||
|
chapter: lastChapter,
|
||||||
|
puzzle: null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const chapter = (await res.json()) as Chapter;
|
||||||
|
|
||||||
|
const lastPuzzle = chapter.puzzles.filter((puzzle) => puzzle.show).pop();
|
||||||
|
|
||||||
|
return {
|
||||||
|
daily: {
|
||||||
|
chapter: lastChapter,
|
||||||
|
puzzle: lastPuzzle
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}) satisfies PageServerLoad;
|
|
@ -1,27 +1,51 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from '$app/stores';
|
import type { PageData } from './$types';
|
||||||
import Card from '$lib/components/Card.svelte';
|
|
||||||
|
|
||||||
export let data;
|
import Card from '$lib/components/Card.svelte';
|
||||||
|
import Button from '$lib/components/ui/Button.svelte';
|
||||||
|
|
||||||
|
export let data: PageData;
|
||||||
|
|
||||||
$: user = data.user;
|
$: user = data.user;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="w-full flex-col space-y-4">
|
<section class="flex w-full flex-col gap-4">
|
||||||
|
{#if data.daily && data.daily.puzzle}
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-between gap-4 rounded-lg border-2 border-brand/40 bg-primary-700 px-4 py-2"
|
||||||
|
>
|
||||||
|
<div class="flex w-full flex-col justify-between md:flex-row md:items-center md:gap-4">
|
||||||
|
<span class="text-lg font-semibold">{data.daily.chapter.name}</span>
|
||||||
|
<span class="text-highlight-secondary">
|
||||||
|
{data.daily.puzzle.name} ({data.daily.puzzle.score ?? '?'}/{data.daily.puzzle.scoreMax})
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<Button
|
||||||
|
variant="brand"
|
||||||
|
href="/dashboard/chapters/{data.daily.chapter.id}/puzzle/{data.daily.puzzle.id}"
|
||||||
|
>
|
||||||
|
<span class="text-lg font-semibold">
|
||||||
|
{data.daily.puzzle.score ? 'Voir' : 'Jouer'}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<header>
|
<header>
|
||||||
<h1 class="text-xl font-semibold">Tableau de bord</h1>
|
<h1 class="text-xl font-semibold">Tableau de bord</h1>
|
||||||
<p class="text-highlight-secondary">Ceci est la page d'accueil du dashboard</p>
|
<p class="text-highlight-secondary">Ceci est la page d'accueil du dashboard</p>
|
||||||
</header>
|
</header>
|
||||||
<main class="flex-col space-y-4">
|
<main class="flex flex-col gap-4">
|
||||||
<div
|
<div
|
||||||
class="w-full flex-col justify-between space-x-0 space-y-4 md:flex md:flex-row md:space-x-6 md:space-y-0"
|
class="flex w-full flex-col justify-between gap-4 space-x-0 md:flex md:flex-row md:space-x-6 md:space-y-0"
|
||||||
>
|
>
|
||||||
<Card title="Puzzles résolus" data={user?.completions ?? 0} />
|
<Card title="Puzzles résolus" data={user?.completions ?? 0} />
|
||||||
<Card title="Badges obtenus" data={user?.badges?.length ?? 'Aucun'} />
|
<Card title="Badges obtenus" data={user?.badges?.length ?? 'Aucun'} />
|
||||||
<Card title="Rang actuel" data={user?.rank ?? 'Non classé'} />
|
<Card title="Rang actuel" data={user?.rank ?? 'Non classé'} />
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1 gap-4">
|
<div class="grid grid-cols-1 gap-4">
|
||||||
<div class="flex flex-col space-y-4">
|
<div class="flex flex-col gap-4">
|
||||||
<header>
|
<header>
|
||||||
<h2 class="text-lg font-semibold">Derniers puzzles</h2>
|
<h2 class="text-lg font-semibold">Derniers puzzles</h2>
|
||||||
<p class="text-highlight-secondary">
|
<p class="text-highlight-secondary">
|
||||||
|
|
|
@ -30,8 +30,6 @@ export const load = (async ({ parent, fetch, cookies, params: { chapterId, puzzl
|
||||||
throw redirect(303, `/dashboard/chapters`);
|
throw redirect(303, `/dashboard/chapters`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(chapter);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!chapter.puzzles.some((puzzle) => puzzle.id === parseInt(puzzleId)) ||
|
!chapter.puzzles.some((puzzle) => puzzle.id === parseInt(puzzleId)) ||
|
||||||
!chapter.puzzles.find((puzzle) => puzzle.id === parseInt(puzzleId))?.show
|
!chapter.puzzles.find((puzzle) => puzzle.id === parseInt(puzzleId))?.show
|
||||||
|
@ -51,8 +49,6 @@ export const load = (async ({ parent, fetch, cookies, params: { chapterId, puzzl
|
||||||
|
|
||||||
const puzzle = await res.json();
|
const puzzle = await res.json();
|
||||||
|
|
||||||
console.log(puzzle);
|
|
||||||
|
|
||||||
if (!puzzle) {
|
if (!puzzle) {
|
||||||
throw error(404, 'Puzzle not found');
|
throw error(404, 'Puzzle not found');
|
||||||
}
|
}
|
||||||
|
@ -65,7 +61,7 @@ export const load = (async ({ parent, fetch, cookies, params: { chapterId, puzzl
|
||||||
}) satisfies PageServerLoad;
|
}) satisfies PageServerLoad;
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
default: async ({ params, request, cookies }) => {
|
default: async ({ params }) => {
|
||||||
throw redirect(303, `/dashboard/chapters/${params.chapterId}/puzzle/${params.puzzleId}`);
|
throw redirect(303, `/dashboard/chapters/${params.chapterId}/puzzle/${params.puzzleId}`);
|
||||||
}
|
}
|
||||||
} satisfies Actions;
|
} satisfies Actions;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
</span>
|
</span>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div class="flex flex-col gap-2 sm:flex-row sm:items-center">
|
<div class="flex flex-col gap-2 sm:flex-row sm:items-center">
|
||||||
<span class="text-lg">{player.pseudo}</span>
|
<span class="break-all text-lg">{player.pseudo}</span>
|
||||||
<span class="text-sm text-highlight-secondary">
|
<span class="text-sm text-highlight-secondary">
|
||||||
<!-- {#if players.length > 1}
|
<!-- {#if players.length > 1}
|
||||||
{#each players as player}
|
{#each players as player}
|
||||||
|
|
Loading…
Add table
Reference in a new issue