ui: Use Masonry layout to present themes and exercices on home page
This commit is contained in:
parent
13a11269a8
commit
5e48ab0928
38
frontend/fic/package-lock.json
generated
38
frontend/fic/package-lock.json
generated
@ -14,6 +14,7 @@
|
||||
"bootswatch": "^5.1.3",
|
||||
"hash-wasm": "^4.9.0",
|
||||
"seedrandom": "^3.0.5",
|
||||
"svelte-bricks": "^0.2.1",
|
||||
"vite": "^5.0.0",
|
||||
"wordcloud": "^1.2.2"
|
||||
},
|
||||
@ -46,7 +47,6 @@
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
|
||||
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
@ -516,7 +516,6 @@
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
|
||||
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
@ -530,7 +529,6 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
@ -539,7 +537,6 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
|
||||
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
@ -547,14 +544,12 @@
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.15",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
|
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.25",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
|
||||
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
@ -880,8 +875,7 @@
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
|
||||
},
|
||||
"node_modules/@ungap/structured-clone": {
|
||||
"version": "1.2.0",
|
||||
@ -893,7 +887,6 @@
|
||||
"version": "8.11.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@ -973,7 +966,6 @@
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
||||
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
}
|
||||
@ -982,7 +974,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz",
|
||||
"integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
}
|
||||
@ -1127,7 +1118,6 @@
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz",
|
||||
"integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15",
|
||||
"@types/estree": "^1.0.1",
|
||||
@ -1187,7 +1177,6 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
|
||||
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mdn-data": "2.0.30",
|
||||
"source-map-js": "^1.0.1"
|
||||
@ -1244,7 +1233,6 @@
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@ -1519,7 +1507,6 @@
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0"
|
||||
}
|
||||
@ -1840,7 +1827,6 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz",
|
||||
"integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "*"
|
||||
}
|
||||
@ -1930,8 +1916,7 @@
|
||||
"node_modules/locate-character": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
|
||||
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="
|
||||
},
|
||||
"node_modules/locate-path": {
|
||||
"version": "6.0.0",
|
||||
@ -1970,7 +1955,6 @@
|
||||
"version": "0.30.8",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
|
||||
"integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||
},
|
||||
@ -1981,8 +1965,7 @@
|
||||
"node_modules/mdn-data": {
|
||||
"version": "2.0.30",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
||||
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
@ -2158,7 +2141,6 @@
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz",
|
||||
"integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^3.0.0",
|
||||
@ -2593,7 +2575,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -2638,7 +2619,6 @@
|
||||
"version": "4.2.12",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz",
|
||||
"integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15",
|
||||
@ -2659,6 +2639,14 @@
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-bricks": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/svelte-bricks/-/svelte-bricks-0.2.1.tgz",
|
||||
"integrity": "sha512-cc3XK3j5ViPyZ3K183+Sr53B2e8mJaiV3POyoJtjmm1dYc/TBMy7jOUMt8MW/snJzodpACfqwFzokBQbrZ297w==",
|
||||
"dependencies": {
|
||||
"svelte": "^4.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-eslint-parser": {
|
||||
"version": "0.33.1",
|
||||
"resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz",
|
||||
|
@ -31,6 +31,7 @@
|
||||
"bootswatch": "^5.1.3",
|
||||
"hash-wasm": "^4.9.0",
|
||||
"seedrandom": "^3.0.5",
|
||||
"svelte-bricks": "^0.2.1",
|
||||
"vite": "^5.0.0",
|
||||
"wordcloud": "^1.2.2"
|
||||
}
|
||||
|
@ -17,13 +17,18 @@
|
||||
export { className as class };
|
||||
export let theme = {};
|
||||
export let exercice = null;
|
||||
export let style = '';
|
||||
export let color = !exercice ? "dark" : "light";
|
||||
let className = '';
|
||||
|
||||
let textColor = "light";
|
||||
$: textColor = color === "dark" ? "light" : "dark";
|
||||
</script>
|
||||
|
||||
<div class="theme-card h-100">
|
||||
<div class="theme-card" {style}>
|
||||
<Card
|
||||
class="text-light h-100 rounded-3 niceborder {className}"
|
||||
color="dark"
|
||||
class="text-{textColor} rounded-3 niceborder {className}"
|
||||
{color}
|
||||
on:click
|
||||
>
|
||||
{#if exercice && exercice.image}
|
||||
@ -95,8 +100,4 @@
|
||||
.theme-card .card-img-top {
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #ccc;
|
||||
}
|
||||
</style>
|
||||
|
@ -12,15 +12,41 @@
|
||||
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
import Masonry from 'svelte-bricks';
|
||||
|
||||
import CardTheme from '$lib/components/CardTheme.svelte';
|
||||
|
||||
import { my } from '$lib/stores/my.js';
|
||||
import { teams } from '$lib/stores/teams.js';
|
||||
import { myThemes, themes } from '$lib/stores/mythemes.js';
|
||||
import { settings } from '$lib/stores/settings.js';
|
||||
import { themesStore } from '$lib/stores/themes.js';
|
||||
|
||||
let items = [];
|
||||
$: {
|
||||
const tmpitems = [];
|
||||
for (const th of $themes) {
|
||||
if (th.id == 0) continue;
|
||||
|
||||
tmpitems.push({id: th.id, theme: th});
|
||||
}
|
||||
|
||||
if ($themesStore["0"] && !$themesStore["0"].locked && $themesStore["0"].exercices) {
|
||||
let i = 1;
|
||||
for (let j = $themesStore["0"].exercices.length - 1; j >= 0 && i < tmpitems.length; j--) {
|
||||
if ($my && $my.team_id && !$my.exercices[$themesStore["0"].exercices[j].id])
|
||||
continue;
|
||||
|
||||
tmpitems.splice(i, 0, {id: tmpitems.length, theme: $themesStore["0"], exercice: $themesStore["0"].exercices[j]});
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
items = tmpitems;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Container class="mt-3">
|
||||
<Container class="mt-3 mb-5">
|
||||
{#if !$my}
|
||||
{#if $settings.allowRegistration}
|
||||
<Alert color="warning" class="text-justify" fade={false}>
|
||||
@ -48,15 +74,27 @@
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<Row cols={{ lg: 3, md: 2, sm: 1 }}>
|
||||
{#each $themes as th, index}
|
||||
<Col class="mb-3">
|
||||
|
||||
<Masonry
|
||||
{items}
|
||||
let:item
|
||||
>
|
||||
{#if item.exercice}
|
||||
{@const theme = item.theme}
|
||||
{@const exercice = item.exercice}
|
||||
<CardTheme
|
||||
class="{$my && $my.team_id && exercice.solved?'border-light ':''}{exercice.curcoeff > 1?'border-success ':''}{theme.locked || exercice.disabled?' border-secondary ':''}"
|
||||
{theme}
|
||||
{exercice}
|
||||
on:click={goto(`${theme.urlid}/${exercice.urlid}`)}
|
||||
/>
|
||||
{:else}
|
||||
{@const th = item.theme}
|
||||
<CardTheme
|
||||
class="{$my && $my.team_id && $myThemes[th.id].exercice_solved > 0?'border-light ':''}{th.exercice_coeff_max > 1?'border-success ':''}{th.locked?' border-secondary ':''}"
|
||||
theme={th}
|
||||
on:click={goto(`${th.urlid}`)}
|
||||
/>
|
||||
</Col>
|
||||
{/each}
|
||||
</Row>
|
||||
{/if}
|
||||
</Masonry>
|
||||
</Container>
|
||||
|
@ -12,6 +12,9 @@
|
||||
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
import Masonry from 'svelte-bricks';
|
||||
|
||||
import CardTheme from '$lib/components/CardTheme.svelte';
|
||||
import { current_theme } from '$lib/stores/themes';
|
||||
import { set_current_exercice } from '$lib/stores/exercices';
|
||||
import { my } from '$lib/stores/my.js';
|
||||
@ -19,6 +22,21 @@
|
||||
set_current_exercice.set(null);
|
||||
</script>
|
||||
|
||||
{#if $current_theme.id == 0}
|
||||
<Masonry
|
||||
class="mb-5"
|
||||
items={$current_theme.exercices}
|
||||
let:item={exercice}
|
||||
>
|
||||
<CardTheme
|
||||
style="min-width: max(30vw,300px); width: max(30vw,300px)"
|
||||
class="item {$my && $my.team_id && exercice.solved?'border-light ':''}{exercice.curcoeff > 1?'border-success ':''}{$current_theme.locked || exercice.disabled?' border-secondary ':''}"
|
||||
theme={$current_theme}
|
||||
{exercice}
|
||||
on:click={goto(`${$current_theme.urlid}/${exercice.urlid}`)}
|
||||
/>
|
||||
</Masonry>
|
||||
{:else}
|
||||
<Card class="bg-dark niceborder text-indent mt-2 mb-4">
|
||||
|
||||
<Row>
|
||||
@ -142,6 +160,7 @@
|
||||
</Row>
|
||||
|
||||
</Card>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.list-group-item-action {
|
||||
|
Loading…
x
Reference in New Issue
Block a user