diff --git a/classquiz/routers/quiztivity.py b/classquiz/routers/quiztivity.py index 7b694da..e725909 100644 --- a/classquiz/routers/quiztivity.py +++ b/classquiz/routers/quiztivity.py @@ -42,3 +42,9 @@ async def delete_quiztivity(uuid: UUID): if quiztivity is None: raise HTTPException(status_code=404, detail="QuizTivity not found") await quiztivity.delete() + + +@router.get("/") +async def get_all_quiztivities(user: User = Depends(get_current_user)) -> list[QuizTivity]: + quiztivities = await QuizTivity.objects.filter(user=user).order_by(QuizTivity.created_at.desc()).all() + return quiztivities diff --git a/frontend/package.json b/frontend/package.json index 3525fcd..cf535b5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -33,6 +33,7 @@ "@tailwindcss/typography": "^0.5.9", "@types/canvas-confetti": "^1.6.0", "@types/cookie": "^0.5.1", + "@types/dompurify": "^3.0.2", "@types/js-cookie": "^3.0.3", "@types/luxon": "^3.3.0", "@types/marked": "^4.3.0", @@ -56,6 +57,7 @@ "cookie": "^0.5.0", "crypto-js": "^4.1.1", "cssnano": "^6.0.0", + "dompurify": "^3.0.3", "eslint": "^8.38.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-svelte3": "^4.0.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index eec0f6b..797eb29 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -20,6 +20,7 @@ specifiers: '@tailwindcss/typography': ^0.5.9 '@types/canvas-confetti': ^1.6.0 '@types/cookie': ^0.5.1 + '@types/dompurify': ^3.0.2 '@types/js-cookie': ^3.0.3 '@types/luxon': ^3.3.0 '@types/marked': ^4.3.0 @@ -43,6 +44,7 @@ specifiers: cookie: ^0.5.0 crypto-js: ^4.1.1 cssnano: ^6.0.0 + dompurify: ^3.0.3 eslint: ^8.38.0 eslint-config-prettier: ^8.8.0 eslint-plugin-svelte3: ^4.0.0 @@ -106,6 +108,7 @@ devDependencies: '@tailwindcss/typography': 0.5.9_tailwindcss@3.3.1 '@types/canvas-confetti': 1.6.0 '@types/cookie': 0.5.1 + '@types/dompurify': 3.0.2 '@types/js-cookie': 3.0.3 '@types/luxon': 3.3.0 '@types/marked': 4.3.0 @@ -129,6 +132,7 @@ devDependencies: cookie: 0.5.0 crypto-js: 4.1.1 cssnano: 6.0.0_postcss@8.4.22 + dompurify: 3.0.3 eslint: 8.38.0 eslint-config-prettier: 8.8.0_eslint@8.38.0 eslint-plugin-svelte3: 4.0.0_a4ckjr7darsrglbip3svgxgxc4 @@ -1438,6 +1442,15 @@ packages: } dev: true + /@types/dompurify/3.0.2: + resolution: + { + integrity: sha512-YBL4ziFebbbfQfH5mlC+QTJsvh0oJUrWbmxKMyEdL7emlHJqGR2Qb34TEFKj+VCayBvjKy3xczMFNhugThUsfQ== + } + dependencies: + '@types/trusted-types': 2.0.3 + dev: true + /@types/estree/1.0.1: resolution: { @@ -1517,6 +1530,13 @@ packages: } dev: true + /@types/trusted-types/2.0.3: + resolution: + { + integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== + } + dev: true + /@types/ua-parser-js/0.7.36: resolution: { @@ -2620,6 +2640,13 @@ packages: domelementtype: 2.3.0 dev: true + /dompurify/3.0.3: + resolution: + { + integrity: sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ== + } + dev: true + /domutils/3.0.1: resolution: { diff --git a/frontend/src/lib/quiztivity/components/markdown/edit.svelte b/frontend/src/lib/quiztivity/components/markdown/edit.svelte index b94ce1f..6128518 100644 --- a/frontend/src/lib/quiztivity/components/markdown/edit.svelte +++ b/frontend/src/lib/quiztivity/components/markdown/edit.svelte @@ -5,13 +5,9 @@ --> + +
+ {@html rendered_html} +
diff --git a/frontend/src/lib/quiztivity/components/memory/edit.svelte b/frontend/src/lib/quiztivity/components/memory/edit.svelte index bc16121..e9405e6 100644 --- a/frontend/src/lib/quiztivity/components/memory/edit.svelte +++ b/frontend/src/lib/quiztivity/components/memory/edit.svelte @@ -7,6 +7,7 @@ import type { Memory } from '../../types'; import { getLocalization } from '$lib/i18n'; import BrownButton from '$lib/components/buttons/brown.svelte'; + import { flip } from 'svelte/animate'; const { t } = getLocalization(); @@ -21,6 +22,20 @@ cards: [] }; } + const arraymove = (arr: any[], fromI: number, toI: number) => { + const el = arr[fromI]; + arr.splice(fromI, 1); + arr.splice(toI, 0, el); + }; + const move_card_left = (selected_slide: number) => { + arraymove(data.cards, selected_slide, selected_slide - 1); + data.cards = data.cards; + }; + + const move_card_right = (selected_slide: number) => { + arraymove(data.cards, selected_slide, selected_slide + 1); + data.cards = data.cards; + }; const add_card = () => { if (!new_pair_data.text_1 || !new_pair_data.text_2) { @@ -81,8 +96,11 @@ > - {#each data.cards as card_pair} -
+ {#each data.cards as card_pair, i (card_pair[0].id)} +
{#each card_pair as card}
@@ -90,6 +108,21 @@
{/each}
+
+ { + move_card_left(i); + }} + disabled={i === 0}>{$t('quiztivity.editor.move_left')} + { + move_card_right(i); + }} + disabled={i + 1 === data.cards.length} + >{$t('quiztivity.editor.move_right')} +
{/each}
diff --git a/frontend/src/lib/quiztivity/components/memory/play.svelte b/frontend/src/lib/quiztivity/components/memory/play.svelte new file mode 100644 index 0000000..a45c675 --- /dev/null +++ b/frontend/src/lib/quiztivity/components/memory/play.svelte @@ -0,0 +1,101 @@ + + + +
+

{$t('quiztivity.play.memory.try_count', { try_count })}

+
+ {#each random_card_order as card} + + {/each} +
+
diff --git a/frontend/src/lib/quiztivity/editor.svelte b/frontend/src/lib/quiztivity/editor.svelte index bb20167..dc94952 100644 --- a/frontend/src/lib/quiztivity/editor.svelte +++ b/frontend/src/lib/quiztivity/editor.svelte @@ -109,7 +109,7 @@
-
+
{#each data.pages as page, i (page.id)}
+ +
+
+ {#if current_slide.type === QuizTivityTypes.MARKDOWN} + {#await import('$lib/quiztivity/components/markdown/play.svelte') then c} + + {/await} + {:else if current_slide.type === QuizTivityTypes.MEMORY} + {#await import('$lib/quiztivity/components/memory/play.svelte') then c} + + {/await} + {/if} +
+ +
diff --git a/frontend/src/routes/quiztivity/play/+page.ts b/frontend/src/routes/quiztivity/play/+page.ts new file mode 100644 index 0000000..be54a5d --- /dev/null +++ b/frontend/src/routes/quiztivity/play/+page.ts @@ -0,0 +1,24 @@ +/* + * 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'; +import { error } from '@sveltejs/kit'; +import type { Data } from '$lib/quiztivity/types'; + +export const load = (async ({ url, fetch }) => { + const id = url.searchParams.get('id'); + if (!id) { + throw error(400, 'id missing'); + } + const resp = await fetch(`/api/v1/quiztivity/${id}`); + if (!resp.ok) { + throw error(404, 'quiztivity not found'); + } + const data: Data = await resp.json(); + return { + quiztivity: data + }; +}) satisfies PageLoad; diff --git a/frontend/src/routes/quiztivity/play/navigation_bar.svelte b/frontend/src/routes/quiztivity/play/navigation_bar.svelte new file mode 100644 index 0000000..abe6c9d --- /dev/null +++ b/frontend/src/routes/quiztivity/play/navigation_bar.svelte @@ -0,0 +1,36 @@ + + + +
+
+ { + current_slide_index -= 1; + }}>{$t('words.back')} +
+
+ {current_slide_index + 1}/{question_count} +
+
+ { + current_slide_index += 1; + }}>{$t('words.next')} +
+