194 lines
4.1 KiB
Svelte
194 lines
4.1 KiB
Svelte
<script lang="ts">
|
|
import type { Exercice } from '../../types/exo.type';
|
|
import { getContext } from 'svelte';
|
|
import ModalCard from './ModalCard.svelte';
|
|
import { goto } from '$app/navigation';
|
|
import { cloneExo } from '../../requests/exo.request';
|
|
import TagContainer from './TagContainer.svelte';
|
|
import PrivacyIndicator from './PrivacyIndicator.svelte';
|
|
import MdContentCopy from 'svelte-icons/md/MdContentCopy.svelte';
|
|
import type { Writable } from 'svelte/store';
|
|
|
|
export let exo: Exercice;
|
|
|
|
const { show } = getContext<{ show: Function }>('modal');
|
|
const { navigate } = getContext<{ navigate: Function }>('navigation');
|
|
const { isAuth } = getContext<{ isAuth: Writable<boolean> }>('auth');
|
|
const exerciceStore = getContext('exos');
|
|
const tagsStore = getContext('tags');
|
|
|
|
let opened = false;
|
|
const handleClick = () => {
|
|
opened = true;
|
|
navigate(`/exercices/${exo.id_code}`);
|
|
show(
|
|
ModalCard,
|
|
{
|
|
exo,
|
|
exos: exerciceStore,
|
|
tags: tagsStore
|
|
},
|
|
() => {
|
|
navigate(-1);
|
|
opened = false;
|
|
}
|
|
);
|
|
};
|
|
</script>
|
|
|
|
<div class="card" on:click={handleClick} on:dblclick={() => {}} on:keypress={() => {}}>
|
|
<h1>{exo.name}</h1>
|
|
<div class="examples">
|
|
{#if exo.examples != null}
|
|
<h2>Exemples</h2>
|
|
{#if !!exo.consigne}<p data-testid="consigne">{exo.consigne}</p>{/if}
|
|
{#each exo.examples.data.slice(0, 3) as ex}
|
|
<p>{ex.calcul}</p>
|
|
{/each}
|
|
{:else}
|
|
<p>Aucun exemple disponible</p>
|
|
{/if}
|
|
</div>
|
|
{#if !!$isAuth && exo.is_author && exo.original == null }
|
|
<div class="status">
|
|
<PrivacyIndicator color={exo.private == true ? 'red' : 'green'}>
|
|
{exo.private == true ? 'Privé' : 'Public'}</PrivacyIndicator
|
|
>
|
|
</div>
|
|
{:else if !exo.is_author}
|
|
<div class="status">
|
|
<PrivacyIndicator color={'blue'}>
|
|
Par <strong>{exo.author.username}</strong>
|
|
</PrivacyIndicator>
|
|
{#if !!$isAuth}
|
|
<div
|
|
data-testid="copy"
|
|
class="icon"
|
|
on:keydown={() => {}}
|
|
on:click|stopPropagation={() => {
|
|
cloneExo(exo.id_code).then((r) => {
|
|
goto('/exercices/' + r.id_code);
|
|
show(ModalCard, { exo: r }, () => {
|
|
goto('/exercices/user');
|
|
});
|
|
});
|
|
}}
|
|
>
|
|
<MdContentCopy />
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
{:else if exo.is_author && exo.original != null}
|
|
<div class="status">
|
|
<PrivacyIndicator color="blue">Par <strong>{exo.original?.author}</strong></PrivacyIndicator>
|
|
</div>
|
|
{/if}
|
|
<div class="card-hover" />
|
|
{#if !!$isAuth}
|
|
<TagContainer bind:exo />
|
|
{/if}
|
|
<!-- TagContainer Must be directly after card-hover for the hover effect -->
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
@import '../../variables';
|
|
* {
|
|
transition: 0.45s;
|
|
}
|
|
.icon {
|
|
width: 18px;
|
|
height: 18px;
|
|
transition: 0.3s;
|
|
cursor: pointer;
|
|
opacity: 0.7;
|
|
transform: scale(0.9);
|
|
&:hover {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.status {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
margin: 10px;
|
|
z-index: 3;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.examples {
|
|
color: gray;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
margin-bottom: 20px;
|
|
p {
|
|
margin: 10px;
|
|
margin-left: 18px;
|
|
font-size: 0.95em;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
h2 {
|
|
font-size: 0.95em;
|
|
margin: 10px;
|
|
margin-left: 0;
|
|
}
|
|
}
|
|
|
|
.card-hover {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
left: 0;
|
|
bottom: 0;
|
|
z-index: 1;
|
|
border: 1px solid $border;
|
|
+ :global(div) {
|
|
transition: 0.45s;
|
|
}
|
|
&:hover {
|
|
border: 1px solid $primary;
|
|
+ :global(div) {
|
|
border: 1px solid $primary;
|
|
border-top: none;
|
|
}
|
|
}
|
|
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.75);
|
|
}
|
|
|
|
h1 {
|
|
font-size: 1.3em;
|
|
margin: 0;
|
|
position: relative;
|
|
z-index: 2;
|
|
max-width: 88%;
|
|
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
word-wrap: break-word;
|
|
&:hover {
|
|
color: $primary;
|
|
}
|
|
}
|
|
|
|
.card {
|
|
border: 1px solid black;
|
|
padding: 20px;
|
|
cursor: pointer;
|
|
position: relative;
|
|
background-color: $background;
|
|
min-height: 250px;
|
|
max-height: 300px;
|
|
&:hover {
|
|
transform: translateX(10px) translateY(-10px);
|
|
}
|
|
}
|
|
</style>
|