Added ABCD-Question to Quiztivities

This commit is contained in:
Mawoka
2023-06-15 18:42:39 +02:00
parent 3cfd51e1cf
commit 2076e7cffb
10 changed files with 187 additions and 10 deletions
+13 -1
View File
@@ -23,21 +23,33 @@ class Markdown(BaseModel):
markdown: str
class _AbcdAnswer(BaseModel):
answer: str
correct: bool
class Abcd(BaseModel):
question: str
answers: list[_AbcdAnswer]
class QuizTivityTypes(str, enum.Enum):
SLIDE = "SLIDE"
PDF = "PDF"
MEMORY = "MEMORY"
MARKDOWN = "MARKDOWN"
ABCD = "ABCD"
TYPE_CLASS_LIST = {
QuizTivityTypes.PDF: type(Pdf),
QuizTivityTypes.MEMORY: type(Memory),
QuizTivityTypes.MARKDOWN: type(Markdown),
QuizTivityTypes.ABCD: type(Abcd),
}
class QuizTivityPage(BaseModel):
title: str | None
type: QuizTivityTypes
data: Pdf | Memory | Markdown
data: Pdf | Memory | Markdown | Abcd
+3
View File
@@ -77,6 +77,9 @@ async def get_share(uuid: UUID) -> QuizTivity:
share = await QuizTivityShare.objects.select_related("quiztivity").get_or_none(id=uuid)
if share is None:
raise HTTPException(status_code=404, detail="Share not found")
print(share.quiztivity)
if share.expire_at is None:
return share.quiztivity
if share.expire_at < datetime.now():
raise HTTPException(status_code=410, detail="Already expired")
return share.quiztivity
@@ -22,8 +22,8 @@
role="alert"
>
<div class="ml-3 text-sm font-normal">
{#if type === PopoverTypes.Copy}{$t('components.popover.copied_to_clipboard')}Copied
to clipboard!
{#if type === PopoverTypes.Copy}
{$t('components.popover.copied_to_clipboard')}
{:else if type === PopoverTypes.GameInLobby}A game is currently in the lobby. Click <a
class="underline"
href="/remote?game_pin={data.game_pin}&game_id={data.game_id}">here</a
@@ -29,6 +29,12 @@
description: 'Add content in Markdown format!',
type: QuizTivityTypes.MARKDOWN,
svg: undefined
},
{
name: 'Multiple Choice',
description: 'Multiple Choice Quiz',
type: QuizTivityTypes.ABCD,
svg: undefined
}
];
</script>
@@ -0,0 +1,90 @@
<!--
- 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/.
-->
<script lang="ts">
import type { Abcd } from '$lib/quiztivity/types';
import { getLocalization } from '$lib/i18n';
import BrownButton from '$lib/components/buttons/brown.svelte';
export let data: Abcd | undefined;
if (!data) {
data = {
question: '',
answers: []
};
}
const { t } = getLocalization();
</script>
<div>
<div class="flex justify-center">
<input
class="bg-transparent outline-none text-3xl text-center"
placeholder="Enter question here..."
bind:value={data.question}
/>
</div>
<div class="grid grid-cols-2 m-4 gap-4">
{#each data.answers as answer}
<div class="rounded p-6 bg-gray-700 flex">
<input
bind:value={answer.answer}
class="w-full my-auto bg-transparent outline-none text-center"
placeholder="Enter answer here"
/>
<button
type="button"
on:click={() => {
answer.correct = !answer.correct;
}}
>
{#if answer.correct}
<svg
class="w-6 h-6 inline-block"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
{:else}
<svg
class="w-6 h-6 inline-block"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
{/if}
</button>
</div>
{/each}
{#if data.answers.length < 4}
<div class="rounded p-6 bg-gray-700">
<BrownButton
on:click={() => {
data.answers = [...data.answers, { ...{ answer: '', correct: false } }];
}}>{$t('editor_page.add_an_answer')}</BrownButton
>
</div>
{/if}
</div>
</div>
@@ -0,0 +1,37 @@
<!--
- 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/.
-->
<script lang="ts">
import type { Abcd } from '$lib/quiztivity/types';
export let data: Abcd | undefined;
let selected_answer: number | undefined;
const select_answer = (i: number) => {
selected_answer = i;
console.log(data);
};
</script>
<div>
<h1 class="text-center text-4xl">{data.question}</h1>
<div class="grid grid-cols-1 lg:grid-cols-2 m-4 gap-4">
{#each data.answers as answer, i}
<button
class="rounded p-6 bg-gray-700 flex transition-all"
on:click={() => {
select_answer(i);
}}
class:opacity-50={selected_answer !== undefined && !answer.correct}
class:text-2xl={selected_answer === i}
>
<span class="m-auto">{answer.answer}</span>
</button>
{/each}
</div>
</div>
@@ -12,6 +12,7 @@
import PdfEdit from './components/pdf/edit.svelte';
import MemoryEdit from './components/memory/edit.svelte';
import MarkdownEdit from './components/markdown/edit.svelte';
import AbcdEdit from './components/abcd/edit.svelte';
import { flip } from 'svelte/animate';
import { createEventDispatcher } from 'svelte';
import SharesPopover from '$lib/quiztivity/shares_popover.svelte';
@@ -46,6 +47,7 @@
console.log(selected_slide);
data.pages.splice(selected_slide, 1);
data.pages = data.pages;
selected_slide = null;
};
const arraymove = (arr: any[], fromI: number, toI: number) => {
@@ -164,6 +166,8 @@
<MemoryEdit bind:data={data.pages[opened_slide].data} />
{:else if sel_t === QuizTivityTypes.MARKDOWN}
<MarkdownEdit bind:data={data.pages[opened_slide].data} />
{:else if sel_t === QuizTivityTypes.ABCD}
<AbcdEdit bind:data={data.pages[opened_slide].data} />
{:else}
<h1 class="text-8xl">ERROR!</h1>
{/if}
@@ -103,6 +103,19 @@
await fetch(`/api/v1/quiztivity/shares/${id}`, { method: 'DELETE' });
loaded_shares = load_shares();
};
const share_available = (): boolean => {
try {
return browser
? !navigator.canShare({
title: 'title',
url: `${window.location.origin}/quiztivity`
})
: false;
} catch {
return false;
}
};
let add_shares_open = false;
</script>
@@ -154,12 +167,7 @@
<div class="w-full mx-auto">
<BrownButton
flex={true}
disabled={browser
? !navigator.canShare({
title: 'title',
url: `${window.location.origin}/quiztivity`
})
: false}
disabled={share_available()}
on:click={() => {
navigator.share({
title: 'Quiztivity on ClassQuiz',
+14 -1
View File
@@ -12,7 +12,9 @@ export enum QuizTivityTypes {
// eslint-disable-next-line no-unused-vars
MEMORY = 'MEMORY',
// eslint-disable-next-line no-unused-vars
MARKDOWN = 'MARKDOWN'
MARKDOWN = 'MARKDOWN',
// eslint-disable-next-line no-unused-vars
ABCD = 'ABCD'
}
export interface Pdf {
@@ -32,6 +34,17 @@ export interface Memory {
export interface Markdown {
markdown: string;
}
export interface AbcdAnswer {
answer: string;
correct: boolean;
}
export interface Abcd {
question: string;
answers: AbcdAnswer[];
}
export interface QuizTivityPage {
title?: string;
type: QuizTivityTypes;
@@ -32,6 +32,10 @@
{#await import('$lib/quiztivity/components/memory/play.svelte') then c}
<svelte:component this={c.default} data={current_slide.data} />
{/await}
{:else if current_slide.type === QuizTivityTypes.ABCD}
{#await import('$lib/quiztivity/components/abcd/play.svelte') then c}
<svelte:component this={c.default} data={current_slide.data} />
{/await}
{/if}
</div>
<NavigationBar bind:current_slide_index question_count={quiztivity.pages.length} />