From 10fd96ae5ee150d11221d5703abb104c0bdf9d28 Mon Sep 17 00:00:00 2001 From: Brieuc Dubois <git@bhasher.com> Date: Fri, 11 Apr 2025 09:46:09 +0200 Subject: [PATCH] WIP questions --- .../admin/tests/groups/questions/+page.svelte | 44 +++++++++++++++++++ .../admin/tests/groups/questions/+page.ts | 12 +++++ .../groups/questions/[id]/+page.server.ts | 42 ++++++++++++++++++ .../tests/groups/questions/[id]/+page.svelte | 9 ++++ .../tests/groups/questions/[id]/+page.ts | 31 +++++++++++++ .../groups/questions/new/+page.server.ts | 33 ++++++++++++++ .../tests/groups/questions/new/+page.svelte | 7 +++ .../admin/tests/groups/questions/new/+page.ts | 10 +++++ 8 files changed, 188 insertions(+) create mode 100644 frontend/src/routes/admin/tests/groups/questions/+page.svelte create mode 100644 frontend/src/routes/admin/tests/groups/questions/+page.ts create mode 100644 frontend/src/routes/admin/tests/groups/questions/[id]/+page.server.ts create mode 100644 frontend/src/routes/admin/tests/groups/questions/[id]/+page.svelte create mode 100644 frontend/src/routes/admin/tests/groups/questions/[id]/+page.ts create mode 100644 frontend/src/routes/admin/tests/groups/questions/new/+page.server.ts create mode 100644 frontend/src/routes/admin/tests/groups/questions/new/+page.svelte create mode 100644 frontend/src/routes/admin/tests/groups/questions/new/+page.ts diff --git a/frontend/src/routes/admin/tests/groups/questions/+page.svelte b/frontend/src/routes/admin/tests/groups/questions/+page.svelte new file mode 100644 index 0000000..eaf8322 --- /dev/null +++ b/frontend/src/routes/admin/tests/groups/questions/+page.svelte @@ -0,0 +1,44 @@ +<script lang="ts"> + import { t } from '$lib/services/i18n'; + import type { PageData } from './$types'; + import type TestTaskGroup from '$lib/types/testTaskGroups'; + + const { data }: { data: PageData } = $props(); + + let groups: TestTaskGroup[] = $state(data.groups); +</script> + +<h1 class="text-xl font-bold m-5 text-center">{$t('header.admin.groups')}</h1> + +<table class="table max-w-5xl mx-auto text-left"> + <thead> + <tr> + <th>#</th> + <th>{$t('utils.words.title')}</th> + <th>{$t('utils.words.demo')}</th> + <th>{$t('utils.words.randomize')}</th> + <th class="capitalize"># {$t('utils.words.questions')}</th> + </tr> + </thead> + <tbody> + {#each groups as group (group.id)} + <tr + class="hover:bg-gray-100 hover:cursor-pointer" + onclick={() => (window.location.href = `/admin/tests/groups/${group.id}`)} + > + <td>{group.id}</td> + <td>{group.title}</td> + <td>{$t(`utils.bool.${group.demo}`)}</td> + <td>{$t(`utils.bool.${group.randomize}`)}</td> + <td>{group.questions.length}</td> + </tr> + {/each} + </tbody> +</table> +<div class="mt-8 mx-auto w-[64rem] flex justify-between pb-8"> + <a class="button" href="/admin/tests/groups/new">{$t('tests.groups.create')}</a> + <span> + <a class="btn" href="/admin/tests">⎠{$t('tests.groups.backtotests')}</a> + <a class="btn" href="/admin/tests/groups/questions">{$t('tests.questions.manage')}</a> + </span> +</div> diff --git a/frontend/src/routes/admin/tests/groups/questions/+page.ts b/frontend/src/routes/admin/tests/groups/questions/+page.ts new file mode 100644 index 0000000..d1d208c --- /dev/null +++ b/frontend/src/routes/admin/tests/groups/questions/+page.ts @@ -0,0 +1,12 @@ +import { getTestQuestionsAPI } from '$lib/api/tests'; +import { type Load } from '@sveltejs/kit'; +import { TestTaskQuestion } from '$lib/types/testTaskQuestions'; + +export const load: Load = async ({ fetch }) => { + const questionsRaw = await getTestQuestionsAPI(fetch); + const questions = TestTaskQuestion.parseAll(questionsRaw); + + return { + questions + }; +}; diff --git a/frontend/src/routes/admin/tests/groups/questions/[id]/+page.server.ts b/frontend/src/routes/admin/tests/groups/questions/[id]/+page.server.ts new file mode 100644 index 0000000..ec22d98 --- /dev/null +++ b/frontend/src/routes/admin/tests/groups/questions/[id]/+page.server.ts @@ -0,0 +1,42 @@ +import { redirect, type Actions } from '@sveltejs/kit'; +import { updateTestTaskGroupAPI } from '$lib/api/tests'; + +export const actions: Actions = { + default: async ({ request, fetch }) => { + const formData = await request.formData(); + + const idStr = formData.get('id')?.toString(); + const title = formData.get('title')?.toString(); + const demo = formData.get('demo')?.toString() == 'on'; + const randomize = formData.get('randomize')?.toString() == 'on'; + + if (!idStr || !title) { + return { + message: 'Invalid request: Missing required fields' + }; + } + + const id = parseInt(idStr, 10); + + if (isNaN(id)) { + return { + message: 'Invalid request: Invalid ID' + }; + } + + const questions = formData + .getAll('questions[]') + .map((question) => parseInt(question.toString(), 10)) + .filter((question) => !isNaN(question)); + + const ok = await updateTestTaskGroupAPI(fetch, id, title, demo, randomize, questions); + + if (!ok) { + return { + message: 'Error updating test task group' + }; + } + + return redirect(303, `/admin/tests/groups`); + } +}; diff --git a/frontend/src/routes/admin/tests/groups/questions/[id]/+page.svelte b/frontend/src/routes/admin/tests/groups/questions/[id]/+page.svelte new file mode 100644 index 0000000..f2e0a43 --- /dev/null +++ b/frontend/src/routes/admin/tests/groups/questions/[id]/+page.svelte @@ -0,0 +1,9 @@ +<script lang="ts"> + import GroupForm from '$lib/components/tests/GroupForm.svelte'; + import type { PageData } from './$types'; + + const { data, form }: { data: PageData; form: FormData } = $props(); + const { group, possibleQuestions } = data; +</script> + +<GroupForm {group} {possibleQuestions} message={form?.message} /> diff --git a/frontend/src/routes/admin/tests/groups/questions/[id]/+page.ts b/frontend/src/routes/admin/tests/groups/questions/[id]/+page.ts new file mode 100644 index 0000000..e33e6f8 --- /dev/null +++ b/frontend/src/routes/admin/tests/groups/questions/[id]/+page.ts @@ -0,0 +1,31 @@ +import { getTestQuestionsAPI, getTestTaskGroupAPI } from '$lib/api/tests'; +import TestTaskGroup from '$lib/types/testTaskGroups'; +import { TestTaskQuestion } from '$lib/types/testTaskQuestions'; +import { error, type Load } from '@sveltejs/kit'; + +export const load: Load = async ({ fetch, params }) => { + const idStr = params?.id; + + if (!idStr) { + return error(400, 'Invalid ID'); + } + + const id = parseInt(idStr, 10); + + if (isNaN(id)) { + return error(400, 'Invalid ID'); + } + + const groupRaw = await getTestTaskGroupAPI(fetch, id); + + if (!groupRaw) { + return error(404, 'Group not found'); + } + + const group = TestTaskGroup.parse(groupRaw); + + const questionsRaw = await getTestQuestionsAPI(fetch); + const questions = TestTaskQuestion.parseAll(questionsRaw); + + return { group, possibleQuestions: questions }; +}; diff --git a/frontend/src/routes/admin/tests/groups/questions/new/+page.server.ts b/frontend/src/routes/admin/tests/groups/questions/new/+page.server.ts new file mode 100644 index 0000000..fd54c87 --- /dev/null +++ b/frontend/src/routes/admin/tests/groups/questions/new/+page.server.ts @@ -0,0 +1,33 @@ +import { redirect, type Actions } from '@sveltejs/kit'; +import { createTestTaskGroupAPI } from '$lib/api/tests'; + +export const actions: Actions = { + default: async ({ request, fetch }) => { + const formData = await request.formData(); + + const title = formData.get('title')?.toString(); + const demo = formData.get('demo')?.toString() == 'on'; + const randomize = formData.get('randomize')?.toString() == 'on'; + + if (!title) { + return { + message: 'Invalid request: Missing required fields' + }; + } + + const questions = formData + .getAll('questions[]') + .map((question) => parseInt(question.toString(), 10)) + .filter((question) => !isNaN(question)); + + const id = await createTestTaskGroupAPI(fetch, title, demo, randomize, questions); + + if (id === null) { + return { + message: 'Error creating test task group' + }; + } + + return redirect(303, `/admin/tests/groups`); + } +}; diff --git a/frontend/src/routes/admin/tests/groups/questions/new/+page.svelte b/frontend/src/routes/admin/tests/groups/questions/new/+page.svelte new file mode 100644 index 0000000..4c3987e --- /dev/null +++ b/frontend/src/routes/admin/tests/groups/questions/new/+page.svelte @@ -0,0 +1,7 @@ +<script lang="ts"> + import GroupForm from '$lib/components/tests/GroupForm.svelte'; + const { data, form }: { data: PageData; form: FormData } = $props(); + const { possibleQuestions } = data; +</script> + +<GroupForm group={null} {possibleQuestions} message={form?.message} /> diff --git a/frontend/src/routes/admin/tests/groups/questions/new/+page.ts b/frontend/src/routes/admin/tests/groups/questions/new/+page.ts new file mode 100644 index 0000000..fcf5f18 --- /dev/null +++ b/frontend/src/routes/admin/tests/groups/questions/new/+page.ts @@ -0,0 +1,10 @@ +import { getTestQuestionsAPI } from '$lib/api/tests'; +import { TestTaskQuestion } from '$lib/types/testTaskQuestions'; +import { type Load } from '@sveltejs/kit'; + +export const load: Load = async ({ fetch }) => { + const questionsRaw = await getTestQuestionsAPI(fetch); + const questions = TestTaskQuestion.parseAll(questionsRaw); + + return { possibleQuestions: questions }; +}; -- GitLab