From 2d3854a4fe2a23184d70f4017f41e5a5b37dade9 Mon Sep 17 00:00:00 2001 From: NetMan <13informatyka14@gmail.com> Date: Tue, 4 Mar 2025 23:38:21 +0100 Subject: [PATCH] fix and improve results, fix api advanced --- app.vue | 7 + components/ResultModal.vue | 55 +++++++ components/{RightBar.vue => RightBarExam.vue} | 5 - components/RightBarResult.vue | 57 +++++++ components/TopBar.vue | 4 +- nuxt.config.ts | 3 +- package.json | 3 + pages/exam.vue | 29 +++- pages/result.vue | 122 +++++++++++++-- plugins/vue-final-modal.ts | 7 + pnpm-lock.yaml | 124 +++++++++++++++ server/api/advanced.get.ts | 147 ++++++++++-------- 12 files changed, 470 insertions(+), 93 deletions(-) create mode 100644 components/ResultModal.vue rename components/{RightBar.vue => RightBarExam.vue} (97%) create mode 100644 components/RightBarResult.vue create mode 100644 plugins/vue-final-modal.ts diff --git a/app.vue b/app.vue index 8e7f33e..3898d01 100644 --- a/app.vue +++ b/app.vue @@ -5,3 +5,10 @@ + + diff --git a/components/ResultModal.vue b/components/ResultModal.vue new file mode 100644 index 0000000..4d183d2 --- /dev/null +++ b/components/ResultModal.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/components/RightBar.vue b/components/RightBarExam.vue similarity index 97% rename from components/RightBar.vue rename to components/RightBarExam.vue index 8f41c0d..a23bec0 100644 --- a/components/RightBar.vue +++ b/components/RightBarExam.vue @@ -112,11 +112,6 @@ const isAdvanced = computed(() => props.now == "advanced"); --> diff --git a/components/TopBar.vue b/components/TopBar.vue index 441f151..48c7d32 100644 --- a/components/TopBar.vue +++ b/components/TopBar.vue @@ -2,7 +2,7 @@ defineProps<{ points: number | undefined; category: string | undefined; - timeRemaining: string | undefined; + timeRemaining?: string | undefined; }>(); @@ -20,7 +20,7 @@ defineProps<{ Aktualna kategoria (implement)
{{ category }}
-
+
Czas do końca egzaminu (implement)
{{ timeRemaining }}
diff --git a/nuxt.config.ts b/nuxt.config.ts index 2734a00..ca34ca9 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -4,6 +4,7 @@ export default defineNuxtConfig({ devtools: { enabled: true }, modules: ["@nuxtjs/tailwindcss", "@nuxt/fonts", "@pinia/nuxt"], ssr: true, + css: ["vue-final-modal/style.css"], imports: { dirs: ["types/*.ts", "store/*.ts", "types/**/*.ts"], }, @@ -12,4 +13,4 @@ export default defineNuxtConfig({ cdn_url: "http://pj.netman.ovh/", }, }, -}); \ No newline at end of file +}); diff --git a/package.json b/package.json index 2be5da3..292df41 100644 --- a/package.json +++ b/package.json @@ -18,14 +18,17 @@ "date-fns": "^4.1.0", "dotenv": "^16.4.7", "drizzle-orm": "^0.40.0", + "lodash": "^4.17.21", "nuxt": "^3.15.4", "pg": "^8.13.3", "pinia": "^3.0.1", "vue": "latest", + "vue-final-modal": "^4.5.5", "vue-router": "latest" }, "packageManager": "pnpm@10.4.1+sha512.c753b6c3ad7afa13af388fa6d808035a008e30ea9993f58c6663e2bc5ff21679aa834db094987129aa4d488b86df57f7b634981b2f827cdcacc698cc0cfb88af", "devDependencies": { + "@types/lodash": "^4.17.16", "@types/pg": "^8.11.11", "drizzle-kit": "^0.30.5", "tsx": "^4.19.3" diff --git a/pages/exam.vue b/pages/exam.vue index 880c4d8..bd9ca8c 100644 --- a/pages/exam.vue +++ b/pages/exam.vue @@ -42,8 +42,8 @@ async function next() { question: questionBasic.value, chosen_answer: tak_nie_model.value ?? "", chosen_is_correct: - tak_nie_model.value == question.value?.poprawna_odp?.toLowerCase(), - liczba_pkt: question.value?.liczba_pkt, + tak_nie_model.value == questionBasic.value?.poprawna_odp?.toLowerCase(), + liczba_pkt: questionBasic.value?.liczba_pkt, }); tak_nie_model.value = ""; countBasic.value++; @@ -56,28 +56,41 @@ async function next() { question: questionAdvanced.value, chosen_answer: abc_model.value ?? "", chosen_is_correct: - abc_model.value == question.value?.poprawna_odp?.toLowerCase(), - liczba_pkt: question.value?.liczba_pkt, + abc_model.value == + questionAdvanced.value?.poprawna_odp?.toLowerCase(), + liczba_pkt: questionAdvanced.value?.liczba_pkt, }); } else { now.value = "advanced"; + + result.value.basic.push({ + question: questionBasic.value, + chosen_answer: tak_nie_model.value ?? "", + chosen_is_correct: + tak_nie_model.value == + questionBasic.value?.poprawna_odp?.toLowerCase(), + liczba_pkt: questionBasic.value?.liczba_pkt, + }); + tak_nie_model.value = ""; } if (countAdvanced.value + 1 < dataAdvanced.value?.length!) { countAdvanced.value++; - } else { + } + if (countAdvanced.value == dataAdvanced.value?.length! - 1) { ending.value = true; } abc_model.value = ""; } } -async function endExam() { +function endExam() { while (!ending.value) { next(); } + next(); examStore.result = result.value; examStore.end = true; - await navigateTo("/result"); + return navigateTo("/result"); } const questionBasic = computed(() => @@ -135,7 +148,7 @@ const result: Ref = ref({ />
- +import { ModalsContainer, useModal } from "vue-final-modal"; +import ResultModal from "~/components/ResultModal.vue"; + definePageMeta({ layout: "exam", }); @@ -9,32 +12,121 @@ const points = ref(); if (!examStore.end) { examStore.resetExam(); - setTimeout(() => { - return navigateTo("/"); - }, 5000); + await navigateTo("/"); } else { let sum = 0; - examStore.result.basic.forEach((a) => { - if (a.chosen_is_correct) { - sum += a.liczba_pkt ?? 0; + examStore.result.basic.forEach((answer) => { + if (answer.chosen_is_correct) { + sum += answer.question?.liczba_pkt ?? 0; } }); - examStore.result.advanced.forEach((a) => { - if (a.chosen_is_correct) { - sum += a.liczba_pkt ?? 0; + examStore.result.advanced.forEach((answer) => { + if (answer.chosen_is_correct) { + sum += answer.question?.liczba_pkt ?? 0; } }); points.value = sum; } + +const countBasic = ref(0); +const countAdvanced = ref(0); + +const resultQuestionBasic = computed | undefined>( + () => examStore.result.basic.at(countBasic.value) +); +const resultQuestionAdvanced = computed< + ResultType | undefined +>(() => examStore.result.advanced.at(countAdvanced.value)); + +const questionBasic = computed( + () => resultQuestionBasic.value?.question +); +const questionAdvanced = computed( + () => resultQuestionAdvanced.value?.question +); + +const now = ref("basic"); + +const question = computed(() => { + if (now.value == "basic") { + return questionBasic.value; + } else if (now.value == "advanced") { + return questionAdvanced.value; + } else { + return; + } +}); + +const tak_nie_model = computed(() => + resultQuestionBasic.value?.chosen_answer.toLowerCase() +); +const abc_model = computed(() => + resultQuestionAdvanced.value?.chosen_answer.toLowerCase() +); + +const media = computed(() => { + const mediaSplit = question.value?.media?.split("."); + return { + fileType: mediaSplit?.pop()?.toLowerCase(), + fileName: mediaSplit?.join("."), + ogName: question.value?.media, + }; +}); + +const { open, close } = useModal({ + component: ResultModal, + attrs: { + title: "Egzamin teorytyczny", + onClose() { + close(); + }, + onHomepage() { + return navigateTo("/"); + }, + onNewExam() { + return navigateTo("/exam"); + }, + }, + slots: { + points: `${points.value}`, + }, +}); +open(); diff --git a/plugins/vue-final-modal.ts b/plugins/vue-final-modal.ts new file mode 100644 index 0000000..5ab028d --- /dev/null +++ b/plugins/vue-final-modal.ts @@ -0,0 +1,7 @@ +import { createVfm } from "vue-final-modal"; + +export default defineNuxtPlugin((nuxtApp) => { + const vfm = createVfm() as any; + + nuxtApp.vueApp.use(vfm); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 43c81ee..10f607c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: drizzle-orm: specifier: ^0.40.0 version: 0.40.0(@types/pg@8.11.11)(gel@2.0.0)(pg@8.13.3) + lodash: + specifier: ^4.17.21 + version: 4.17.21 nuxt: specifier: ^3.15.4 version: 3.15.4(@parcel/watcher@2.5.1)(@types/node@22.13.4)(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)(rollup@4.34.8)(terser@5.39.0)(tsx@4.19.3)(typescript@5.7.3)(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))(yaml@2.7.0) @@ -47,10 +50,16 @@ importers: vue: specifier: latest version: 3.5.13(typescript@5.7.3) + vue-final-modal: + specifier: ^4.5.5 + version: 4.5.5(@vueuse/core@12.7.0(typescript@5.7.3))(@vueuse/integrations@12.7.0(focus-trap@7.6.4)(fuse.js@7.1.0)(typescript@5.7.3))(focus-trap@7.6.4)(vue@3.5.13(typescript@5.7.3)) vue-router: specifier: latest version: 4.5.0(vue@3.5.13(typescript@5.7.3)) devDependencies: + '@types/lodash': + specifier: ^4.17.16 + version: 4.17.16 '@types/pg': specifier: ^8.11.11 version: 8.11.11 @@ -1247,6 +1256,9 @@ packages: '@types/http-proxy@1.17.16': resolution: {integrity: sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==} + '@types/lodash@4.17.16': + resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} + '@types/node@22.13.4': resolution: {integrity: sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==} @@ -1259,6 +1271,9 @@ packages: '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + '@unhead/dom@1.11.19': resolution: {integrity: sha512-udkgITdIblEWH3hsoFQMKW+6QXNO2qFZlZ2FI37bVAplQSnK/PytTPt/5oA1GWkoVwT0DsQNGHbU6kOg/3SlNg==} @@ -1369,6 +1384,56 @@ packages: '@vue/shared@3.5.13': resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + '@vueuse/core@12.7.0': + resolution: {integrity: sha512-jtK5B7YjZXmkGNHjviyGO4s3ZtEhbzSgrbX+s5o+Lr8i2nYqNyHuPVOeTdM1/hZ5Tkxg/KktAuAVDDiHMraMVA==} + + '@vueuse/integrations@12.7.0': + resolution: {integrity: sha512-IEq7K4bCl7mn3uKJaWtNXnd1CAPaHLUMuyj5K1/k/pVcItt0VONZW8xiGxdIovJcQjkzOHjImhX5t6gija+0/g==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@12.7.0': + resolution: {integrity: sha512-4VvTH9mrjXqFN5LYa5YfqHVRI6j7R00Vy4995Rw7PQxyCL3z0Lli86iN4UemWqixxEvYfRjG+hF9wL8oLOn+3g==} + + '@vueuse/shared@12.7.0': + resolution: {integrity: sha512-coLlUw2HHKsm7rPN6WqHJQr18WymN4wkA/3ThFaJ4v4gWGWAQQGK+MJxLuJTBs4mojQiazlVWAKNJNpUWGRkNw==} + abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -2162,6 +2227,9 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + focus-trap@7.6.4: + resolution: {integrity: sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==} + fontaine@0.5.0: resolution: {integrity: sha512-vPDSWKhVAfTx4hRKT777+N6Szh2pAosAuzLpbppZ6O3UdD/1m6OlHjNcC3vIbgkRTIcLjzySLHXzPeLO2rE8cA==} @@ -3615,6 +3683,9 @@ packages: resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} engines: {node: '>=18'} + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tailwind-config-viewer@2.0.4: resolution: {integrity: sha512-icvcmdMmt9dphvas8wL40qttrHwAnW3QEN4ExJ2zICjwRsPj7gowd1cOceaWG3IfTuM/cTNGQcx+bsjMtmV+cw==} engines: {node: '>=13'} @@ -4008,6 +4079,14 @@ packages: vue-devtools-stub@0.1.0: resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} + vue-final-modal@4.5.5: + resolution: {integrity: sha512-A6xgsXqE6eLw9e6Tq/W6pxDBmimPuSuvq20WL9TOZpZy7itPdGeNn8e1P15PCGqP2yHM3q2gJIchPY9ZJd8YsA==} + peerDependencies: + '@vueuse/core': '>=10.0.0' + '@vueuse/integrations': '>=10.0.0' + focus-trap: '>=7.2.0' + vue: '>=3.2.0' + vue-router@4.5.0: resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==} peerDependencies: @@ -5233,6 +5312,8 @@ snapshots: dependencies: '@types/node': 22.13.4 + '@types/lodash@4.17.16': {} + '@types/node@22.13.4': dependencies: undici-types: 6.20.0 @@ -5247,6 +5328,8 @@ snapshots: '@types/resolve@1.20.2': {} + '@types/web-bluetooth@0.0.20': {} + '@unhead/dom@1.11.19': dependencies: '@unhead/schema': 1.11.19 @@ -5444,6 +5527,34 @@ snapshots: '@vue/shared@3.5.13': {} + '@vueuse/core@12.7.0(typescript@5.7.3)': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 12.7.0 + '@vueuse/shared': 12.7.0(typescript@5.7.3) + vue: 3.5.13(typescript@5.7.3) + transitivePeerDependencies: + - typescript + + '@vueuse/integrations@12.7.0(focus-trap@7.6.4)(fuse.js@7.1.0)(typescript@5.7.3)': + dependencies: + '@vueuse/core': 12.7.0(typescript@5.7.3) + '@vueuse/shared': 12.7.0(typescript@5.7.3) + vue: 3.5.13(typescript@5.7.3) + optionalDependencies: + focus-trap: 7.6.4 + fuse.js: 7.1.0 + transitivePeerDependencies: + - typescript + + '@vueuse/metadata@12.7.0': {} + + '@vueuse/shared@12.7.0(typescript@5.7.3)': + dependencies: + vue: 3.5.13(typescript@5.7.3) + transitivePeerDependencies: + - typescript + abbrev@1.1.1: {} accepts@1.3.8: @@ -6210,6 +6321,10 @@ snapshots: flatted@3.3.3: {} + focus-trap@7.6.4: + dependencies: + tabbable: 6.2.0 + fontaine@0.5.0: dependencies: '@capsizecss/metrics': 2.2.0 @@ -7887,6 +8002,8 @@ snapshots: system-architecture@0.1.0: {} + tabbable@6.2.0: {} + tailwind-config-viewer@2.0.4(tailwindcss@3.4.17): dependencies: '@koa/router': 12.0.2 @@ -8315,6 +8432,13 @@ snapshots: vue-devtools-stub@0.1.0: {} + vue-final-modal@4.5.5(@vueuse/core@12.7.0(typescript@5.7.3))(@vueuse/integrations@12.7.0(focus-trap@7.6.4)(fuse.js@7.1.0)(typescript@5.7.3))(focus-trap@7.6.4)(vue@3.5.13(typescript@5.7.3)): + dependencies: + '@vueuse/core': 12.7.0(typescript@5.7.3) + '@vueuse/integrations': 12.7.0(focus-trap@7.6.4)(fuse.js@7.1.0)(typescript@5.7.3) + focus-trap: 7.6.4 + vue: 3.5.13(typescript@5.7.3) + vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)): dependencies: '@vue/devtools-api': 6.6.4 diff --git a/server/api/advanced.get.ts b/server/api/advanced.get.ts index b82085a..f5b4bba 100644 --- a/server/api/advanced.get.ts +++ b/server/api/advanced.get.ts @@ -1,71 +1,94 @@ import "dotenv/config"; import { drizzle } from "drizzle-orm/node-postgres"; import { dane, punkty } from "@/src/db/schema"; -import { sql, eq, isNotNull, and } from "drizzle-orm"; +import { sql, eq, and, or, isNotNull } from "drizzle-orm"; import { AdvancedQuestion } from "~/types"; +import arrayShuffle from "array-shuffle"; export default defineEventHandler(async (event) => { - const query = getQuery(event); - const amount = query?.amount; - const db = drizzle(process.env.DATABASE_URL!); - const questions: AdvancedQuestion[] = await db - .select({ - id: dane.id, - nr_pytania: dane.nr_pytania, - pytanie: dane.pytanie, - poprawna_odp: dane.poprawna_odp, - media: dane.media, - kategorie: dane.kategorie, - nazwa_media_pjm_tresc_pyt: dane.nazwa_media_pjm_tresc_pyt, - pytanie_eng: dane.pytanie_eng, - pytanie_de: dane.pytanie_de, - pytanie_ua: dane.pytanie_ua, - liczba_pkt: punkty.liczba_pkt, + async function getFromDb(points: number | string) { + return await db + .select({ + id: dane.id, + nr_pytania: dane.nr_pytania, + pytanie: dane.pytanie, + poprawna_odp: dane.poprawna_odp, + media: dane.media, + kategorie: dane.kategorie, + nazwa_media_pjm_tresc_pyt: dane.nazwa_media_pjm_tresc_pyt, + pytanie_eng: dane.pytanie_eng, + pytanie_de: dane.pytanie_de, + pytanie_ua: dane.pytanie_ua, + liczba_pkt: punkty.liczba_pkt, - odp_a: dane.odp_a, - odp_b: dane.odp_b, - odp_c: dane.odp_c, - nazwa_media_pjm_tresc_odp_a: dane.nazwa_media_pjm_tresc_odp_a, - nazwa_media_pjm_tresc_odp_b: dane.nazwa_media_pjm_tresc_odp_b, - nazwa_media_pjm_tresc_odp_c: dane.nazwa_media_pjm_tresc_odp_c, - odp_a_eng: dane.odp_a_eng, - odp_b_eng: dane.odp_b_eng, - odp_c_eng: dane.odp_c_eng, - odp_a_de: dane.odp_a_de, - odp_b_de: dane.odp_b_de, - odp_c_de: dane.odp_c_de, - odp_a_ua: dane.odp_a_ua, - odp_b_ua: dane.odp_b_ua, - odp_c_ua: dane.odp_c_ua, - }) - .from(dane) - .innerJoin(punkty, eq(dane.nr_pytania, punkty.nr_pytania)) - .where( - and( - isNotNull(dane.odp_a), - isNotNull(dane.odp_b), - isNotNull(dane.odp_c), - isNotNull(dane.odp_a_eng), - isNotNull(dane.odp_b_eng), - isNotNull(dane.odp_c_eng), - isNotNull(dane.odp_a_de), - isNotNull(dane.odp_b_de), - isNotNull(dane.odp_c_de) - ) - ); - const randoms: Array = []; - const randomizedQuestions = []; - for (let i = 0; i < +(amount ?? 12); i++) { - let randomized = Math.floor(Math.random() * (questions.length - 1 + 1)) + 0; - while (randoms.includes(randomized)) { - randomized = Math.floor(Math.random() * (questions.length - 1 + 1)) + 0; - } - randoms.push(randomized); - if (questions[randomized].kategorie?.split(",").includes("B")) { - randomizedQuestions.push(questions[randomized]); - } else { - i--; - } + odp_a: dane.odp_a, + odp_b: dane.odp_b, + odp_c: dane.odp_c, + nazwa_media_pjm_tresc_odp_a: dane.nazwa_media_pjm_tresc_odp_a, + nazwa_media_pjm_tresc_odp_b: dane.nazwa_media_pjm_tresc_odp_b, + nazwa_media_pjm_tresc_odp_c: dane.nazwa_media_pjm_tresc_odp_c, + odp_a_eng: dane.odp_a_eng, + odp_b_eng: dane.odp_b_eng, + odp_c_eng: dane.odp_c_eng, + odp_a_de: dane.odp_a_de, + odp_b_de: dane.odp_b_de, + odp_c_de: dane.odp_c_de, + odp_a_ua: dane.odp_a_ua, + odp_b_ua: dane.odp_b_ua, + odp_c_ua: dane.odp_c_ua, + }) + .from(dane) + .innerJoin(punkty, eq(dane.nr_pytania, punkty.nr_pytania)) + .where( + and( + isNotNull(dane.odp_a), + isNotNull(dane.odp_b), + isNotNull(dane.odp_c), + isNotNull(dane.odp_a_eng), + isNotNull(dane.odp_b_eng), + isNotNull(dane.odp_c_eng), + isNotNull(dane.odp_a_de), + isNotNull(dane.odp_b_de), + isNotNull(dane.odp_c_de), + eq(punkty.liczba_pkt, +points) + ) + ); } - return randomizedQuestions; + const query = getQuery(event); + const category = query.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 randomizedQuestions: AdvancedQuestion[] = []; + + for (let [key, value] of Object.entries({ 1: 2, 2: 4, 3: 6 })) { + const questionsKeyPoints: AdvancedQuestion[] = await getFromDb(key); + const chosenRandomQuestions: AdvancedQuestion[] = []; + + const randoms: Array = []; + for (let j = 0; j < value; j++) { + let randomized = + Math.floor(Math.random() * (questionsKeyPoints.length - 1 + 1)) + 0; + while (randoms.includes(randomized)) { + randomized = + Math.floor(Math.random() * (questionsKeyPoints.length - 1 + 1)) + 0; + } + randoms.push(randomized); + if ( + questionsKeyPoints[randomized].kategorie + .split(",") + .includes(category ?? "B") + ) { + chosenRandomQuestions.push(questionsKeyPoints[randomized]); + } else { + j--; + } + } + chosenRandomQuestions.forEach((q) => randomizedQuestions.push(q)); + } + return arrayShuffle(randomizedQuestions); });