Exam not finished, redirecting...
- Result: {{ points }} / 74
-
- {{ examStore.result }}
+
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);
});