daisyui, categories, check examstore at middleware, remove 7.css

This commit is contained in:
NetMan 2025-03-08 14:14:19 +01:00
parent 3c5511f067
commit 652550a41d
23 changed files with 296 additions and 303 deletions

22
app.vue
View file

@ -1,23 +1,9 @@
<script setup lang="ts">
import "~/assets/css/main.css";
</script>
<template>
<div>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</div>
</template>
<style>
.set-translate {
@apply absolute top-[50%] left-[50%];
transform: translate(-50%, -50%);
}
/* .page-enter-active,
.page-leave-active {
transition: all 0.4s;
}
.page-enter-from,
.page-leave-to {
opacity: 0;
filter: blur(1rem);
} */
</style>

23
assets/css/main.css Normal file
View file

@ -0,0 +1,23 @@
.btn {
height: initial !important;
min-height: var(--size);
}
.set-translate {
@apply absolute top-[50%] left-[50%];
transform: translate(-50%, -50%);
}
/* Transition (later)
.page-enter-active,
.page-leave-active {
transition: all 0.4s;
}
.page-enter-from,
.page-leave-to {
opacity: 0;
filter: blur(1rem);
} */
.info-little-box {
@apply inline-block px-[15px] py-[8px] bg-blue-500 text-white font-bold rounded-md;
}

View file

