232 lines
5.5 KiB
Svelte
232 lines
5.5 KiB
Svelte
<script lang="ts">
|
|
import { getContext } from 'svelte/internal';
|
|
import Card from './Card.svelte';
|
|
import Head from './Head.svelte';
|
|
import ModalCard from './ModalCard.svelte';
|
|
import { getExo, getExos, getTags } from '../../requests/exo.request';
|
|
import { page } from '$app/stores';
|
|
import { onMount } from 'svelte';
|
|
import Pagination from './Pagination.svelte';
|
|
import { goto } from '$app/navigation';
|
|
import {type Writable, writable} from 'svelte/store';
|
|
import { setContext } from 'svelte';
|
|
import type { Page, Tag } from '../../types/exo.type';
|
|
import type { Store } from '../../types/api.type';
|
|
import { page as p } from '$app/stores';
|
|
|
|
const { show } = getContext<{ show: Function }>('modal');
|
|
const { navigate, insertUrl } = getContext<{ navigate: Function; insertUrl: Function }>(
|
|
'navigation'
|
|
);
|
|
const { isAuth } = getContext<{ isAuth: Writable<boolean> }>('auth');
|
|
let filter = $isAuth ? 'user' : 'public';
|
|
|
|
const exerciceStore = writable<Store<Page | undefined>>({
|
|
isLoading: false,
|
|
isFetching: false,
|
|
isSuccess: false,
|
|
data: undefined
|
|
});
|
|
const tagStore = writable<Store<Tag[] | undefined>>({
|
|
isLoading: false,
|
|
isFetching: false,
|
|
isSuccess: false,
|
|
data: []
|
|
});
|
|
|
|
setContext('exos', exerciceStore);
|
|
setContext('tags', tagStore);
|
|
|
|
|
|
onMount(() => {
|
|
let page = $page.url.searchParams.get('page')
|
|
if(page == null){
|
|
page = '1'
|
|
}
|
|
if ($page.params.slug != undefined && !['user', 'public'].includes($page.params.slug)) {
|
|
getExo($page.params.slug).then((r) => {
|
|
insertUrl('exercices/' + filter);
|
|
show(ModalCard, { exo: r, exos: exerciceStore, tags: tagStore }, () => navigate(-1));
|
|
});
|
|
} else if ($page.params.slug == undefined || $page.params.slug == "user") {
|
|
filter = $isAuth ? 'user' : 'public';
|
|
goto(`/exercices/${filter}?${new URLSearchParams({page}).toString()}`)
|
|
} else if($page.params.slug == "public"){
|
|
filter = 'public';
|
|
goto(`/exercices/${filter}?${new URLSearchParams({page}).toString()}`)
|
|
}
|
|
});
|
|
|
|
$: filter = ['user', 'public'].includes($page.params.slug) ? $page.params.slug : filter;
|
|
|
|
/*$: if(['user', 'public'].includes($page.params.slug) && !$isAuth){
|
|
filter = "public"
|
|
//goto('/exercices/' + filter)
|
|
}*/
|
|
const size = 15;
|
|
$: activePage = parseInt($page.url.searchParams.get('page')!) || 1;
|
|
let search = '';
|
|
let selected: Tag[] = [];
|
|
|
|
$: {
|
|
if(!$isAuth){
|
|
filter = 'public'
|
|
}
|
|
exerciceStore.update((s) => {
|
|
return { ...s, isFetching: true };
|
|
});
|
|
getExos(filter as 'public' | 'user', {
|
|
page: activePage == 0 ? 1: activePage,
|
|
search,
|
|
size,
|
|
tags: [...selected.map((t) => t.id_code)]
|
|
})
|
|
.then((r) => {
|
|
console.log('R', r);
|
|
if (activePage > r.totalPage && r.total != 0 && r.totalPage != 0) {
|
|
activePage = r.totalPage;
|
|
//$p.url.searchParams.set('page', String(activePage));
|
|
goto(`?${new URLSearchParams({page: activePage}).toString()}`);
|
|
return;
|
|
}
|
|
exerciceStore.update((e) => {
|
|
return { ...e, isSuccess: true, isFetching: false, data: r };
|
|
});
|
|
})
|
|
.catch(console.log);
|
|
}
|
|
|
|
$: {
|
|
if($isAuth) {
|
|
tagStore.update((s) => {
|
|
return {...s, isFetching: true};
|
|
});
|
|
getTags().then((r) => {
|
|
tagStore.update((e) => {
|
|
return {...e, isSuccess: true, isFetching: false, data: r};
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
{#if $tagStore.data != undefined}
|
|
<Head location={filter} bind:search bind:selected />
|
|
{/if}
|
|
{#if $tagStore.isFetching == true}
|
|
Fetching
|
|
{/if}
|
|
|
|
<div class="feed">
|
|
<div class="title">
|
|
{#if filter == 'user'}
|
|
<h1>
|
|
Vos <span>exercices</span>
|
|
</h1>
|
|
<p>
|
|
Vous retrouverez ici tous les exercices que vous avez créé ou copié depuis les exercices
|
|
publics
|
|
</p>
|
|
{:else}
|
|
<h1>
|
|
Tous les <span>exercices</span>
|
|
</h1>
|
|
<p>Vous retrouverez ici tous les exercices créés par les autres utilisateurs</p>
|
|
{/if}
|
|
</div>
|
|
{#if $exerciceStore.data != undefined}
|
|
{#each $exerciceStore.data.items.filter((e) => e != null && selected.every((t) => e.tags
|
|
.map((s) => s.id_code)
|
|
.includes(t.id_code))) as e}
|
|
<Card bind:exo={e} />
|
|
{/each}
|
|
{:else}
|
|
{#each Array(10) as i}
|
|
<div class="skeleton"><span /></div>
|
|
{/each}
|
|
{/if}
|
|
</div>
|
|
{#if $exerciceStore.data != undefined}
|
|
<Pagination bind:page={activePage} total={$exerciceStore.data.totalPage} />
|
|
{/if}
|
|
|
|
<style lang="scss">
|
|
@import '../../variables';
|
|
|
|
.skeleton {
|
|
width: 330px;
|
|
height: 250px;
|
|
opacity: .8;
|
|
span {
|
|
display: block;
|
|
height: 100%;
|
|
width: 100%;
|
|
background-color: $skeleton;
|
|
display: block;
|
|
position: relative;
|
|
border-radius: 4px;
|
|
background-color: $skeleton;
|
|
overflow: hidden;
|
|
&::after {
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
content: '';
|
|
position: absolute;
|
|
animation: waves 1.6s linear 0.5s infinite;
|
|
transform: translateX(-100%);
|
|
background: linear-gradient(
|
|
90deg,
|
|
transparent,
|
|
(lighten($color: $skeleton, $amount: 3), rgba(0, 0, 0, 0.04)),
|
|
transparent
|
|
);
|
|
}
|
|
}
|
|
}
|
|
@keyframes waves {
|
|
0% {
|
|
transform: translateX(-100%);
|
|
}
|
|
60% {
|
|
transform: translateX(100%);
|
|
}
|
|
100% {
|
|
transform: translateX(100%);
|
|
}
|
|
}
|
|
|
|
.feed {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
|
grid-auto-flow: dense;
|
|
grid-gap: 32px;
|
|
margin: 0 auto;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.title {
|
|
grid-column: 1/3;
|
|
display: flex;
|
|
text-align: left;
|
|
justify-content: center;
|
|
flex-direction: column;
|
|
h1 {
|
|
font-size: 3.5em;
|
|
font-weight: bolder;
|
|
margin: 0;
|
|
}
|
|
p {
|
|
font-size: 1.1em;
|
|
}
|
|
span {
|
|
color: $primary;
|
|
}
|
|
}
|
|
</style>
|