262 lines
5.0 KiB
Svelte
262 lines
5.0 KiB
Svelte
<script lang="ts">
|
|
import type { Member, ParcoursRead, Room } from '../../types/room.type';
|
|
import { getContext, onDestroy } from 'svelte';
|
|
import type { Writable } from 'svelte/store';
|
|
import { getParcours } from '../../requests/room.request';
|
|
import { goto } from '$app/navigation';
|
|
import { page } from '$app/stores';
|
|
import { parseTimer } from '../../utils/utils';
|
|
import IoIosArrowDown from 'svelte-icons/io/IoIosArrowDown.svelte';
|
|
import IoMdOpen from 'svelte-icons/io/IoMdOpen.svelte';
|
|
import FaTimes from 'svelte-icons/fa/FaTimes.svelte';
|
|
import FaEdit from 'svelte-icons/fa/FaEdit.svelte';
|
|
import { messages, handlers } from '../../store/ws';
|
|
import Stats from './Stats.svelte';
|
|
import ChallengesList from './ChallengesList.svelte';
|
|
|
|
export let id_code: string;
|
|
|
|
const room: Writable<Room> = getContext('room');
|
|
const member: Writable<Member> = getContext('member');
|
|
|
|
const { send } = getContext<{ send: Function }>('ws');
|
|
|
|
const parcours: Writable<ParcoursRead | null> = getContext('parcours');
|
|
|
|
let open = '';
|
|
|
|
$: ($parcours == null || (parcours != null && $parcours.id_code != id_code)) &&
|
|
getParcours($room.id_code, id_code, $member.isUser ? $member.clientId : null).then((p) => {
|
|
console.log('SETPARC');
|
|
parcours.set(p);
|
|
send('sub_parcours', { parcours_id: p.id_code });
|
|
});
|
|
|
|
let tab = 'stats';
|
|
</script>
|
|
|
|
<div class="parcours">
|
|
{#if $parcours != null}
|
|
<div class="title">
|
|
<h1>{$parcours.name}</h1>
|
|
|
|
<div>
|
|
{#if !!$member.isAdmin}
|
|
<div
|
|
|
|
class="icon edit"
|
|
on:click={() => {
|
|
goto(`?${new URLSearchParams({p: id_code, edit: "1"}).toString()}`);
|
|
}}
|
|
on:keydown={()=>{}}
|
|
>
|
|
<FaEdit />
|
|
</div>
|
|
{/if}
|
|
|
|
<div
|
|
class="icon back"
|
|
on:click={() => {
|
|
//$page.url.searchParams.delete('p');
|
|
|
|
goto(`?${new URLSearchParams().toString()}`);
|
|
//parcours.set(null)
|
|
}}
|
|
on:keydown={()=>{}}
|
|
>
|
|
<FaTimes />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="main">
|
|
<div class="tabs">
|
|
<div
|
|
class="tab"
|
|
class:active={tab == 'stats'}
|
|
on:click={() => {
|
|
tab = 'stats';
|
|
}}
|
|
on:keydown={() => {}}
|
|
>
|
|
Statistiques
|
|
</div>
|
|
<div
|
|
class="tab"
|
|
class:active={tab == 'infos'}
|
|
on:click={() => {
|
|
tab = 'infos';
|
|
}}
|
|
on:keydown={() => {}}
|
|
>
|
|
Informations
|
|
</div>
|
|
</div>
|
|
|
|
{#if tab == 'infos'}
|
|
<div class="infos">
|
|
<div>
|
|
<h2>Informations</h2>
|
|
<p><span class="strong">Temps imparti :</span> {parseTimer($parcours.time)}</p>
|
|
<p>
|
|
<span class="strong">Nombre de fautes maximal :</span>
|
|
{$parcours.max_mistakes}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="exos">
|
|
<h2>Exercices</h2>
|
|
{#each $parcours.exercices as e}
|
|
<div class="exo">
|
|
<p>{e.name} <span class="quantity">x {e.quantity}</span></p>
|
|
<div class="examples">
|
|
{#each e.examples.data as ex}
|
|
<p>{ex.calcul}</p>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
|
|
{#if tab == 'stats'}
|
|
<div class="stats">
|
|
<Stats />
|
|
</div>
|
|
<div class="trylist">
|
|
<h2>Résumé des essais</h2>
|
|
<ChallengesList />
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
<div class="btn">
|
|
<button
|
|
on:click={() => {
|
|
if ($parcours == null) return;
|
|
$page.url.searchParams.set('c', $parcours.id_code);
|
|
$page.url.searchParams.delete('p');
|
|
$page.url.searchParams.delete('corr');
|
|
goto(`?${$page.url.searchParams.toString()}`);
|
|
}}
|
|
class="primary-btn">Essayer</button
|
|
>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
|
|
.main {
|
|
background-color: $background;
|
|
padding: 50px;
|
|
border-radius: 5px;
|
|
border: 1px solid $border;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20px;
|
|
position: relative;
|
|
padding-top: 100px;
|
|
}
|
|
|
|
.tabs {
|
|
position: absolute;
|
|
display: flex;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
border-bottom: 1px solid $border;
|
|
.tab {
|
|
flex-grow: 1;
|
|
text-align: center;
|
|
padding: 20px 0;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
.active {
|
|
color: $primary;
|
|
border-bottom: 1px solid $primary;
|
|
font-weight: 600;
|
|
}
|
|
|
|
|
|
|
|
.icon {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 20px;
|
|
}
|
|
|
|
|
|
.trylist {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
margin-top: 40px;
|
|
}
|
|
|
|
.exo {
|
|
margin-bottom: 10px;
|
|
margin-left: 10px;
|
|
> p {
|
|
font-weight: 600;
|
|
font-size: 1.1em;
|
|
span.quantity {
|
|
font-weight: 400;
|
|
font-size: 0.9em;
|
|
color: grey;
|
|
}
|
|
}
|
|
}
|
|
.examples {
|
|
margin-left: 10px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 5px;
|
|
p {
|
|
color: grey;
|
|
}
|
|
}
|
|
|
|
.infos {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
.parcours {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20px;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.btn {
|
|
text-align: center;
|
|
width: 100%;
|
|
}
|
|
|
|
.title {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
> div {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
.icon {
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
transform: scale(1.1);
|
|
}
|
|
}
|
|
}
|
|
.back {
|
|
color: $red;
|
|
}
|
|
.edit {
|
|
color: $green;
|
|
}
|
|
</style>
|