Compare commits
5 commits
49f2c09648
...
e44cb8d185
Author | SHA1 | Date | |
---|---|---|---|
e44cb8d185 | |||
a496751f8c | |||
|
3c12603404 | ||
|
7e2d80f971 | ||
|
c98b641bb1 |
26 changed files with 164 additions and 150 deletions
6
src/app.d.ts
vendored
6
src/app.d.ts
vendored
|
@ -5,7 +5,10 @@ import type { User } from '$lib/types';
|
||||||
// for information about these interfaces
|
// for information about these interfaces
|
||||||
declare global {
|
declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
// interface Error {}
|
interface Error {
|
||||||
|
message: string;
|
||||||
|
errorId: string;
|
||||||
|
}
|
||||||
interface Locals {
|
interface Locals {
|
||||||
user: User | null;
|
user: User | null;
|
||||||
}
|
}
|
||||||
|
@ -17,3 +20,4 @@ declare global {
|
||||||
}
|
}
|
||||||
|
|
||||||
export { };
|
export { };
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { Handle } from '@sveltejs/kit';
|
import type { Handle, HandleFetch, HandleServerError } from '@sveltejs/kit';
|
||||||
|
|
||||||
import { API_URL } from '$env/static/private';
|
import { API_URL } from '$env/static/private';
|
||||||
|
|
||||||
|
@ -30,3 +30,32 @@ export const handle: Handle = async ({ event, resolve }) => {
|
||||||
|
|
||||||
return resolve(event);
|
return resolve(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const handleFetch: HandleFetch = async ({ request, fetch, event: { cookies } }) => {
|
||||||
|
|
||||||
|
const session = cookies.get('session');
|
||||||
|
|
||||||
|
if (!session) {
|
||||||
|
return fetch(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
request = new Request(request, {
|
||||||
|
headers: {
|
||||||
|
...request.headers,
|
||||||
|
Authorization: `Bearer ${session}`
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return fetch(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const handleError: HandleServerError = async ({ error, status }) => {
|
||||||
|
const errorId = crypto.randomUUID();
|
||||||
|
|
||||||
|
console.error(`Error ID: ${errorId} - Status: ${status} - ${error}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: 'Whoops!',
|
||||||
|
errorId,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -29,6 +29,7 @@ export interface Completion {
|
||||||
export interface Group {
|
export interface Group {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
playerCount: number;
|
||||||
chapter?: number;
|
chapter?: number;
|
||||||
puzzle?: number;
|
puzzle?: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
import { type ClassValue, clsx } from "clsx";
|
import { clsx, type ClassValue } from "clsx";
|
||||||
import { twMerge } from "tailwind-merge";
|
|
||||||
import { cubicOut } from "svelte/easing";
|
import { cubicOut } from "svelte/easing";
|
||||||
import type { TransitionConfig } from "svelte/transition";
|
import type { TransitionConfig } from "svelte/transition";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs));
|
return twMerge(clsx(inputs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const handleRedirect = (path: string, url: URL) => {
|
||||||
|
const redirectTo = url.pathname + url.search;
|
||||||
|
return `/${path}?redirectTo=${encodeURIComponent(redirectTo)}`;
|
||||||
|
}
|
||||||
|
|
||||||
type FlyAndScaleParams = {
|
type FlyAndScaleParams = {
|
||||||
y?: number;
|
y?: number;
|
||||||
x?: number;
|
x?: number;
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
import { redirect, type ServerLoad } from '@sveltejs/kit';
|
|
||||||
|
|
||||||
export const load: ServerLoad = async ({ parent }) => {
|
|
||||||
const { user } = await parent();
|
|
||||||
if (!user) redirect(302, '/login');
|
|
||||||
};
|
|
|
@ -2,7 +2,6 @@
|
||||||
import { navigating } from '$app/stores';
|
import { navigating } from '$app/stores';
|
||||||
|
|
||||||
import { Loader, Navbar, Sidenav } from '$lib/components/layout';
|
import { Loader, Navbar, Sidenav } from '$lib/components/layout';
|
||||||
import { Toaster } from '$lib/components/ui/sonner';
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $navigating}
|
{#if $navigating}
|
||||||
|
@ -18,7 +17,6 @@
|
||||||
class="flex w-full flex-1 transform flex-col overflow-y-auto p-4 duration-300 ease-in-out"
|
class="flex w-full flex-1 transform flex-col overflow-y-auto p-4 duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
<Toaster position="top-right" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,18 +4,13 @@ import { redirect } from '@sveltejs/kit';
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
import type { Chapter } from '$lib/types';
|
import type { Chapter } from '$lib/types';
|
||||||
|
import { handleRedirect } from '$lib/utils';
|
||||||
|
|
||||||
export const load = (async ({ fetch, cookies, locals: { user } }) => {
|
export const load = (async ({ url, fetch, locals: { user } }) => {
|
||||||
|
|
||||||
if (!user) redirect(302, '/login');
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
const session = cookies.get('session');
|
const res = await fetch(`${API_URL}/chapters`);
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/chapters`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { redirect } from '@sveltejs/kit';
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
export const load = (async ({ locals: { user } }) => {
|
import { handleRedirect } from '$lib/utils';
|
||||||
if (!user) redirect(302, '/login');
|
|
||||||
}) satisfies PageServerLoad;
|
export const load: PageServerLoad = async ({ url, locals: { user } }) => {
|
||||||
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
}
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
import { API_URL } from '$env/static/private';
|
import { API_URL } from '$env/static/private';
|
||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
import type { Chapter } from '$lib/types';
|
import type { Chapter } from '$lib/types';
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { handleRedirect } from '$lib/utils';
|
||||||
|
|
||||||
export const load = (async ({ locals: { user }, fetch, cookies }) => {
|
export const load = (async ({ url, locals: { user }, fetch }) => {
|
||||||
|
|
||||||
if (!user) redirect(302, '/login');
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
const session = cookies.get('session');
|
const res = await fetch(`${API_URL}/chapters`);
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/chapters`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -3,19 +3,14 @@ import { API_URL } from '$env/static/private';
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
import type { Chapter } from '$lib/types';
|
import type { Chapter } from '$lib/types';
|
||||||
|
import { handleRedirect } from '$lib/utils';
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const load = (async ({ locals: { user }, fetch, cookies, params: { chapterId } }) => {
|
export const load = (async ({ url, locals: { user }, fetch, params: { chapterId } }) => {
|
||||||
|
|
||||||
if (!user) redirect(302, '/login');
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
const session = cookies.get('session');
|
const res = await fetch(`${API_URL}/chapter/${chapterId}`);
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/chapter/${chapterId}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
redirect(302, '/chapters');
|
redirect(302, '/chapters');
|
||||||
|
|
|
@ -3,19 +3,14 @@ import { API_URL } from '$env/static/private';
|
||||||
import type { Actions, PageServerLoad } from './$types';
|
import type { Actions, PageServerLoad } from './$types';
|
||||||
|
|
||||||
import type { Chapter, Group } from '$lib/types';
|
import type { Chapter, Group } from '$lib/types';
|
||||||
|
import { handleRedirect } from '$lib/utils';
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const load = (async ({ locals: { user }, fetch, cookies, params: { chapterId } }) => {
|
export const load: PageServerLoad = async ({ url, locals: { user }, fetch, params: { chapterId } }) => {
|
||||||
|
|
||||||
if (!user) redirect(302, '/login');
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
const session = cookies.get('session');
|
let res = await fetch(`${API_URL}/chapter/${chapterId}`);
|
||||||
|
|
||||||
let res = await fetch(`${API_URL}/chapter/${chapterId}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
redirect(302, '/chapters');
|
redirect(302, '/chapters');
|
||||||
|
@ -27,12 +22,7 @@ export const load = (async ({ locals: { user }, fetch, cookies, params: { chapte
|
||||||
redirect(302, '/chapters');
|
redirect(302, '/chapters');
|
||||||
}
|
}
|
||||||
|
|
||||||
res = await fetch(`${API_URL}/groups/${chapter.id}`, {
|
res = await fetch(`${API_URL}/groups/${chapter.id}`);
|
||||||
headers:
|
|
||||||
{
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
redirect(302, `/chapters/${chapterId}`);
|
redirect(302, `/chapters/${chapterId}`);
|
||||||
|
@ -45,23 +35,18 @@ export const load = (async ({ locals: { user }, fetch, cookies, params: { chapte
|
||||||
chapter,
|
chapter,
|
||||||
groups
|
groups
|
||||||
};
|
};
|
||||||
}) satisfies PageServerLoad;
|
};
|
||||||
|
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
join: async ({ fetch, params: { chapterId }, cookies, request }) => {
|
join: async ({ fetch, params: { chapterId }, request }) => {
|
||||||
|
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const name = data.get('name') as string;
|
const name = data.get('name') as string;
|
||||||
|
|
||||||
const session = cookies.get('session');
|
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/groupJoin`, {
|
const res = await fetch(`${API_URL}/groupJoin`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name,
|
name,
|
||||||
chapter: parseInt(chapterId),
|
chapter: parseInt(chapterId),
|
||||||
|
@ -78,7 +63,7 @@ export const actions: Actions = {
|
||||||
if (res.status === 403) {
|
if (res.status === 403) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Vous êtes déjà dans un groupe'
|
message: 'Vous êtes déjà dans un groupe ou le groupe est complet'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,19 +79,14 @@ export const actions: Actions = {
|
||||||
message: "Une erreur s'est produite"
|
message: "Une erreur s'est produite"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
leave: async ({ fetch, params: { chapterId }, cookies, request }) => {
|
leave: async ({ fetch, params: { chapterId }, request }) => {
|
||||||
|
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const name = data.get('name') as string;
|
const name = data.get('name') as string;
|
||||||
|
|
||||||
const session = cookies.get('session');
|
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/groupQuit`, {
|
const res = await fetch(`${API_URL}/groupQuit`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name,
|
name,
|
||||||
chapter: parseInt(chapterId),
|
chapter: parseInt(chapterId),
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
export let form: ActionData;
|
export let form: ActionData;
|
||||||
|
|
||||||
|
let limit = 4;
|
||||||
|
|
||||||
let name = '';
|
let name = '';
|
||||||
let submitting = false;
|
let submitting = false;
|
||||||
|
|
||||||
|
@ -58,19 +60,26 @@
|
||||||
</div>
|
</div>
|
||||||
<ul class="flex flex-col gap-2">
|
<ul class="flex flex-col gap-2">
|
||||||
{#if filteredGroups.length === 0}
|
{#if filteredGroups.length === 0}
|
||||||
<li class="flex h-16 w-full items-center justify-center rounded border border-border bg-card">
|
<li
|
||||||
|
class="flex min-h-16 w-full items-center justify-center rounded border border-border bg-card"
|
||||||
|
>
|
||||||
<p class="text-muted-foreground">Aucun groupe trouvé</p>
|
<p class="text-muted-foreground">Aucun groupe trouvé</p>
|
||||||
</li>
|
</li>
|
||||||
{:else}
|
{:else}
|
||||||
{#each filteredGroups as group (group.name)}
|
{#each filteredGroups as group (group.name)}
|
||||||
<li class="group relative flex h-full w-full flex-col rounded border border-border bg-card">
|
<li
|
||||||
<div class="flex h-full w-full items-center justify-between gap-4 p-4">
|
class="group relative flex min-h-16 w-full flex-col rounded border border-border bg-card"
|
||||||
|
>
|
||||||
|
<div class="flex items-center justify-between gap-4 p-4">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="font-semibold">
|
<span class="font-semibold">
|
||||||
{group.name}
|
{group.name}
|
||||||
</span>
|
</span>
|
||||||
|
<span class="text-muted-foreground">
|
||||||
|
{group.playerCount} membres
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
{#if group.playerCount < limit}
|
||||||
{#if $page.data.user?.groups.some((g) => g.name === group.name)}
|
{#if $page.data.user?.groups.some((g) => g.name === group.name)}
|
||||||
<form
|
<form
|
||||||
method="post"
|
method="post"
|
||||||
|
@ -127,7 +136,7 @@
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
|
import { API_URL } from "$env/static/private";
|
||||||
import { fail, redirect, type Actions } from "@sveltejs/kit";
|
import { fail, redirect, type Actions } from "@sveltejs/kit";
|
||||||
import type { PageServerLoad } from "./$types";
|
import type { PageServerLoad } from "./$types";
|
||||||
|
|
||||||
import { superValidate } from "sveltekit-superforms";
|
import { superValidate } from "sveltekit-superforms";
|
||||||
import { zod } from "sveltekit-superforms/adapters";
|
import { zod } from "sveltekit-superforms/adapters";
|
||||||
|
|
||||||
import { API_URL } from "$env/static/private";
|
import { handleRedirect } from "$lib/utils";
|
||||||
import { groupSchema } from "$lib/validations/group";
|
import { groupSchema } from "$lib/validations/group";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ params: { chapterId }, locals: { user } }) => {
|
export const load: PageServerLoad = async ({ url, params: { chapterId }, locals: { user } }) => {
|
||||||
|
|
||||||
if (!user) redirect(302, '/login');
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
if (user.groups.find(g => g.chapter === parseInt(chapterId))) {
|
if (user.groups.find(g => g.chapter === parseInt(chapterId))) {
|
||||||
redirect(302, `/chapters/${chapterId}/groups`);
|
redirect(302, `/chapters/${chapterId}/groups`);
|
||||||
|
@ -24,14 +25,12 @@ export const load: PageServerLoad = async ({ params: { chapterId }, locals: { us
|
||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
default: async ({ locals: { user }, fetch, request, cookies, params: { chapterId } }) => {
|
default: async ({ url, locals: { user }, fetch, request, params: { chapterId } }) => {
|
||||||
|
|
||||||
if (!user) redirect(302, '/login');
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
if (!chapterId) redirect(302, '/chapters');
|
if (!chapterId) redirect(302, '/chapters');
|
||||||
|
|
||||||
const session = cookies.get('session');
|
|
||||||
|
|
||||||
const form = await superValidate(request, zod(groupSchema));
|
const form = await superValidate(request, zod(groupSchema));
|
||||||
|
|
||||||
if (!form.valid) {
|
if (!form.valid) {
|
||||||
|
@ -40,9 +39,6 @@ export const actions: Actions = {
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/groupCreate`, {
|
const res = await fetch(`${API_URL}/groupCreate`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
...form.data,
|
...form.data,
|
||||||
chapter: parseInt(chapterId)
|
chapter: parseInt(chapterId)
|
||||||
|
|
|
@ -1,22 +1,17 @@
|
||||||
import { API_URL } from '$env/static/private';
|
import { API_URL } from '$env/static/private';
|
||||||
import type { PageServerLoad } from './$types';
|
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
import type { LeaderboardEvent } from '$lib/types';
|
import type { LeaderboardEvent } from '$lib/types';
|
||||||
|
import { handleRedirect } from '$lib/utils';
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ locals: { user }, fetch, cookies, params: { chapterId } }) => {
|
export const load: PageServerLoad = async ({ url, locals: { user }, fetch, params: { chapterId } }) => {
|
||||||
|
|
||||||
if (!user) redirect(302, '/login');
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
if (!chapterId) redirect(302, '/');
|
if (!chapterId) redirect(302, '/');
|
||||||
|
|
||||||
const session = cookies.get('session');
|
const res = await fetch(`${API_URL}/leaderboard/${chapterId}`);
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/leaderboard/${chapterId}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) return {
|
if (!res.ok) return {
|
||||||
leaderboard: []
|
leaderboard: []
|
||||||
|
|
|
@ -2,7 +2,9 @@ import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
export const load = (async ({ locals: { user }, params: { chapterId } }) => {
|
import { handleRedirect } from '$lib/utils';
|
||||||
if (!user) redirect(302, '/login');
|
|
||||||
|
export const load = (async ({ url, locals: { user }, params: { chapterId } }) => {
|
||||||
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
redirect(302, chapterId ? `/chapters/${chapterId}` : `/chapters`);
|
redirect(302, chapterId ? `/chapters/${chapterId}` : `/chapters`);
|
||||||
}) satisfies PageServerLoad;
|
}) satisfies PageServerLoad;
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import { API_URL } from '$env/static/private';
|
import { API_URL } from '$env/static/private';
|
||||||
import { error, redirect, type Actions } from '@sveltejs/kit';
|
import { error, redirect, type Actions } from '@sveltejs/kit';
|
||||||
import type { PageServerLoad } from './$types';
|
|
||||||
import { compile } from 'mdsvex';
|
import { compile } from 'mdsvex';
|
||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
import type Puzzle from '$lib/components/puzzle.svelte';
|
import type Puzzle from '$lib/components/puzzle.svelte';
|
||||||
import type { Chapter } from '$lib/types';
|
import type { Chapter } from '$lib/types';
|
||||||
|
import { handleRedirect } from '$lib/utils';
|
||||||
|
|
||||||
export const load = (async ({ locals: { user }, fetch, cookies, params: { chapterId, puzzleId } }) => {
|
export const load = (async ({ url, locals: { user }, fetch, cookies, params: { chapterId, puzzleId } }) => {
|
||||||
if (!user) redirect(302, '/login');
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
const session = cookies.get('session');
|
const session = cookies.get('session');
|
||||||
|
|
||||||
|
@ -15,11 +16,7 @@ export const load = (async ({ locals: { user }, fetch, cookies, params: { chapte
|
||||||
redirect(302, `/chapters/${chapterId}`);
|
redirect(302, `/chapters/${chapterId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = await fetch(`${API_URL}/chapter/${chapterId}`, {
|
let res = await fetch(`${API_URL}/chapter/${chapterId}`);
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
redirect(302, `/chapters`);
|
redirect(302, `/chapters`);
|
||||||
|
@ -38,20 +35,22 @@ export const load = (async ({ locals: { user }, fetch, cookies, params: { chapte
|
||||||
redirect(302, `/chapters/${chapterId}`);
|
redirect(302, `/chapters/${chapterId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = await fetch(`${API_URL}/puzzle/${puzzleId}`, {
|
res = await fetch(`${API_URL}/puzzle/${puzzleId}`);
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
error(404, 'Puzzle not found');
|
error(404, {
|
||||||
|
errorId: 'puzzle_not_found',
|
||||||
|
message: 'Puzzle not found'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const puzzle: Puzzle = await res.json();
|
const puzzle: Puzzle = await res.json();
|
||||||
|
|
||||||
if (!puzzle) {
|
if (!puzzle) {
|
||||||
error(404, 'Puzzle not found');
|
error(404, {
|
||||||
|
errorId: 'puzzle_not_found',
|
||||||
|
message: 'Puzzle not found'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = await compile(puzzle.content);
|
const content = await compile(puzzle.content);
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
</script>
|
|
||||||
|
|
||||||
TODO
|
|
|
@ -4,18 +4,13 @@ import { redirect } from '@sveltejs/kit';
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
import type { Leaderboard } from '$lib/types';
|
import type { Leaderboard } from '$lib/types';
|
||||||
|
import { handleRedirect } from '$lib/utils';
|
||||||
|
|
||||||
export const load = (async ({ locals: { user }, fetch, cookies }) => {
|
export const load = (async ({ url, locals: { user }, fetch }) => {
|
||||||
|
|
||||||
if (!user) redirect(302, '/login');
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
const session = cookies.get('session');
|
const res = await fetch(`${API_URL}/leaderboard`);
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/leaderboard`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { page } from '$app/stores';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
let routes = [
|
let routes = [
|
||||||
{
|
{
|
||||||
|
@ -14,7 +16,13 @@
|
||||||
<ul class="flex gap-2 lg:flex-col">
|
<ul class="flex gap-2 lg:flex-col">
|
||||||
{#each routes as { name, href } (name)}
|
{#each routes as { name, href } (name)}
|
||||||
<li>
|
<li>
|
||||||
<Button class="w-full" variant="outline" {href}>{name}</Button>
|
<Button
|
||||||
|
class={cn('w-full', {
|
||||||
|
'bg-secondary': $page.url.pathname === href
|
||||||
|
})}
|
||||||
|
variant="outline"
|
||||||
|
{href}>{name}</Button
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -2,12 +2,14 @@ import { API_URL } from '$env/static/private';
|
||||||
import { fail, redirect, type Actions } from '@sveltejs/kit';
|
import { fail, redirect, type Actions } from '@sveltejs/kit';
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
import { settingSchema } from '$lib/validations/auth';
|
|
||||||
import { zod } from 'sveltekit-superforms/adapters';
|
import { zod } from 'sveltekit-superforms/adapters';
|
||||||
import { setError, superValidate } from 'sveltekit-superforms/server';
|
import { setError, superValidate } from 'sveltekit-superforms/server';
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ locals: { user } }) => {
|
import { handleRedirect } from '$lib/utils';
|
||||||
if (!user) redirect(302, '/login');
|
import { settingSchema } from '$lib/validations/auth';
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async ({ url, locals: { user } }) => {
|
||||||
|
if (!user) redirect(302, handleRedirect('login', url));
|
||||||
|
|
||||||
const form = await superValidate(user, zod(settingSchema));
|
const form = await superValidate(user, zod(settingSchema));
|
||||||
|
|
||||||
|
@ -18,12 +20,10 @@ export const load: PageServerLoad = async ({ locals: { user } }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
default: async ({ request, cookies, locals: { user } }) => {
|
default: async ({ request, fetch, locals: { user } }) => {
|
||||||
|
|
||||||
if (!user) return fail(401);
|
if (!user) return fail(401);
|
||||||
|
|
||||||
const session = cookies.get('session');
|
|
||||||
|
|
||||||
const form = await superValidate(request, zod(settingSchema));
|
const form = await superValidate(request, zod(settingSchema));
|
||||||
|
|
||||||
if (!form.valid) {
|
if (!form.valid) {
|
||||||
|
@ -32,9 +32,6 @@ export const actions: Actions = {
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/user/settings`, {
|
const res = await fetch(`${API_URL}/user/settings`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${session}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
...form.data
|
...form.data
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import { Toaster } from '$lib/components/ui/sonner';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<slot />
|
|
||||||
|
|
||||||
<Toaster />
|
|
|
@ -21,7 +21,7 @@ export const load: PageServerLoad = async ({ locals: { user } }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
default: async ({ request, cookies, fetch }) => {
|
default: async ({ request, cookies, fetch, url: { searchParams } }) => {
|
||||||
|
|
||||||
const form = await superValidate(request, zod(loginSchema));
|
const form = await superValidate(request, zod(loginSchema));
|
||||||
|
|
||||||
|
@ -52,6 +52,11 @@ export const actions: Actions = {
|
||||||
sameSite: 'strict',
|
sameSite: 'strict',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const redirectTo = searchParams.get('redirectTo');
|
||||||
|
|
||||||
|
if (redirectTo)
|
||||||
|
redirect(302, `/${redirectTo.slice(1)}`);
|
||||||
|
|
||||||
redirect(302, '/');
|
redirect(302, '/');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,7 +53,7 @@ export const actions: Actions = {
|
||||||
form
|
form
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
confirmation: async ({ request, cookies }) => {
|
confirmation: async ({ request, cookies, url: { searchParams } }) => {
|
||||||
const form = await superValidate(request, zod(registerConfirmationSchema));
|
const form = await superValidate(request, zod(registerConfirmationSchema));
|
||||||
|
|
||||||
if (!form.valid) {
|
if (!form.valid) {
|
||||||
|
@ -93,6 +93,11 @@ export const actions: Actions = {
|
||||||
sameSite: 'strict',
|
sameSite: 'strict',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const redirectTo = searchParams.get('redirectTo');
|
||||||
|
|
||||||
|
if (redirectTo)
|
||||||
|
redirect(302, `/${redirectTo.slice(1)}`);
|
||||||
|
|
||||||
redirect(302, '/');
|
redirect(302, '/');
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
import Input from '$lib/components/ui/input/input.svelte';
|
import Input from '$lib/components/ui/input/input.svelte';
|
||||||
|
|
||||||
import { registerConfirmationSchema, registerSchema } from '$lib/validations/auth';
|
import { registerConfirmationSchema, registerSchema } from '$lib/validations/auth';
|
||||||
import { enhance } from '$app/forms';
|
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
|
|
14
src/routes/+error.svelte
Normal file
14
src/routes/+error.svelte
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
|
||||||
|
import Button from '$lib/components/ui/button/button.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex min-h-screen items-center justify-center">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="text-6xl font-bold text-red-500">Oops!</h1>
|
||||||
|
<p class="mt-4 text-xl">Apparement tu as navigué en eau trouble...</p>
|
||||||
|
<Button class="mt-4" href="/">Retour au port</Button>
|
||||||
|
<p class="mt-4 text-xs text-muted-foreground">{$page.error?.errorId}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -2,8 +2,11 @@
|
||||||
import '../app.css';
|
import '../app.css';
|
||||||
|
|
||||||
import { Metadata } from '$lib/components';
|
import { Metadata } from '$lib/components';
|
||||||
|
import { Toaster } from '$lib/components/ui/sonner';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Metadata />
|
<Metadata />
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
|
|
||||||
|
<Toaster />
|
||||||
|
|
Loading…
Add table
Reference in a new issue