Compare commits
3 commits
f05a98b074
...
4d53327521
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4d53327521 | ||
![]() |
af20ec21ee | ||
![]() |
db5e908430 |
13 changed files with 333 additions and 251 deletions
1
.env.example
Normal file
1
.env.example
Normal file
|
@ -0,0 +1 @@
|
||||||
|
DATABASE_URL="postgres://USERNAME:PASSWORD@HOST:PORT/DATABASE"
|
0
components/AdvancedQuestionBlock.vue
Normal file
0
components/AdvancedQuestionBlock.vue
Normal file
51
components/BasicQuestionBlock.vue
Normal file
51
components/BasicQuestionBlock.vue
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
defineProps<{
|
||||||
|
question: BasicQuestion | undefined;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const tak_nie_model = defineModel();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex flex-col gap-3">
|
||||||
|
<div>{{ question?.pytanie }}</div>
|
||||||
|
<div>
|
||||||
|
<div class="flex flex-row justify-around">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="tak_nie"
|
||||||
|
id="odp_tak"
|
||||||
|
v-model="tak_nie_model"
|
||||||
|
value="tak"
|
||||||
|
class="hidden"
|
||||||
|
/>
|
||||||
|
<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>
|
||||||
|
</template>
|
29
components/Media.vue
Normal file
29
components/Media.vue
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
const runtimeConfig = useRuntimeConfig();
|
||||||
|
const cdnUrl = runtimeConfig.public.cdn_url;
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
media: { fileName: string | undefined; fileType: string | undefined };
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="select-none z-[-1] w-full flex items-center justify-center *:object-contain *:object-contain *:*:object-contain flex-1"
|
||||||
|
>
|
||||||
|
<div class="w-full *:w-full text-center">
|
||||||
|
<img
|
||||||
|
:src="cdnUrl + [media.fileName, media.fileType].join('.')"
|
||||||
|
alt=""
|
||||||
|
v-if="media.fileType == 'jpg'"
|
||||||
|
/>
|
||||||
|
<video v-else-if="media.fileType == 'wmv'" :key="media.fileName" autoplay>
|
||||||
|
<source
|
||||||
|
:src="cdnUrl + [media.fileName, 'mp4'].join('.')"
|
||||||
|
type="video/mp4"
|
||||||
|
/>
|
||||||
|
</video>
|
||||||
|
<span v-else class="text-4xl font-bold">Brak mediów</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
86
components/RightBar.vue
Normal file
86
components/RightBar.vue
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import "7.css/dist/7.scoped.css";
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
questionaries: BasicQuestion[] | null;
|
||||||
|
countBasic: number;
|
||||||
|
countAdvanced: number;
|
||||||
|
dataBasic: BasicQuestion[] | null;
|
||||||
|
dataAdvanced: AdvancedQuestion[] | null;
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex flex-col items-center p-4 gap-10">
|
||||||
|
<div>
|
||||||
|
<button class="btn-major">Zakończ egzamin</button>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row gap-6">
|
||||||
|
<div>
|
||||||
|
Pytania podstawowe
|
||||||
|
<div class="win7">
|
||||||
|
<div
|
||||||
|
role="progressbar"
|
||||||
|
class="animate relative min-h-6"
|
||||||
|
aria-valuemin="0"
|
||||||
|
:aria-valuemax="dataBasic?.length"
|
||||||
|
:aria-valuenow="countBasic + 1"
|
||||||
|
>
|
||||||
|
<div :class="`w-${countBasic + 1}/${dataBasic?.length}`">
|
||||||
|
<div class="absolute top-0 w-full text-center font-semibold">
|
||||||
|
{{ countBasic + 1 }} / {{ dataBasic?.length }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Pytania specjalistyczne
|
||||||
|
<div class="win7">
|
||||||
|
<div
|
||||||
|
role="progressbar"
|
||||||
|
class="animate relative min-h-6"
|
||||||
|
aria-valuemin="0"
|
||||||
|
aria-valuemax="100"
|
||||||
|
aria-valuenow="80"
|
||||||
|
>
|
||||||
|
<div class="w-[60%]">
|
||||||
|
<div class="absolute top-0 w-full text-center">
|
||||||
|
{{ countAdvanced + 1 }} / {{ dataAdvanced?.length }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Czas na zapoznanie się z treścią pytania<br />
|
||||||
|
Czas na odpowiedź
|
||||||
|
<div class="btn-major">START</div>
|
||||||
|
<div class="win7">
|
||||||
|
<div
|
||||||
|
role="progressbar"
|
||||||
|
class="animate relative min-h-6"
|
||||||
|
aria-valuemin="0"
|
||||||
|
aria-valuemax="30"
|
||||||
|
aria-valuenow="10"
|
||||||
|
>
|
||||||
|
<div class="w-[60%]">
|
||||||
|
<div class="absolute top-0 w-full text-center font-semibold">
|
||||||
|
10 sekund
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button @click="$emit('next-question')" class="btn-major">
|
||||||
|
Następne pytanie
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div class="max-h-[300px] overflow-y-scroll">{{ questionaries }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
26
components/TopBar.vue
Normal file
26
components/TopBar.vue
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
points: number | undefined;
|
||||||
|
category: string | undefined;
|
||||||
|
timeRemaining: string | undefined;
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex flex-row gap-5">
|
||||||
|
<div>
|
||||||
|
Wartość punktowa
|
||||||
|
<div class="info-little-box">
|
||||||
|
{{ points }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Aktualna kategoria (implement)
|
||||||
|
<div class="info-little-box">{{ category }}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Czas do końca egzaminu (implement)
|
||||||
|
<div class="info-little-box">{{ timeRemaining }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -10,6 +10,7 @@
|
||||||
"postinstall": "nuxt prepare"
|
"postinstall": "nuxt prepare"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"7.css": "^0.17.0",
|
||||||
"@nuxt/fonts": "0.10.3",
|
"@nuxt/fonts": "0.10.3",
|
||||||
"@nuxtjs/tailwindcss": "6.13.1",
|
"@nuxtjs/tailwindcss": "6.13.1",
|
||||||
"array-shuffle": "^3.0.0",
|
"array-shuffle": "^3.0.0",
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
const {data} = await useFetch("/api/advanced");
|
|
||||||
|
|
||||||
const count = ref(0);
|
|
||||||
|
|
||||||
function next() {
|
|
||||||
if (count.value + 1 < data.value.length) {
|
|
||||||
count.value++;
|
|
||||||
} else {
|
|
||||||
console.log("Ok!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div v-if="data">
|
|
||||||
{{ data[count].nr_pytania }}: {{ data[count].pytanie }}
|
|
||||||
<!-- {{ data[count].poprawna_odp }} -->
|
|
||||||
{{ data[count].odp_a }}
|
|
||||||
{{ data[count].odp_b }}
|
|
||||||
{{ data[count].odp_c }}
|
|
||||||
<div v-if="data[count].media">
|
|
||||||
<img :src="'http://localhost:8081/'+data[count].media" alt="" v-if="data[count].media.split('.').at(-1).toLowerCase() == 'jpg'">
|
|
||||||
<video controls width="650" v-else-if="data[count].media.split('.').at(-1).toLowerCase() == 'mp4'">
|
|
||||||
<source :src="'http://localhost:8081/'+data[count].media" type="video/mp4" />
|
|
||||||
</video>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
No Media.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<button @click="next()">Next</button>
|
|
||||||
{{count}}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
206
pages/basic.vue
206
pages/basic.vue
|
@ -1,206 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { BasicQuestion } from "@/types/basic";
|
|
||||||
|
|
||||||
useHead({
|
|
||||||
title: "Pytanie 1/20",
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data, error, status, refresh } = await useFetch<BasicQuestion[]>(
|
|
||||||
"/api/basic"
|
|
||||||
);
|
|
||||||
|
|
||||||
const runtimeConfig = useRuntimeConfig();
|
|
||||||
const cdnUrl = runtimeConfig.public.cdn_url;
|
|
||||||
|
|
||||||
const count = ref(0);
|
|
||||||
|
|
||||||
const tak_nie_model = ref();
|
|
||||||
|
|
||||||
async function next() {
|
|
||||||
if (count.value + 1 < data.value?.length!) {
|
|
||||||
questionaries.value.push({
|
|
||||||
nr_pytania: question.value?.nr_pytania,
|
|
||||||
chosen_answer: tak_nie_model.value ?? "",
|
|
||||||
correct_answer: question.value?.poprawna_odp?.toLowerCase(),
|
|
||||||
chosen_is_correct:
|
|
||||||
tak_nie_model.value == question.value?.poprawna_odp?.toLowerCase(),
|
|
||||||
liczba_pkt: question.value?.liczba_pkt,
|
|
||||||
});
|
|
||||||
tak_nie_model.value = "";
|
|
||||||
count.value++;
|
|
||||||
useHead({
|
|
||||||
title: `Pytanie ${count.value + 1}/${data.value?.length}`,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// await navigateTo("/advanced");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const question = computed(() => data.value?.at(count.value));
|
|
||||||
const media = computed(() => {
|
|
||||||
const mediaSplit = question.value?.media?.split(".");
|
|
||||||
return {
|
|
||||||
fileType: mediaSplit?.pop()?.toLowerCase(),
|
|
||||||
fileName: mediaSplit?.join("."),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const questionaries: Ref<Array<any>> = ref([]);
|
|
||||||
|
|
||||||
const progres = ref();
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
const progresInterval = setInterval(() => {
|
|
||||||
progres.value.value = +progres.value.value + 1;
|
|
||||||
if (progres.value.value >= 100) {
|
|
||||||
clearInterval(progresInterval);
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div v-if="status === 'success'">
|
|
||||||
<div class="grid grid-cols-4">
|
|
||||||
<div class="col-span-3 flex flex-col gap-4 p-4">
|
|
||||||
<div class="flex flex-row gap-5">
|
|
||||||
<div>
|
|
||||||
Wartość punktowa
|
|
||||||
<div class="info-little-box">
|
|
||||||
{{ question?.liczba_pkt }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Aktualna kategoria (implement)
|
|
||||||
<div class="info-little-box">B</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Czas do końca egzaminu (implement)
|
|
||||||
<div class="info-little-box">25:00</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="select-none z-[-1] w-full flex items-center justify-center *:object-contain *:object-contain *:*:object-contain"
|
|
||||||
>
|
|
||||||
<div class="w-[650px] *:w-full">
|
|
||||||
<img
|
|
||||||
:src="cdnUrl + [media.fileName, media.fileType].join('.')"
|
|
||||||
alt=""
|
|
||||||
v-if="media.fileType == 'jpg'"
|
|
||||||
/>
|
|
||||||
<video
|
|
||||||
v-else-if="media.fileType == 'wmv'"
|
|
||||||
:key="media.fileName"
|
|
||||||
autoplay
|
|
||||||
>
|
|
||||||
<source
|
|
||||||
:src="cdnUrl + [media.fileName, 'mp4'].join('.')"
|
|
||||||
type="video/mp4"
|
|
||||||
/>
|
|
||||||
</video>
|
|
||||||
<span v-else>Brak mediów</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>{{ question?.pytanie }}</div>
|
|
||||||
<div>
|
|
||||||
<div class="flex flex-row justify-around">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
name="tak_nie"
|
|
||||||
id="odp_tak"
|
|
||||||
v-model="tak_nie_model"
|
|
||||||
value="tak"
|
|
||||||
class="hidden"
|
|
||||||
/>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<div class="flex flex-col items-center">
|
|
||||||
<div>
|
|
||||||
<button class="btn-major">Zakończ egzamin</button>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-row">
|
|
||||||
<div>
|
|
||||||
Pytania podstawowe
|
|
||||||
<div class="progressive">
|
|
||||||
{{ count + 1 }} / {{ data?.length }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Pytania specjalistyczne
|
|
||||||
<div class="progressive">
|
|
||||||
{{ count + 1 }} / {{ data?.length }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>TimeLeft (implement)</div>
|
|
||||||
<div>
|
|
||||||
<button @click="next()" class="btn-major">Następne pytanie</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
{{ questionaries }}
|
|
||||||
</div>
|
|
||||||
<div v-else-if="status === 'error'">Error: {{ error }}</div>
|
|
||||||
<div v-else>Loading...</div>
|
|
||||||
<progress max="100" ref="progres">Aha...</progress>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.btn {
|
|
||||||
@apply box-border text-white font-bold p-3 rounded-md w-fit cursor-pointer border-[4px];
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-little-box {
|
|
||||||
@apply inline-block px-[15px] py-[8px] bg-blue-500 text-white font-bold;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
.progressive {
|
|
||||||
} */
|
|
||||||
</style>
|
|
121
pages/exam.vue
Normal file
121
pages/exam.vue
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import "7.css/dist/7.scoped.css";
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: "Pytanie 1/20",
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: dataBasic,
|
||||||
|
error: errorBasic,
|
||||||
|
status: statusBasic,
|
||||||
|
} = await useFetch<BasicQuestion[]>("/api/basic");
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: dataAdvanced,
|
||||||
|
error: errorAdvanced,
|
||||||
|
status: statusAdvanced,
|
||||||
|
} = await useFetch<AdvancedQuestion[]>("/api/advanced");
|
||||||
|
|
||||||
|
const countBasic = ref(0);
|
||||||
|
const countAdvanced = ref(-1);
|
||||||
|
|
||||||
|
const tak_nie_model = ref();
|
||||||
|
|
||||||
|
async function next() {
|
||||||
|
if (countBasic.value + 1 < dataBasic.value?.length!) {
|
||||||
|
questionaries.value.push({
|
||||||
|
nr_pytania: question.value?.nr_pytania,
|
||||||
|
chosen_answer: tak_nie_model.value ?? "",
|
||||||
|
correct_answer: question.value?.poprawna_odp?.toLowerCase(),
|
||||||
|
chosen_is_correct:
|
||||||
|
tak_nie_model.value == question.value?.poprawna_odp?.toLowerCase(),
|
||||||
|
liczba_pkt: question.value?.liczba_pkt,
|
||||||
|
});
|
||||||
|
tak_nie_model.value = "";
|
||||||
|
countBasic.value++;
|
||||||
|
useHead({
|
||||||
|
title: `Pytanie ${countBasic.value + 1}/${dataBasic.value?.length}`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// await navigateTo("/advanced");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const question = computed(() => dataBasic.value?.at(countBasic.value));
|
||||||
|
const media = computed(() => {
|
||||||
|
const mediaSplit = question.value?.media?.split(".");
|
||||||
|
return {
|
||||||
|
fileType: mediaSplit?.pop()?.toLowerCase(),
|
||||||
|
fileName: mediaSplit?.join("."),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const questionaries: Ref<Array<any>> = ref([]);
|
||||||
|
|
||||||
|
// onMounted(() => {
|
||||||
|
// const progresInterval = setInterval(() => {
|
||||||
|
// progres.value.value = +progres.value.value + 1;
|
||||||
|
// if (progres.value.value >= 100) {
|
||||||
|
// clearInterval(progresInterval);
|
||||||
|
// }
|
||||||
|
// }, 100);
|
||||||
|
// });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="statusBasic === 'success'">
|
||||||
|
<div class="grid grid-cols-4 min-h-dvh">
|
||||||
|
<div class="col-span-3 flex flex-col gap-4 p-4">
|
||||||
|
<TopBar
|
||||||
|
:points="question?.liczba_pkt"
|
||||||
|
:category="`B`"
|
||||||
|
:time-remaining="`25:00`"
|
||||||
|
/>
|
||||||
|
<Media :media="media" />
|
||||||
|
<BasicQuestionBlock :question="question" v-model="tak_nie_model" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<RightBar
|
||||||
|
:questionaries="questionaries"
|
||||||
|
:data-basic="dataBasic"
|
||||||
|
:data-advanced="dataAdvanced"
|
||||||
|
:count-basic="countBasic"
|
||||||
|
:count-advanced="countAdvanced"
|
||||||
|
@next-question="next()"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="statusBasic === 'error' || statusAdvanced === 'error'">
|
||||||
|
An API error occurred: {{ errorBasic }} {{ errorAdvanced }}
|
||||||
|
</div>
|
||||||
|
<div v-else>Loading...</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.btn {
|
||||||
|
@apply box-border text-white font-bold p-3 rounded-md w-fit cursor-pointer border-[4px] transition duration-100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-answer {
|
||||||
|
@apply btn bg-blue-500 text-xl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-answer:hover {
|
||||||
|
@apply bg-blue-300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-answer:active {
|
||||||
|
@apply bg-blue-400 duration-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-major {
|
||||||
|
@apply btn bg-orange-400 text-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-little-box {
|
||||||
|
@apply inline-block px-[15px] py-[8px] bg-blue-500 text-white font-bold;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -5,6 +5,8 @@
|
||||||
Witaj w teście na prawo jazdy kat.B, aby rozpocząć, naciśnij poniższy
|
Witaj w teście na prawo jazdy kat.B, aby rozpocząć, naciśnij poniższy
|
||||||
przycisk:
|
przycisk:
|
||||||
</p>
|
</p>
|
||||||
<NuxtLink to="/basic">START!</NuxtLink>
|
<NuxtLink to="/exam" class="text-4xl font-bold bg-fuchsia-200"
|
||||||
|
>START!</NuxtLink
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
|
@ -11,6 +11,9 @@ importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
7.css:
|
||||||
|
specifier: ^0.17.0
|
||||||
|
version: 0.17.0
|
||||||
'@nuxt/fonts':
|
'@nuxt/fonts':
|
||||||
specifier: 0.10.3
|
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))
|
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))
|
||||||
|
@ -51,6 +54,9 @@ importers:
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
7.css@0.17.0:
|
||||||
|
resolution: {integrity: sha512-U4DqX1WDFDbG6C9Myw/s2tgPapP8bkEYAd4tCchv3Zrjuugye3Fjv3IK32nq2cRO1Y4SnkbsBlyvu+o51rnPGg==}
|
||||||
|
|
||||||
'@alloc/quick-lru@5.2.0':
|
'@alloc/quick-lru@5.2.0':
|
||||||
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
@ -4073,6 +4079,8 @@ packages:
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
|
7.css@0.17.0: {}
|
||||||
|
|
||||||
'@alloc/quick-lru@5.2.0': {}
|
'@alloc/quick-lru@5.2.0': {}
|
||||||
|
|
||||||
'@ampproject/remapping@2.3.0':
|
'@ampproject/remapping@2.3.0':
|
||||||
|
|
|
@ -31,6 +31,12 @@ export default defineEventHandler(async (event) => {
|
||||||
}
|
}
|
||||||
const query = getQuery(event);
|
const query = getQuery(event);
|
||||||
const category = query.category;
|
const category = query.category;
|
||||||
|
console.log(typeof category);
|
||||||
|
if (typeof category != "undefined" && typeof category != "string") {
|
||||||
|
throw new Error(
|
||||||
|
"category argument has to be string (or not to be defined at all)"
|
||||||
|
);
|
||||||
|
}
|
||||||
const db = drizzle(process.env.DATABASE_URL!);
|
const db = drizzle(process.env.DATABASE_URL!);
|
||||||
|
|
||||||
const randomizedQuestions: BasicQuestion[] = [];
|
const randomizedQuestions: BasicQuestion[] = [];
|
||||||
|
@ -51,13 +57,7 @@ export default defineEventHandler(async (event) => {
|
||||||
if (
|
if (
|
||||||
questionsKeyPoints[randomized].kategorie
|
questionsKeyPoints[randomized].kategorie
|
||||||
.split(",")
|
.split(",")
|
||||||
.filter((q) =>
|
.includes(category ?? "B")
|
||||||
q
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(
|
|
||||||
`${typeof category === "string" ? category.toLowerCase() : "b"}`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
chosenRandomQuestions.push(questionsKeyPoints[randomized]);
|
chosenRandomQuestions.push(questionsKeyPoints[randomized]);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Reference in a new issue