@ -7,10 +7,12 @@ const abc_model = defineModel();
</script>
<template>
<div class="flex flex-col gap-3 border-t p-4 border-slate-300 bg-slate-100">
<div
class="flex flex-col gap-5 border-t px-4 py-5 border-slate-300 bg-slate-100"
>
<div class="text-xl">{{ question?.pytanie }}</div>
<div>
<div class="flex flex-col">
<div class="flex flex-col gap-3">
<input
type="radio"
name="abc"
@ -21,7 +23,9 @@ const abc_model = defineModel();
/>
<label for="odp_a">
<div
:class="`btn-answer ${abc_model == 'a' ? ' !bg-fuchsia-500' : ''}`"
:class="`btn btn-primary btn-lg ${
abc_model == 'a' ? ' !btn-secondary' : ''
}`"
>
A
</div>
@ -37,7 +41,9 @@ const abc_model = defineModel();
/>
<label for="odp_b">
<div
:class="`btn-answer ${abc_model == 'b' ? ' !bg-fuchsia-500' : ''}`"
:class="`btn btn-primary btn-lg ${
abc_model == 'b' ? ' !btn-secondary' : ''
}`"
>
B
</div>
@ -53,7 +59,9 @@ const abc_model = defineModel();
/>
<label for="odp_c">
<div
:class="`btn-answer ${abc_model == 'c' ? ' !bg-fuchsia-500' : ''}`"
:class="`btn btn-primary btn-lg ${
abc_model == 'c' ? ' !btn-secondary' : ''
}`"
>
C
</div>
@ -65,21 +73,11 @@ const abc_model = defineModel();
</template>
<style scoped>
.btn-answer {
@apply flex justify-center items-center text-center;
}
label {
@apply cursor-pointer flex flex-row gap-2 items-center;
}
label:hover .btn-answer {
@apply bg-blue-300;
}
label:hover {
@apply bg-slate-200;
}
/* label > div {
} */
</style>

View file

@ -7,44 +7,24 @@ const tak_nie_model = defineModel();
</script>
<template>
<div class="flex flex-col gap-3 border-t p-4 border-slate-300 bg-slate-100">
<div
class="flex flex-col gap-6 border-t px-4 py-5 border-slate-300 bg-slate-100"
>
<div class="text-xl">{{ question?.pytanie }}</div>
<div>
<div class="flex flex-row justify-around">
<input
type="radio"
name="tak_nie"
id="odp_tak"
v-for="tn in ['tak', 'nie']"
:id="`odp_${tn}`"
v-model="tak_nie_model"
value="tak"
class="hidden"
:value="tn"
class="btn btn-primary btn-xl"
:aria-label="tn.toUpperCase()"
:class="`${tak_nie_model == tn ? ' !btn-secondary' : ''}`"
:checked="tak_nie_model == tn"
/>
<label for="odp_tak">
<div
:class="`btn-answer ${
tak_nie_model == 'tak' ? ' !bg-fuchsia-500' : ''
}`"
>
TAK
</div>
</label>
<input
type="radio"
name="tak_nie"
id="odp_nie"
v-model="tak_nie_model"
value="nie"
class="hidden"
/>
<label for="odp_nie">
<div
:class="`btn-answer ${
tak_nie_model == 'nie' ? ' !bg-fuchsia-500' : ''
}`"
>
NIE
</div>
</label>
</div>
</div>
</div>

8
components/Loading.vue Normal file
View file

@ -0,0 +1,8 @@
<template>
<div
class="flex min-h-dvh justify-center items-center text-5xl flex-col gap-10"
>
<span class="loading loading-spinner loading-xl scale-[2.5] block"></span>
<span class="block">Ładowanie</span>
</div>
</template>

View file

@ -24,22 +24,14 @@ const emit = defineEmits<{
<h1 class="text-[1.5rem]">{{ title }}</h1>
<div class="*:inline">Punkty: <slot name="points" /> / 74</div>
<div class="*:inline">Wynik: <slot name="resultTrueFalse" /></div>
<div
class="flex flex-row gap-2 *:py-1 *:px-3 *:border *:border-1 *:border-slate-300 *:rounded-md *:bg-slate-100"
>
<button
class="!border-slate-200 text-slate-600"
@click="emit('homepage')"
>
<div class="flex flex-row gap-2">
<button class="btn btn-soft" @click="emit('homepage')">
Wróć na stronę główną
</button>
<button class="!bg-slate-200 text-slate-800" @click="emit('newExam')">
<button class="btn btn-outline" @click="emit('newExam')">
Rozpocznij jeszcze raz
</button>
<button
class="!border-2 !border-slate-200 !bg-slate-700 text-white"
@click="emit('close')"
>
<button class="btn btn-neutral" @click="emit('close')">
Przejrzyj odpowiedzi
</button>
</div>

View file

@ -1,6 +1,4 @@
<script setup lang="ts">
import "7.css/dist/7.scoped.css";
const props = defineProps<{
result: ResultEndType;
countBasic: number;
@ -17,98 +15,68 @@ const isAdvanced = computed(() => props.now == "advanced");
<template>
<div
class="flex flex-col items-center p-4 gap-10 border-l border-slate-300 bg-slate-100"
class="flex flex-col items-stretch p-4 gap-10 border-l border-slate-300 bg-slate-100"
>
<div>
<button @click="$emit('end-exam')" class="btn-major">
<button @click="$emit('end-exam')" class="btn btn-warning btn-xl">
Zakończ egzamin
</button>
</div>
<div class="flex flex-row gap-6 *:flex-1 w-full">
<div :class="isBasic ? '' : 'opacity-45'">
<div class="flex flex-col gap-1" :class="isBasic ? '' : 'opacity-45'">
<span class="text-lg">Pytania podstawowe</span>
<div class="win7 *:!h-10 *:*:!h-10 *:*:*:h-10 text-lg">
<div
role="progressbar"
class="relative"
:class="isBasic ? 'animate' : ''"
>
<div :class="`w-full`">
<div
class="set-translate w-full text-center bg-blue-500 bg-opacity-60"
class="info-little-box w-full text-center"
:class="isBasic ? 'font-semibold' : ''"
>
<span class="block set-translate w-full text-center"
>{{ countBasic + 1 }} / {{ dataBasic?.length }}</span
>
{{ countBasic + 1 }} / {{ dataBasic?.length }}
</div>
</div>
</div>
</div>
</div>
<div :class="isAdvanced ? '' : 'opacity-45'">
<div class="flex flex-col gap-1" :class="isAdvanced ? '' : 'opacity-45'">
<span class="text-lg">Pytania specjalistyczne</span>
<div class="win7 *:!h-10 *:*:!h-10 *:*:*:h-10 text-lg">
<div
role="progressbar"
class="relative"
:class="isAdvanced ? 'animate' : ''"
>
<div class="w-full">
<div
class="set-translate w-full text-center bg-blue-500 bg-opacity-60"
class="info-little-box w-full text-center"
:class="isAdvanced ? 'font-semibold' : ''"
>
<span class="block set-translate w-full text-center">
{{ countAdvanced + 1 }} / {{ dataAdvanced?.length }}
</span>
</div>
</div>
</div>
<div class="text-center text-xl flex flex-col gap-2">
<span>Czas na zapoznanie się z pytaniem</span>
<div class="flex flex-row items-stretch gap-2">
<div class="btn btn-primary">START</div>
<div class="h-full flex-1 relative">
<progress
class="progress progress-warning w-full h-full"
value="50"
max="100"
></progress>
<span class="block set-translate z-10 text-black text-2xl">20s</span>
</div>
</div>
</div>
<div class="text-center text-xl">
Czas na zapoznanie się z pytaniem
<div class="flex flex-row items-stretch">
<div class="btn-major">START</div>
<div class="win7 flex-1 *:!h-[100%] *:*:!h-[100%]">
<div role="progressbar" class="relative min-h-6">
<div class="progressive !bg-orange-500">
<div class="set-translate w-full text-center text-3xl">10 s</div>
<div class="text-center text-xl flex flex-col gap-2">
<span>Czas na udzielenie odpowiedzi</span>
<div class="h-9 relative">
<progress
class="progress progress-warning w-full h-full"
value="50"
max="100"
></progress>
<span class="block set-translate z-10 text-black text-2xl">15s</span>
</div>
</div>
<div class="max-h-[150px] overflow-y-scroll">
{{ result }}
</div>
</div>
</div>
<div class="text-center text-xl">
Czas na udzielenie odpowiedzi
<div class="flex flex-row items-stretch">
<div class="win7 flex-1 *:!h-[100%] *:*:!h-[100%]">
<div role="progressbar" class="relative min-h-6">
<div class="progressive !bg-orange-500">
<div class="set-translate w-full text-center text-3xl">10 s</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div class="flex-1"></div>
<button
@click="$emit('next-question')"
class="btn-major"
class="btn btn-warning btn-xl"
:disabled="ending"
>
Następne pytanie
</button>
</div>
<br />
<div class="max-h-[150px] overflow-y-scroll">{{ result }}</div>
</div>
</template>
<style>
@ -116,11 +84,6 @@ const isAdvanced = computed(() => props.now == "advanced");
animation: progressZapoznanie 20s linear;
}
.btn-major:disabled,
.btn-major:disabled:hover {
@apply cursor-not-allowed bg-orange-600 !bg-opacity-40;
}
@keyframes progressZapoznanie {
0% {
width: 0;

View file

@ -16,9 +16,9 @@ const isAdvanced = computed(() => props.now == "advanced");
const boxesAmount = computed(() => {
if (isBasic.value) {
return 20 + 1;
return 20;
} else if (isAdvanced.value) {
return 12 + 1;
return 12;
} else {
return 0;
}
@ -37,22 +37,17 @@ const countSwitchable = computed(() => {
<template>
<div
class="flex flex-col items-center p-4 gap-6 border-l border-slate-300 bg-slate-100"
class="flex flex-col items-stretch p-4 gap-6 border-l border-slate-300 bg-slate-100"
>
<div>
<button @click="$emit('nav', '/')" class="btn-major">
<button @click="$emit('nav', '/')" class="btn btn-warning btn-xl">
Wróć na stronę główną
</button>
</div>
<div class="flex flex-row gap-6 *:flex-1 w-full">
<button
class="text-md text-white bg-blue-400"
@click="$emit('change-now', 'basic')"
>
<div class="flex flex-row gap-4 *:flex-1 w-full flex-wrap">
<button class="btn btn-info btn-lg" @click="$emit('change-now', 'basic')">
Pytania podstawowe
</button>
<button
class="text-md text-white bg-blue-400"
class="btn btn-info btn-lg"
@click="$emit('change-now', 'advanced')"
>
Pytania specjalistyczne
@ -61,37 +56,32 @@ const countSwitchable = computed(() => {
<div
class="grid grid-cols-[repeat(auto-fit,50px)] gap-2 justify-around w-full"
>
<div
v-for="num in range(1, boxesAmount)"
class="p-1 bg-blue-500 text-white text-center cursor-pointer"
@click="$emit('change-count', num - 1)"
<input
type="radio"
:aria-label="(num + 1).toString()"
class="btn btn-lg"
:name="`${now}-chooser`"
v-for="num in range(0, boxesAmount)"
@click="$emit('change-count', num)"
:class="`${
isBasic
? result.basic[num - 1].question?.poprawna_odp.toLowerCase() ==
result.basic[num - 1].chosen_answer
? 'bg-green-500'
: 'bg-red-500'
? result.basic[num].question?.poprawna_odp.toLowerCase() ==
result.basic[num].chosen_answer
? 'btn-success'
: 'btn-error'
: ''
}${
isAdvanced
? result.advanced[num - 1].question?.poprawna_odp.toLowerCase() ==
result.advanced[num - 1].chosen_answer
? 'bg-green-500'
: 'bg-red-500'
? result.advanced[num].question?.poprawna_odp.toLowerCase() ==
result.advanced[num].chosen_answer
? 'btn-success'
: 'btn-error'
: ''
} ${countSwitchable + 1 == num ? '!bg-orange-500' : ''}`"
>
{{ num }}
}`"
:checked="countSwitchable == num"
:key="`choose-${num}-${now}`"
/>
</div>
</div>
<!-- <div class="flex flex-row gap-6 *:flex-1 w-full">
<button class="text-md text-white bg-blue-400">
Odtwórz film ponownie
</button>
<button class="text-md text-white bg-blue-400">
Pokaż poprawną odpowiedź
</button>
</div> -->
<div class="text-center text-4xl flex flex-col gap-5">
<span class="block">Poprawna odpowiedź</span>
<span class="block">{{ question?.poprawna_odp }}</span>
@ -110,10 +100,9 @@ const countSwitchable = computed(() => {
}}
</span>
</div>
<div>
<button @click="$emit('nav', '/exam')" class="btn-major">
<div class="flex-1"></div>
<button @click="$emit('nav', '/exam')" class="btn btn-warning btn-xl">
Rozpocznij jeszcze raz
</button>
</div>
</div>
</template>

