peer-at-code-web/src/routes/(app)/chapters/[chapterId]/groups/+page.svelte
2024-03-31 23:55:56 +02:00

145 lines
4.3 KiB
Svelte

<script lang="ts">
import { enhance } from '$app/forms';
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import type { ActionData, PageData } from './$types';
import Code from 'lucide-svelte/icons/code';
import Minus from 'lucide-svelte/icons/minus';
import Plus from 'lucide-svelte/icons/plus';
import Users from 'lucide-svelte/icons/users';
import Button from '$lib/components/ui/button/button.svelte';
import Input from '$lib/components/ui/input/input.svelte';
import { Loader2 } from 'lucide-svelte';
import { toast } from 'svelte-sonner';
export let data: PageData;
export let form: ActionData;
let limit = 4;
let name = '';
let submitting = false;
$: filteredGroups = data.groups.filter((group) => {
const regex = new RegExp(name, 'i');
return regex.test(group.name);
});
$: hasGroup = $page.data.user?.groups.some((g) =>
data.groups.map((g) => g.name).includes(g.name)
);
$: if (form?.message) {
toast(form.message);
}
</script>
<section class="flex w-full flex-col gap-2">
<header class="flex flex-col justify-between gap-2 lg:flex-row lg:items-center">
<div class="flex flex-col">
<h2 class="text-xl font-semibold">{data.chapter.name}</h2>
<p class="text-muted-foreground">
Vous pouvez créer ou rejoindre un groupe pour participer à la complétion de ce chapitre
</p>
</div>
<div class="flex gap-2">
<Button disabled={hasGroup} on:click={() => goto(`/chapters/${data.chapter.id}/groups/new`)}>
<Users class="mr-2 h-4 w-4" />
Créer un groupe
</Button>
<Button href="/chapters/{data.chapter.id}">
<Code class="mr-2 h-4 w-4" />
Retourner aux puzzles
</Button>
</div>
</header>
<div class="flex">
<Input placeholder="Quarter Master" bind:value={name} />
</div>
<ul class="flex flex-col gap-2">
{#if filteredGroups.length === 0}
<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>
</li>
{:else}
{#each filteredGroups as group (group.name)}
<li
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">
<span class="font-semibold">
{group.name}
</span>
<span class="text-muted-foreground">
{group.playerCount} membres
</span>
</div>
{#if group.playerCount < limit}
{#if $page.data.user?.groups.some((g) => g.name === group.name)}
<form
method="post"
action="?/leave"
use:enhance={({ formElement, formData, action, cancel, submitter }) => {
submitting = true;
return async ({ result, update }) => {
switch (result.type) {
case 'success':
await update({ invalidateAll: true });
break;
}
submitting = false;
};
}}
>
<input type="hidden" name="name" value={group.name} />
<Button disabled={submitting} variant="destructive" type="submit">
{#if submitting}
<Loader2 class="mr-2 h-4 w-4 animate-spin" />
{:else}
<Minus class="mr-2 h-4 w-4" />
{/if}
Quitter
</Button>
</form>
{/if}
{#if !$page.data.user?.groups.some((g) => data.groups
.map((g) => g.name)
.includes(g.name))}
<form
method="post"
action="?/join"
use:enhance={({ formElement, formData, action, cancel, submitter }) => {
submitting = true;
return async ({ result, update }) => {
switch (result.type) {
case 'success':
await update({ invalidateAll: true });
break;
}
submitting = false;
};
}}
>
<input type="hidden" name="name" value={group.name} />
<Button disabled={submitting} variant="outline" type="submit">
{#if submitting}
<Loader2 class="mr-2 h-4 w-4 animate-spin" />
{:else}
<Plus class="mr-2 h-4 w-4" />
{/if}
Rejoindre
</Button>
</form>
{/if}
{/if}
</div>
</li>
{/each}
{/if}
</ul>
</section>