✨ New dashboard done
This commit is contained in:
@@ -18,7 +18,11 @@
|
|||||||
<a
|
<a
|
||||||
{href}
|
{href}
|
||||||
{target}
|
{target}
|
||||||
class="text-black hover:bg-opacity-80 w-full px-4 py-2 leading-5 text-black transition-all duration-200 transform bg-[#B07156] rounded text-center focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 outline-none"
|
{disabled}
|
||||||
|
class:opacity-50={disabled}
|
||||||
|
class:cursor-not-allowed={disabled}
|
||||||
|
class:pointer-events-none={disabled}
|
||||||
|
class="text-black hover:bg-opacity-80 w-full px-4 py-2 leading-5 transition-all duration-200 transform bg-[#B07156] rounded text-center outline-none"
|
||||||
on:click
|
on:click
|
||||||
class:flex
|
class:flex
|
||||||
class:justify-center={flex}
|
class:justify-center={flex}
|
||||||
@@ -29,7 +33,7 @@
|
|||||||
<button
|
<button
|
||||||
{disabled}
|
{disabled}
|
||||||
{type}
|
{type}
|
||||||
class="text-black hover:opacity-80 w-full px-4 py-2 leading-5 text-black transition-all duration-200 transform bg-[#B07156] rounded text-center focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 outline-none"
|
class="text-black hover:opacity-80 w-full px-4 py-2 leading-5 transition-all duration-200 transform bg-[#B07156] rounded text-center focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 outline-none"
|
||||||
on:click
|
on:click
|
||||||
class:flex
|
class:flex
|
||||||
class:justify-center={flex}
|
class:justify-center={flex}
|
||||||
|
|||||||
@@ -169,7 +169,12 @@
|
|||||||
"point_plural": "Points",
|
"point_plural": "Points",
|
||||||
"back": "Back",
|
"back": "Back",
|
||||||
"finish": "Finish",
|
"finish": "Finish",
|
||||||
"normal": "Normal"
|
"normal": "Normal",
|
||||||
|
"selected": "Selected",
|
||||||
|
"select": "Select",
|
||||||
|
"quiz": "Quiz",
|
||||||
|
"quiztivity": "Quiztivity",
|
||||||
|
"next": "Next"
|
||||||
},
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"time_in_seconds": "Time in seconds",
|
"time_in_seconds": "Time in seconds",
|
||||||
@@ -344,5 +349,27 @@
|
|||||||
"old_school_mode": "Old-School",
|
"old_school_mode": "Old-School",
|
||||||
"old_school_mode_description": "Questions and images will be shown on both admins screen and on the screen of the players",
|
"old_school_mode_description": "Questions and images will be shown on both admins screen and on the screen of the players",
|
||||||
"start_game": "Start Game"
|
"start_game": "Start Game"
|
||||||
|
},
|
||||||
|
"quiztivity": {
|
||||||
|
"editor": {
|
||||||
|
"select_page_type": "Select Page Type",
|
||||||
|
"move_left": "Move left",
|
||||||
|
"move_right": "Move right",
|
||||||
|
"title_placeholder": "Enter title here",
|
||||||
|
"add_new": "Add new",
|
||||||
|
"delete": "Delete"
|
||||||
|
},
|
||||||
|
"memory": {
|
||||||
|
"editor": {
|
||||||
|
"add_card": "Add card",
|
||||||
|
"upload_image": "Upload image",
|
||||||
|
"add_pair": "Add pair"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"play": {
|
||||||
|
"memory": {
|
||||||
|
"try_count": "Tries: {{try_count}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,12 @@
|
|||||||
export let type: QuizTivityTypes | undefined;
|
export let type: QuizTivityTypes | undefined;
|
||||||
|
|
||||||
const PageTypes = [
|
const PageTypes = [
|
||||||
{
|
/* {
|
||||||
name: 'Pdf',
|
name: 'Pdf',
|
||||||
description: 'Upload a PDF!',
|
description: 'Upload a PDF!',
|
||||||
type: QuizTivityTypes.PDF,
|
type: QuizTivityTypes.PDF,
|
||||||
svg: undefined
|
svg: undefined
|
||||||
},
|
},*/
|
||||||
{
|
{
|
||||||
name: 'Memory',
|
name: 'Memory',
|
||||||
description: 'Matching Pairs game',
|
description: 'Matching Pairs game',
|
||||||
|
|||||||
@@ -41,7 +41,8 @@
|
|||||||
$: handle_slide_add(selected_type);
|
$: handle_slide_add(selected_type);
|
||||||
|
|
||||||
const delete_slide = () => {
|
const delete_slide = () => {
|
||||||
data.pages.slice(selected_slide, 1);
|
console.log(selected_slide);
|
||||||
|
data.pages.splice(selected_slide, 1);
|
||||||
data.pages = data.pages;
|
data.pages = data.pages;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
// import Spinner from "$lib/Spinner.svelte";
|
// import Spinner from "$lib/Spinner.svelte";
|
||||||
import Fuse from 'fuse.js';
|
import Fuse from 'fuse.js';
|
||||||
import BrownButton from '$lib/components/buttons/brown.svelte';
|
import BrownButton from '$lib/components/buttons/brown.svelte';
|
||||||
|
import type { PageData } from './$types';
|
||||||
|
import { fly } from 'svelte/transition';
|
||||||
|
|
||||||
// import GrayButton from "$lib/components/buttons/gray.svelte";
|
// import GrayButton from "$lib/components/buttons/gray.svelte";
|
||||||
|
|
||||||
@@ -25,60 +27,73 @@
|
|||||||
questions: Question[];
|
questions: Question[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export let data: PageData;
|
||||||
let search_term = '';
|
let search_term = '';
|
||||||
let start_game = null;
|
let start_game = null;
|
||||||
signedIn.set(true);
|
signedIn.set(true);
|
||||||
navbarVisible.set(true);
|
navbarVisible.set(true);
|
||||||
const { t } = getLocalization();
|
const { t } = getLocalization();
|
||||||
|
|
||||||
let quizzes_to_show = [];
|
let items_to_show = [];
|
||||||
let quizzes: Array<any>;
|
let all_items: Array<any>;
|
||||||
let fuse;
|
let fuse;
|
||||||
/* const minisearch = new MiniSearch({
|
|
||||||
fields: ['title', 'description'],
|
|
||||||
idField: 'id',
|
|
||||||
storeFields: ['id']
|
|
||||||
})*/
|
|
||||||
|
|
||||||
let id_to_position_map = {};
|
let id_to_position_map = {};
|
||||||
|
|
||||||
const getData = async (): Promise<Array<QuizData>> => {
|
const getData = async (): Promise<Array<QuizData>> => {
|
||||||
const res = await fetch('/api/v1/quiz/list?page_size=100');
|
items_to_show = [];
|
||||||
quizzes_to_show = await res.json();
|
for (let i = 0; i < data.quizzes.length; i++) {
|
||||||
fuse = new Fuse(quizzes_to_show, {
|
items_to_show.push({ ...data.quizzes[i], type: 'quiz' });
|
||||||
keys: ['title', 'description', 'questions.question'],
|
}
|
||||||
|
for (let i = 0; i < data.quiztivities.length; i++) {
|
||||||
|
items_to_show.push({ ...data.quiztivities[i], type: 'quiztivity' });
|
||||||
|
}
|
||||||
|
fuse = new Fuse(items_to_show, {
|
||||||
|
keys: ['title', 'description', 'questions.title'],
|
||||||
findAllMatches: true
|
findAllMatches: true
|
||||||
});
|
});
|
||||||
quizzes = quizzes_to_show;
|
all_items = items_to_show;
|
||||||
for (let i = 0; i < quizzes.length; i++) {
|
for (let i = 0; i < all_items.length; i++) {
|
||||||
id_to_position_map[quizzes[i].id] = i;
|
id_to_position_map[all_items[i].id] = i;
|
||||||
}
|
}
|
||||||
return quizzes_to_show;
|
return all_items;
|
||||||
};
|
};
|
||||||
|
|
||||||
let suggestions = [];
|
|
||||||
|
|
||||||
const search = () => {
|
const search = () => {
|
||||||
if (search_term === '') {
|
if (search_term === '') {
|
||||||
quizzes_to_show = [];
|
items_to_show = all_items;
|
||||||
quizzes_to_show = quizzes;
|
|
||||||
quizzes_to_show = quizzes_to_show;
|
|
||||||
} else {
|
} else {
|
||||||
const res = fuse.search(search_term);
|
const res = fuse.search(search_term);
|
||||||
console.log(res, 'search_res');
|
console.log(res, 'search_res');
|
||||||
quizzes_to_show = [];
|
items_to_show = [];
|
||||||
for (const quiz_data of res) {
|
for (const quiz_data of res) {
|
||||||
quizzes_to_show.push(quiz_data.item);
|
items_to_show.push(quiz_data.item);
|
||||||
}
|
}
|
||||||
|
|
||||||
quizzes_to_show = quizzes_to_show;
|
items_to_show = items_to_show;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$: {
|
$: {
|
||||||
search_term;
|
search_term;
|
||||||
// console.log(search_term);
|
|
||||||
search();
|
search();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deleteQuiz = async (to_delete: string, type: 'quiz' | 'quiztivity') => {
|
||||||
|
if (!confirm('Do you really want to delete this quiz?')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (type === 'quiz') {
|
||||||
|
await fetch(`/api/v1/quiz/delete/${to_delete}`, {
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await fetch(`/api/v1/quiztivity/${to_delete}`, {
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
let create_button_clicked = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@@ -104,7 +119,19 @@
|
|||||||
Primary
|
Primary
|
||||||
</button>-->
|
</button>-->
|
||||||
<div class="w-full grid lg:grid-cols-4 gap-2 grid-cols-2 px-4">
|
<div class="w-full grid lg:grid-cols-4 gap-2 grid-cols-2 px-4">
|
||||||
<BrownButton href="/create">{$t('words.create')}</BrownButton>
|
{#if create_button_clicked}
|
||||||
|
<div class="flex gap-2" transition:fly={{ y: 10 }}>
|
||||||
|
<BrownButton href="/create">{$t('words.quiz')}</BrownButton>
|
||||||
|
<BrownButton href="/quiztivity/create">{$t('words.quiztivity')}</BrownButton
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<BrownButton
|
||||||
|
on:click={() => {
|
||||||
|
create_button_clicked = true;
|
||||||
|
}}>{$t('words.create')}</BrownButton
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
<BrownButton href="/import">{$t('words.import')}</BrownButton>
|
<BrownButton href="/import">{$t('words.import')}</BrownButton>
|
||||||
<BrownButton href="/results">{$t('words.results')}</BrownButton>
|
<BrownButton href="/results">{$t('words.results')}</BrownButton>
|
||||||
<BrownButton href="/account/settings">
|
<BrownButton href="/account/settings">
|
||||||
@@ -123,8 +150,7 @@
|
|||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
search_term = '';
|
search_term = '';
|
||||||
quizzes_to_show = quizzes;
|
items_to_show = all_items;
|
||||||
suggestions = [];
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -146,7 +172,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-4 mt-4 px-2">
|
<div class="flex flex-col gap-4 mt-4 px-2">
|
||||||
{#each quizzes_to_show as quiz}
|
{#each items_to_show as quiz}
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-2 lg:grid-cols-3 w-full rounded border-[#B07156] border-2 p-2 h-[20vh] overflow-hidden max-h-[20vh]"
|
class="grid grid-cols-2 lg:grid-cols-3 w-full rounded border-[#B07156] border-2 p-2 h-[20vh] overflow-hidden max-h-[20vh]"
|
||||||
>
|
>
|
||||||
@@ -160,18 +186,22 @@
|
|||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="my-auto mx-auto max-h-full">
|
<div class="my-auto mx-auto max-h-full overflow-hidden">
|
||||||
<p class="text-xl text-center">{@html quiz.title}</p>
|
<p class="text-xl text-center">{@html quiz.title}</p>
|
||||||
<p class="text-sm text-center text-clip overflow-hidden">
|
<p class="text-sm text-center text-clip overflow-hidden">
|
||||||
{@html quiz.description}
|
{@html quiz.description ?? ''}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-2 grid-rows-2 ml-auto gap-2 w-fit self-end my-auto"
|
class="grid grid-cols-2 grid-rows-2 ml-auto gap-2 w-fit self-end my-auto"
|
||||||
>
|
>
|
||||||
<BrownButton href="/edit?quiz_id={quiz.id}"
|
<BrownButton
|
||||||
|
href={quiz.type === 'quiz'
|
||||||
|
? `/edit?quiz_id=${quiz.id}`
|
||||||
|
: `/quiztivity/edit?id=${quiz.id}`}
|
||||||
>{$t('words.edit')}</BrownButton
|
>{$t('words.edit')}</BrownButton
|
||||||
>
|
>
|
||||||
|
{#if quiz.type === 'quiz'}
|
||||||
<BrownButton
|
<BrownButton
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
start_game = quiz.id;
|
start_game = quiz.id;
|
||||||
@@ -179,9 +209,15 @@
|
|||||||
>
|
>
|
||||||
{$t('words.start')}
|
{$t('words.start')}
|
||||||
</BrownButton>
|
</BrownButton>
|
||||||
|
{:else}
|
||||||
|
<BrownButton href="/quiztivity/play?id={quiz.id}">
|
||||||
|
{$t('words.play')}
|
||||||
|
</BrownButton>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<BrownButton
|
<BrownButton
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
// deleteQuiz(quiz.id);
|
deleteQuiz(quiz.id, quiz.type);
|
||||||
}}
|
}}
|
||||||
flex={true}
|
flex={true}
|
||||||
>
|
>
|
||||||
@@ -201,7 +237,10 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</BrownButton>
|
</BrownButton>
|
||||||
<BrownButton href="/api/v1/eximport/{quiz.id}" flex={true}
|
<BrownButton
|
||||||
|
href="/api/v1/eximport/{quiz.id}"
|
||||||
|
flex={true}
|
||||||
|
disabled={quiz.type !== 'quiz'}
|
||||||
><!-- heroicons/download -->
|
><!-- heroicons/download -->
|
||||||
<svg
|
<svg
|
||||||
class="w-5 h-5"
|
class="w-5 h-5"
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { PageLoad } from './$types';
|
||||||
|
|
||||||
|
export const load = (async ({ fetch }) => {
|
||||||
|
const quiz_res = await fetch('/api/v1/quiz/list?page_size=100');
|
||||||
|
const quizzes = await quiz_res.json();
|
||||||
|
const quiztivity_res = await fetch('/api/v1/quiztivity/');
|
||||||
|
const quiztivities = await quiztivity_res.json();
|
||||||
|
return {
|
||||||
|
quizzes,
|
||||||
|
quiztivities
|
||||||
|
};
|
||||||
|
}) satisfies PageLoad;
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Data } from '$lib/quiztivity/types';
|
import type { Data } from '$lib/quiztivity/types';
|
||||||
import Editor from '$lib/quiztivity/editor.svelte';
|
import Editor from '$lib/quiztivity/editor.svelte';
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
let data: Data = { pages: [], id: undefined, title: '' };
|
let data: Data = { pages: [], id: undefined, title: '' };
|
||||||
let saving = false;
|
let saving = false;
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
body: stringification
|
body: stringification
|
||||||
});
|
});
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
// await goto("/dashboard")
|
await goto('/dashboard');
|
||||||
} else {
|
} else {
|
||||||
alert("Couldn't save");
|
alert("Couldn't save");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
import Editor from '../../../lib/quiztivity/editor.svelte';
|
import Editor from '../../../lib/quiztivity/editor.svelte';
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@
|
|||||||
body: stringification
|
body: stringification
|
||||||
});
|
});
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
// await goto("/dashboard")
|
await goto('/dashboard');
|
||||||
} else {
|
} else {
|
||||||
alert("Couldn't save");
|
alert("Couldn't save");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user