View file

@ -28,12 +28,12 @@ const timeRemainingFriendly = computed(() => {
</div>
</div>
<div>
<span class="block">Aktualna kategoria (implement)</span>
<span class="block">Aktualna kategoria</span>
<div class="info-little-box">{{ category }}</div>
</div>
<div v-if="typeof timeRemaining !== 'undefined'">
<span class="block">Czas do końca egzaminu</span>
<div class="info-little-box w-18 text-center">
<div class="info-little-box w-20 text-center">
{{ timeRemainingFriendly }}
</div>
</div>

View file

@ -1,3 +0,0 @@
<template>
<div><slot /></div>
</template>

View file

@ -1,5 +0,0 @@
<script setup lang="ts"></script>
<template>
<div><slot /></div>
</template>

10
middleware/exam.ts Normal file
View file

@ -0,0 +1,10 @@
export default defineNuxtRouteMiddleware((to, from) => {
const examStore = useExamStore();
if (examStore.category != "") {
examStore.mildReset();
} else {
examStore.resetExam();
return navigateTo("/");
}
});

8
middleware/result.ts Normal file
View file

@ -0,0 +1,8 @@
export default defineNuxtRouteMiddleware((to, from) => {
const examStore = useExamStore();
if (!examStore.end) {
examStore.resetExam();
return navigateTo("/");
}
});

View file

@ -10,6 +10,7 @@ export default defineNuxtConfig({
imports: {
dirs: ["types/*.ts", "store/*.ts", "types/**/*.ts"],
},
// Transition (later)
// app: {
// pageTransition: { name: "page", mode: "out-in" },
// },
@ -18,4 +19,7 @@ export default defineNuxtConfig({
cdn_url: process.env.CDN_URL,
},
},
routeRules: {
"/": { prerender: true },
},
});

View file

@ -10,11 +10,11 @@
"postinstall": "nuxt prepare"
},
"dependencies": {
"7.css": "^0.17.0",
"@nuxt/fonts": "0.10.3",
"@nuxtjs/tailwindcss": "6.13.1",
"@pinia/nuxt": "0.10.1",
"array-shuffle": "^3.0.0",
"daisyui": "^5.0.0",
"date-fns": "^4.1.0",
"dotenv": "^16.4.7",
"drizzle-orm": "^0.40.0",

View file

@ -1,13 +1,10 @@
<script lang="ts" setup>
definePageMeta({
layout: "exam",
});
import "7.css/dist/7.scoped.css";
import { useExamStore } from "~/store/examResults";
import { useExamStore } from "~/store/examStore";
import { intervalToDuration, addMinutes, addSeconds, isEqual } from "date-fns";
definePageMeta({ middleware: ["exam"] });
const nowTime = ref(new Date());
const timeEnd = addMinutes(new Date(), 25);
@ -31,8 +28,6 @@ onMounted(() => {
const examStore = useExamStore();
examStore.resetExam();
useHead({
title: "Pytanie 1/20",
});
@ -41,13 +36,21 @@ const {
data: dataBasic,
error: errorBasic,
status: statusBasic,
} = await useFetch<BasicQuestion[]>("/api/basic");
} = await useLazyFetch<BasicQuestion[]>(`/api/basic`, {
query: {
category: examStore.category,
},
});
const {
data: dataAdvanced,
error: errorAdvanced,
status: statusAdvanced,
} = await useFetch<AdvancedQuestion[]>("/api/advanced");
} = await useLazyFetch<AdvancedQuestion[]>(`/api/advanced`, {
query: {
category: examStore.category,
},
});
const countBasic = ref(0);
const countAdvanced = ref(-1);
@ -150,12 +153,12 @@ const result: Ref<ResultEndType> = ref({
<template>
<div>
<div v-if="statusBasic === 'success'">
<div v-if="statusBasic === 'success' && statusAdvanced === 'success'">
<div class="grid grid-cols-4 min-h-dvh">
<div class="col-span-3 flex flex-col gap-4">
<TopBar
:points="question?.liczba_pkt"
:category="`B`"
:category="examStore.category"
:time-remaining="timeRemainingTotal"
/>
<Media :media="media" />
@ -187,44 +190,6 @@ const result: Ref<ResultEndType> = ref({
<div v-else-if="statusBasic === 'error' || statusAdvanced === 'error'">
An API error occurred: {{ errorBasic }} {{ errorAdvanced }}
</div>
<div v-else>Loading...</div>
<Loading v-else />
</div>
</template>
<style>
.btn {
@apply box-border text-white font-bold p-3 rounded-lg w-fit cursor-pointer border-[4px] transition duration-100 select-none;
}
.btn:active {
@apply duration-0;
}
.btn-answer {
@apply btn bg-blue-500 text-xl;
}
.btn-answer:hover {
@apply bg-blue-300;
}
.btn-answer:active {
@apply bg-blue-400;
}
.btn-major {
@apply btn bg-orange-400 text-base;
}
.btn-major:hover {
@apply bg-orange-200;
}
.btn-major:active {
@apply bg-orange-300;
}
.info-little-box {
@apply inline-block px-[15px] py-[8px] bg-blue-500 text-white font-bold;
}
</style>

View file

@ -1,12 +1,43 @@
<script setup lang="ts">
const categories = [
"A",
"B",
"C",
"D",
"T",
"AM",
"A1",
"A2",
"B1",
"C1",
"D1",
"PT",
];
const examStore = useExamStore();
function setAndGo(category: string) {
examStore.category = category;
return navigateTo("/exam");
}
</script>
<template>
<div>
<h1>Test na prawo jazdy kat.B</h1>
<div class="text-3xl">
<span>Test na prawo jazdy</span>
<p>
Witaj w teście na prawo jazdy kat.B, aby rozpocząć, naciśnij poniższy
przycisk:
Witaj w teście na prawo jazdy, aby rozpocząć, naciśnij jeden z poniższych
przycisków:
<br />
</p>
<NuxtLink to="/exam" class="text-4xl font-bold bg-fuchsia-200"
>START!</NuxtLink
<div class="flex flex-row flex-wrap gap-2">
<button
class="btn btn-xl btn-secondary"
v-for="category in categories"
@click="setAndGo(category)"
>
{{ category }}
</button>
</div>
</div>
</template>

View file

@ -2,18 +2,12 @@
import { ModalsContainer, useModal } from "vue-final-modal";
import ResultModal from "~/components/ResultModal.vue";
definePageMeta({
layout: "exam",
});
definePageMeta({ middleware: ["result"] });
const examStore = useExamStore();
const points = ref<number>(0);
if (!examStore.end) {
examStore.resetExam();
await navigateTo("/");
} else {
examStore.result.basic.forEach((answer) => {
if (answer.chosen_is_correct) {
points.value += answer.question?.liczba_pkt ?? 0;
@ -24,7 +18,6 @@ if (!examStore.end) {
points.value += answer.question?.liczba_pkt ?? 0;
}
});
}
const resultTrueFalse = ref(points.value >= 68 ? "pozytywny" : "negatywny");
@ -117,7 +110,10 @@ function nav(route: string) {
<div>
<div class="grid grid-cols-4 min-h-dvh">
<div class="col-span-3 flex flex-col gap-4">
<TopBar :points="question?.liczba_pkt" :category="`B`" />
<TopBar
:points="question?.liczba_pkt"
:category="examStore.category"
/>
<Media :media="media" />
<BasicQuestionBlock
v-if="now == 'basic'"

16
pnpm-lock.yaml generated
View file

@ -11,9 +11,6 @@ importers:
.:
dependencies:
7.css:
specifier: ^0.17.0
version: 0.17.0
'@nuxt/fonts':
specifier: 0.10.3
version: 0.10.3(db0@0.2.4(drizzle-orm@0.40.0(@types/pg@8.11.11)(gel@2.0.0)(pg@8.13.3)))(ioredis@5.5.0)(magicast@0.3.5)(vite@6.1.1(@types/node@22.13.4)(jiti@2.4.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.0))
@ -26,6 +23,9 @@ importers:
array-shuffle:
specifier: ^3.0.0
version: 3.0.0
daisyui:
specifier: ^5.0.0
version: 5.0.0
date-fns:
specifier: ^4.1.0
version: 4.1.0
@ -72,9 +72,6 @@ importers:
packages:
7.css@0.17.0:
resolution: {integrity: sha512-U4DqX1WDFDbG6C9Myw/s2tgPapP8bkEYAd4tCchv3Zrjuugye3Fjv3IK32nq2cRO1Y4SnkbsBlyvu+o51rnPGg==}
'@alloc/quick-lru@5.2.0':
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
@ -1835,6 +1832,9 @@ packages:
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
daisyui@5.0.0:
resolution: {integrity: sha512-U0K9Bac3Bi3zZGm6ojrw12F0vBHTpEgf46zv/BYxLe07hF0Xnx7emIQliwaRBgJuYhY0BhwQ6wSnq5cJXHA2yA==}
date-fns@4.1.0:
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
@ -4190,8 +4190,6 @@ packages:
snapshots:
7.css@0.17.0: {}
'@alloc/quick-lru@5.2.0': {}
'@ampproject/remapping@2.3.0':
@ -5984,6 +5982,8 @@ snapshots:
csstype@3.1.3: {}
daisyui@5.0.0: {}
date-fns@4.1.0: {}
db0@0.2.4(drizzle-orm@0.40.0(@types/pg@8.11.11)(gel@2.0.0)(pg@8.13.3)):

View file

@ -56,11 +56,28 @@ export default defineEventHandler(async (event) => {
}
const query = getQuery(event);
const category = query.category;
if (typeof category != "undefined" && typeof category != "string") {
const categories = [
"A",
"B",
"C",
"D",
"T",
"AM",
"A1",
"A2",
"B1",
"C1",
"D1",
"PT",
];
if (category == null || category == "") {
throw new Error(
"category argument has to be string (or not to be defined at all)"
);
}
if (!categories.includes(`${category}`)) {
throw new Error(`category argument has to be equal to: ${categories}`);
}
const db = drizzle(process.env.DATABASE_URL!);
const randomizedQuestions: AdvancedQuestion[] = [];
@ -81,7 +98,7 @@ export default defineEventHandler(async (event) => {
if (
questionsKeyPoints[randomized].kategorie
.split(",")
.includes(category ?? "B")
.includes(`${category}`)
) {
chosenRandomQuestions.push(questionsKeyPoints[randomized]);
} else {

View file

@ -35,11 +35,28 @@ export default defineEventHandler(async (event) => {
}
const query = getQuery(event);
const category = query.category;
if (typeof category != "undefined" && typeof category != "string") {
const categories = [
"A",
"B",
"C",
"D",
"T",
"AM",
"A1",
"A2",
"B1",
"C1",
"D1",
"PT",
];
if (category == null || category == "") {
throw new Error(
"category argument has to be string (or not to be defined at all)"
);
}
if (!categories.includes(`${category}`)) {
throw new Error(`category argument has to be equal to: ${categories}`);
}
const db = drizzle(process.env.DATABASE_URL!);
const randomizedQuestions: BasicQuestion[] = [];
@ -60,7 +77,7 @@ export default defineEventHandler(async (event) => {
if (
questionsKeyPoints[randomized].kategorie
.split(",")
.includes(category ?? "B")
.includes(`${category}`)
) {
chosenRandomQuestions.push(questionsKeyPoints[randomized]);
} else {

View file

@ -1,12 +1,17 @@
import { defineStore } from "pinia";
export const useExamStore = defineStore("exam-results", () => {
export const useExamStore = defineStore("exam-store", () => {
const category = ref("");
const end = ref(false);
const result: Ref<ResultEndType> = ref({
basic: [],
advanced: [],
});
function resetExam() {
category.value = "";
mildReset();
}
function mildReset() {
end.value = false;
result.value = {
basic: [],
@ -15,8 +20,10 @@ export const useExamStore = defineStore("exam-results", () => {
}
return {
category,
end,
result,
resetExam,
mildReset,
};
});

7
tailwind.config.ts Normal file
View file

@ -0,0 +1,7 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
plugins: [require("daisyui")],
daisyui: {
themes: ["light", "dark"],
},
};