Compare commits
4 commits
c99576617b
...
c05db22b6b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c05db22b6b | ||
|
|
59497e8b01 | ||
|
|
97b8d5dab9 | ||
|
|
63121da4b7 |
28 changed files with 1052 additions and 338 deletions
|
|
@ -1,2 +1,2 @@
|
||||||
DATABASE_URL="postgres://USERNAME:PASSWORD@HOST:PORT/DATABASE"
|
DATABASE_URL="file:./db/database.db"
|
||||||
CDN_URL="http://DOMAIN.TLD/FOLDER"
|
CDN_URL="http://DOMAIN.TLD/FOLDER"
|
||||||
69
README.md
69
README.md
|
|
@ -1,5 +1,48 @@
|
||||||
# nuxt-prawo-jazdy
|
# nuxt-prawo-jazdy
|
||||||
|
|
||||||
|
## Required
|
||||||
|
|
||||||
|
The [db-prawo-jazdy](https://git.mandarynki.eu/netman/db-prawo-jazdy) project is designed for this one in mind, so use it in conjunction with this - visit it for more details
|
||||||
|
|
||||||
|
You also need the exam media files from the (Ministry of Infrasture)[https://www.gov.pl/web/infrastruktura/prawo-jazdy] - the latest files should be there
|
||||||
|
|
||||||
|
The newest at the moment of me writing this (December 13th 2025) are the (visualisations for questions from November 2025)[https://www.gov.pl/pliki/mi/pytania_egzaminacyjne_na_prawo_jazdy_11_2025.zip]
|
||||||
|
|
||||||
|
# To-do:
|
||||||
|
|
||||||
|
- [x] re-forge database structure (good for now)
|
||||||
|
- [x] choose category (good for now)
|
||||||
|
- [x] come up with how to show results appropriately
|
||||||
|
- [x] better answer click recognition
|
||||||
|
- [x] beautify website (good for now)
|
||||||
|
- [x] <b>Fixed?</b> Needs testing, but should be fine question-mark? - fix pinia middleware between pages, MAJOR ISSUE - finishing exam sometimes redirects to homepage instead of results
|
||||||
|
- [x] question timers
|
||||||
|
- [x] exam (& results?) warning leave message on exit and timer end (and definitely on refresh)
|
||||||
|
- [x] add keybinds:
|
||||||
|
- S - start
|
||||||
|
- D - nast.pyt
|
||||||
|
- X - koniec egzaminu (na pewno chcesz zakonczyc egzamin?)
|
||||||
|
- T - Tak
|
||||||
|
- N - Nie
|
||||||
|
- A - A
|
||||||
|
- B - B
|
||||||
|
- C - C
|
||||||
|
- [ ] i18n - pl, en, de, ua (not all questions are available in ua, api handle)
|
||||||
|
- UI i18n
|
||||||
|
- db: examstore add language field, api handle languages
|
||||||
|
- [ ] db: (revise) script for processing, (revise and) share appropriate files
|
||||||
|
- [ ] clean up js code in exam.vue and result.vue (currently a little bit of a mess)
|
||||||
|
|
||||||
|
## Some information about the project
|
||||||
|
|
||||||
|
My intention is, to share access to test exams free of charge, you don't have to pay me - although you can, I greatly appreciate if you donate!
|
||||||
|
|
||||||
|
In the future I will host this project publicly `aaS`, and will probably put non-invasive, privacy friendly ads if it gains enough traction
|
||||||
|
|
||||||
|
All data used by this software is public information by definition provided in the Polish Constitution - (article 61.)[https://www.sejm.gov.pl/prawo/konst/polski/kon1.htm], and can be acquired by either checking above links on the gov website, or by writing to the Ministry ((if something happened to be missing))[placeholder_for_post_about_missing_points_column]
|
||||||
|
|
||||||
|
This project is a website mimicking an official driver's license theoritical exam (for different license categories) with a seperate media server, connected using drizzle ORM to a SQLite database
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
This project utilizes `pnpm`, thus it is recommended
|
This project utilizes `pnpm`, thus it is recommended
|
||||||
|
|
@ -8,32 +51,6 @@ This project utilizes `pnpm`, thus it is recommended
|
||||||
pnpm install
|
pnpm install
|
||||||
```
|
```
|
||||||
|
|
||||||
## Required
|
|
||||||
|
|
||||||
The [db-prawo-jazdy](https://git.mandarynki.eu/netman/db-prawo-jazdy) project is designed for this one in mind, so use it in conjunction with this - visit it for more details
|
|
||||||
|
|
||||||
You also need the exam media files from the (Ministry of Infrasture)[https://www.gov.pl/web/infrastruktura/prawo-jazdy]. The newest at the moment of me writing this (19th of April 2025) are the (visualisations for questions from the 18th of January of 2024)[https://www.gov.pl/pliki/mi/wizualizacje_do_pytan_18_01_2024.zip]
|
|
||||||
|
|
||||||
# To-do:
|
|
||||||
|
|
||||||
- [x] re-forge database structure (good for now)
|
|
||||||
- [x] choose category (good for now)
|
|
||||||
- [x] come up with how to show results appropriately
|
|
||||||
- [x] db: script for processing, share appropriate files
|
|
||||||
- [x] better answer click recognition
|
|
||||||
- [x] beautify website (good for now)
|
|
||||||
- [ ] <b>fix pinia middleware between pages, MAJOR ISSUE - finishing exam sometimes redirects to homepage instead of results, help appreciated</b>
|
|
||||||
- [ ] exam (& results?) warning leave message on exit and timer end (and definitely on refresh)
|
|
||||||
- [ ] question timers
|
|
||||||
- [ ] lazy loading
|
|
||||||
- [ ] i18n - pl, en, de, ua (not all questions are not available in ua, api handle)
|
|
||||||
|
|
||||||
## Some info
|
|
||||||
|
|
||||||
My intention is, to share access to test exams free of charge - all data is free of charge and is already available as public information, either on the gov website, or by writing to the MI
|
|
||||||
|
|
||||||
This project is an SSR website mimicking an official driver's license exam (for different categories) with a seperate CDN for media, connected using an ORM to a postgres DB
|
|
||||||
|
|
||||||
## Development Server
|
## Development Server
|
||||||
|
|
||||||
Start the development server on `http://localhost:3000`:
|
Start the development server on `http://localhost:3000`:
|
||||||
|
|
|
||||||
6
app.vue
6
app.vue
|
|
@ -3,3 +3,9 @@
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.outline-set-solid {
|
||||||
|
outline-style: solid;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -12,3 +12,33 @@ export default [
|
||||||
'D1',
|
'D1',
|
||||||
'PT',
|
'PT',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const opis = [
|
||||||
|
'motocykle bez ograniczeń mocy',
|
||||||
|
'⭐ samochody osobowe do 3,5 t',
|
||||||
|
'pojazdy ciężarowe powyżej 3,5 t',
|
||||||
|
'autobusy',
|
||||||
|
'ciągniki rolnicze i pojazdy wolnobieżne',
|
||||||
|
'motorowery i lekkie czterokołowce',
|
||||||
|
'motocykle do 125 cm³ i 11 kW',
|
||||||
|
'motocykle do 35 kW',
|
||||||
|
'czterokołowce (np. quady)',
|
||||||
|
'pojazdy od 3,5 t do 7,5 t',
|
||||||
|
'autobusy do 16 pasażerów',
|
||||||
|
'tramwaje',
|
||||||
|
];
|
||||||
|
|
||||||
|
export const wiek = [
|
||||||
|
'(24 lata; lub 20 lat jeśli masz kat. A2 min. 2 lata)',
|
||||||
|
'(18 lat)',
|
||||||
|
'(21 lat; lub 18 lat z kwalifikacją wstępną)',
|
||||||
|
'(24 lata; lub 21 lat z kwalifikacją wstępną)',
|
||||||
|
'(16 lat)',
|
||||||
|
'(14 lat)',
|
||||||
|
'(16 lat)',
|
||||||
|
'(18 lat)',
|
||||||
|
'(16 lat)',
|
||||||
|
'(18 lat)',
|
||||||
|
'(21 lat; lub 18 lat z kwalifikacją wstępną)',
|
||||||
|
'(21 lat)',
|
||||||
|
];
|
||||||
|
|
|
||||||
29
components/EndModal.vue
Normal file
29
components/EndModal.vue
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps<{ showModal: boolean }>();
|
||||||
|
const endModal = useTemplateRef('endModal');
|
||||||
|
|
||||||
|
const emit = defineEmits(['hideEndModal', 'endExam']);
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
if (props.showModal && endModal.value?.open == false) {
|
||||||
|
endModal.value?.showModal();
|
||||||
|
emit('hideEndModal');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<dialog
|
||||||
|
ref="endModal"
|
||||||
|
class="flex justify-center items-center backdrop-blur-sm modal"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col p-3 bg-base rounded-md gap-3 modal-box min-w-fit">
|
||||||
|
<h1 class="text-[1.5rem]">Koniec egzaminu</h1>
|
||||||
|
<div class="*:inline">Czy na pewno chcesz zakończyć egzamin?</div>
|
||||||
|
<div class="flex flex-row gap-2 justify-around">
|
||||||
|
<div class="btn btn-lg btn-success" @click="emit('endExam')">Tak</div>
|
||||||
|
<div class="btn btn-lg btn-error" @click="endModal?.close()">Nie</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
</template>
|
||||||
|
|
@ -6,8 +6,11 @@ const cdnUrl = runtimeConfig.public.cdn_url;
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
const emit = defineEmits(['mediaload']);
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
mediaPath: string | null | undefined;
|
mediaPath: string | null | undefined;
|
||||||
|
phase: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const media = computed(() => {
|
const media = computed(() => {
|
||||||
|
|
@ -21,6 +24,21 @@ const media = computed(() => {
|
||||||
}
|
}
|
||||||
return { name: dotSplit?.join('.'), type };
|
return { name: dotSplit?.join('.'), type };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const video = ref();
|
||||||
|
|
||||||
|
function onVideoLoad() {
|
||||||
|
if (route.path === '/exam') {
|
||||||
|
video.value.play();
|
||||||
|
let duration = video.value.duration;
|
||||||
|
if (isNaN(duration) || duration == Infinity) {
|
||||||
|
duration = 0;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
emit('mediaload');
|
||||||
|
}, duration * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -28,23 +46,26 @@ const media = computed(() => {
|
||||||
class="select-none flex-auto w-full *:object-contain *:w-full *:h-full *:max-h-full relative *:absolute"
|
class="select-none flex-auto w-full *:object-contain *:w-full *:h-full *:max-h-full relative *:absolute"
|
||||||
:class="route.path === '/exam' ? 'z-[-1]' : ''"
|
:class="route.path === '/exam' ? 'z-[-1]' : ''"
|
||||||
>
|
>
|
||||||
|
<img v-if="phase == 'set-basic'" src="/placeholder.svg" alt="placeholder" />
|
||||||
<NuxtImg
|
<NuxtImg
|
||||||
v-if="media.type === 'image'"
|
v-else-if="media.type === 'image'"
|
||||||
:key="`${mediaPath}-image`"
|
:key="`${mediaPath}-image`"
|
||||||
provider="selfhost"
|
provider="selfhost"
|
||||||
:src="'/' + mediaPath"
|
:src="'/' + mediaPath"
|
||||||
:alt="mediaPath ?? ''"
|
:alt="mediaPath ?? ''"
|
||||||
|
@load="emit('mediaload')"
|
||||||
/>
|
/>
|
||||||
<video
|
<video
|
||||||
v-else-if="media.type === 'video'"
|
v-else-if="media.type === 'video'"
|
||||||
:key="`${mediaPath}-video`"
|
:key="`${mediaPath}-video`"
|
||||||
:autoplay="route.path === '/exam'"
|
ref="video"
|
||||||
:controls="route.path === '/result'"
|
:controls="route.path === '/result'"
|
||||||
|
@canplaythrough="onVideoLoad()"
|
||||||
>
|
>
|
||||||
<source :src="joinURL(cdnUrl, media.name + '.mp4')" type="video/mp4" />
|
<source :src="joinURL(cdnUrl, media.name + '.mp4')" type="video/mp4" />
|
||||||
</video>
|
</video>
|
||||||
<span v-else class="text-5xl font-bold flex items-center justify-center"
|
<span v-else class="text-5xl font-bold flex items-center justify-center"
|
||||||
>Brak mediów</span
|
>Pytanie bez wizualizacji</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ const myModal = useTemplateRef('myModal');
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
myModal.value?.showModal();
|
myModal.value?.showModal();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
defineEmits(['again', 'home']);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -19,10 +21,12 @@ onMounted(() => {
|
||||||
<div class="*:inline">Punkty: <slot name="points" /> / 74</div>
|
<div class="*:inline">Punkty: <slot name="points" /> / 74</div>
|
||||||
<div class="*:inline">Wynik: <slot name="resultTrueFalse" /></div>
|
<div class="*:inline">Wynik: <slot name="resultTrueFalse" /></div>
|
||||||
<div class="flex flex-row gap-2">
|
<div class="flex flex-row gap-2">
|
||||||
<NuxtLink to="/" class="btn btn-soft">Wróć na stronę główną</NuxtLink>
|
<div class="btn btn-soft" @click="$emit('home')">
|
||||||
<NuxtLink to="/exam" class="btn btn-outline">
|
Wróć na stronę główną
|
||||||
|
</div>
|
||||||
|
<div class="btn btn-outline" @click="$emit('again')">
|
||||||
Rozpocznij jeszcze raz
|
Rozpocznij jeszcze raz
|
||||||
</NuxtLink>
|
</div>
|
||||||
<button class="btn btn-neutral" @click="myModal?.close()">
|
<button class="btn btn-neutral" @click="myModal?.close()">
|
||||||
Przejrzyj odpowiedzi
|
Przejrzyj odpowiedzi
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,59 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
defineProps<{
|
import { onKeyStroke } from '@vueuse/core';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
countBasic: number;
|
countBasic: number;
|
||||||
countAdvanced: number;
|
countAdvanced: number;
|
||||||
now: string | null | undefined;
|
now: string | null | undefined;
|
||||||
ending: boolean;
|
ending: boolean;
|
||||||
|
setBasic: boolean;
|
||||||
|
time: number;
|
||||||
|
phase: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
endExam: [];
|
endExam: [];
|
||||||
nextQuestion: [];
|
nextQuestion: [];
|
||||||
|
nextTime: [];
|
||||||
|
showEndModal: [];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
function tryEndExam() {
|
||||||
|
if (props.ending == false) {
|
||||||
|
emit('showEndModal');
|
||||||
|
} else {
|
||||||
|
emit('endExam');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const startButton = useTemplateRef('start-button');
|
||||||
|
|
||||||
|
onKeyStroke(['S', 's'], () => {
|
||||||
|
startButton.value?.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
const nextButton = useTemplateRef('next-button');
|
||||||
|
|
||||||
|
onKeyStroke(['D', 'd'], () => {
|
||||||
|
nextButton.value?.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
const endButton = useTemplateRef('end-button');
|
||||||
|
|
||||||
|
onKeyStroke(['X', 'x'], () => {
|
||||||
|
endButton.value?.click();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col items-stretch p-4 gap-10 border-l border-base-300 bg-base-100"
|
class="flex flex-col items-stretch p-4 gap-10 border-l border-base-300 bg-base-100"
|
||||||
>
|
>
|
||||||
<button class="btn btn-warning btn-xl" @click="emit('endExam')">
|
<button
|
||||||
|
ref="end-button"
|
||||||
|
class="btn btn-warning btn-xl"
|
||||||
|
@click="tryEndExam()"
|
||||||
|
>
|
||||||
Zakończ egzamin
|
Zakończ egzamin
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -36,38 +73,90 @@ const emit = defineEmits<{
|
||||||
</CurrentQuestionCount>
|
</CurrentQuestionCount>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center text-xl flex flex-col gap-2">
|
<div
|
||||||
|
v-if="phase == 'set-basic'"
|
||||||
|
class="text-center text-xl flex flex-col gap-2"
|
||||||
|
>
|
||||||
<span>Czas na zapoznanie się z pytaniem</span>
|
<span>Czas na zapoznanie się z pytaniem</span>
|
||||||
<div class="flex flex-row items-stretch gap-2">
|
<div class="flex flex-row items-stretch gap-2">
|
||||||
<div class="btn btn-primary">START</div>
|
<div
|
||||||
|
ref="start-button"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="emit('nextTime')"
|
||||||
|
>
|
||||||
|
START
|
||||||
|
</div>
|
||||||
<div class="h-full flex-1 relative">
|
<div class="h-full flex-1 relative">
|
||||||
<progress
|
<progress
|
||||||
class="progress progress-warning w-full h-full"
|
class="progress progress-warning w-full h-full"
|
||||||
value="50"
|
:value="time"
|
||||||
max="100"
|
max="20"
|
||||||
/>
|
></progress>
|
||||||
<span class="block set-translate z-10 text-black text-2xl">20s</span>
|
<span class="block set-translate z-10 text-black text-2xl">
|
||||||
|
{{ time >= 0 ? time : 0 }}s
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center text-xl flex flex-col gap-2">
|
<div v-else class="text-center text-xl flex flex-col gap-2">
|
||||||
<span>Czas na udzielenie odpowiedzi</span>
|
<span>Czas na udzielenie odpowiedzi</span>
|
||||||
<div class="h-9 relative">
|
<div class="h-9 relative">
|
||||||
<progress
|
<progress
|
||||||
class="progress progress-warning w-full h-full"
|
class="progress progress-warning w-full h-full"
|
||||||
value="50"
|
:value="time"
|
||||||
max="100"
|
:max="phase == 'start-basic' ? 15 : 45"
|
||||||
/>
|
></progress>
|
||||||
<span class="block set-translate z-10 text-black text-2xl">15s</span>
|
<span class="block set-translate z-10 text-black text-2xl">
|
||||||
|
{{ time >= 0 ? time : 0 }}s
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-1" />
|
<div class="flex-1">
|
||||||
|
<span class="text-xl">Skróty klawiszowe</span>
|
||||||
|
<table class="table table-sm">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>S</td>
|
||||||
|
<td>niebieski przycisk start</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>D</td>
|
||||||
|
<td>następne pytanie</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>X</td>
|
||||||
|
<td>zakończ egzamin</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>T / Y</td>
|
||||||
|
<td>Tak</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>N</td>
|
||||||
|
<td>Nie</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>A</td>
|
||||||
|
<td>A</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>B</td>
|
||||||
|
<td>B</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>C</td>
|
||||||
|
<td>C</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
ref="next-button"
|
||||||
class="btn btn-warning btn-xl"
|
class="btn btn-warning btn-xl"
|
||||||
:disabled="ending"
|
:disabled="ending || setBasic"
|
||||||
@click="emit('nextQuestion')"
|
@click="emit('nextQuestion')"
|
||||||
>
|
>
|
||||||
Następne pytanie
|
Następne pytanie
|
||||||
|
|
@ -76,16 +165,12 @@ const emit = defineEmits<{
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/*.progressive {
|
.progressive {
|
||||||
animation: progressZapoznanie 20s linear;
|
width: calc(100% / v-bind('time'));
|
||||||
|
transition: all 1s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes progressZapoznanie {
|
progress[value]::-webkit-progress-value {
|
||||||
0% {
|
transition: width 0.5s;
|
||||||
width: 0;
|
}
|
||||||
}
|
|
||||||
100% {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ defineProps<{
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
changeNow: [value: string];
|
changeNow: [value: string];
|
||||||
changeCount: [num: number];
|
changeCount: [num: number];
|
||||||
|
again: [];
|
||||||
|
home: [];
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -18,9 +20,9 @@ const emit = defineEmits<{
|
||||||
<div
|
<div
|
||||||
class="flex flex-col items-stretch p-4 gap-6 border-l border-base-300 bg-base-100"
|
class="flex flex-col items-stretch p-4 gap-6 border-l border-base-300 bg-base-100"
|
||||||
>
|
>
|
||||||
<NuxtLink to="/" class="btn btn-warning btn-xl">
|
<div class="btn btn-warning btn-xl" @click="$emit('home')">
|
||||||
Wróć na stronę główną
|
Wróć na stronę główną
|
||||||
</NuxtLink>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-info btn-lg" @click="emit('changeNow', 'basic')">
|
<button class="btn btn-info btn-lg" @click="emit('changeNow', 'basic')">
|
||||||
Pytania podstawowe
|
Pytania podstawowe
|
||||||
|
|
@ -37,10 +39,12 @@ const emit = defineEmits<{
|
||||||
class="btn btn-md"
|
class="btn btn-md"
|
||||||
name="chooser"
|
name="chooser"
|
||||||
:class="`${
|
:class="`${
|
||||||
result.basic[num].question?.correct_answer ===
|
result.basic[num].chosen_answer == ''
|
||||||
result.basic[num].chosen_answer
|
? 'btn-warning'
|
||||||
? 'btn-success'
|
: result.basic[num].question?.correct_answer ===
|
||||||
: 'btn-error'
|
result.basic[num].chosen_answer
|
||||||
|
? 'btn-success'
|
||||||
|
: 'btn-error'
|
||||||
} ${now === 'basic' && countBasic === num ? 'outline-set-solid outline-2' : ''}`"
|
} ${now === 'basic' && countBasic === num ? 'outline-set-solid outline-2' : ''}`"
|
||||||
:checked="now === 'basic' ? countBasic === num : false"
|
:checked="now === 'basic' ? countBasic === num : false"
|
||||||
@click="
|
@click="
|
||||||
|
|
@ -65,10 +69,12 @@ const emit = defineEmits<{
|
||||||
class="btn btn-md"
|
class="btn btn-md"
|
||||||
name="chooser"
|
name="chooser"
|
||||||
:class="`${
|
:class="`${
|
||||||
result.advanced[num].question?.correct_answer ===
|
result.advanced[num].chosen_answer == ''
|
||||||
result.advanced[num].chosen_answer
|
? 'btn-warning'
|
||||||
? 'btn-success'
|
: result.advanced[num].question?.correct_answer ===
|
||||||
: 'btn-error'
|
result.advanced[num].chosen_answer
|
||||||
|
? 'btn-success'
|
||||||
|
: 'btn-error'
|
||||||
} ${now === 'advanced' && countAdvanced === num ? 'outline-set-solid outline-2' : ''}`"
|
} ${now === 'advanced' && countAdvanced === num ? 'outline-set-solid outline-2' : ''}`"
|
||||||
:checked="now === 'advanced' ? countAdvanced === num : false"
|
:checked="now === 'advanced' ? countAdvanced === num : false"
|
||||||
@click="
|
@click="
|
||||||
|
|
@ -81,14 +87,8 @@ const emit = defineEmits<{
|
||||||
<div class="*:inline">Punkty: <slot name="points" /> / 74</div>
|
<div class="*:inline">Punkty: <slot name="points" /> / 74</div>
|
||||||
<div class="*:inline">Wynik: <slot name="resultTrueFalse" /></div>
|
<div class="*:inline">Wynik: <slot name="resultTrueFalse" /></div>
|
||||||
</div>
|
</div>
|
||||||
<NuxtLink to="/exam" class="btn btn-warning btn-xl">
|
<div class="btn btn-warning btn-xl" @click="$emit('again')">
|
||||||
Rozpocznij jeszcze raz
|
Rozpocznij jeszcze raz
|
||||||
</NuxtLink>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.outline-set-solid {
|
|
||||||
outline-style: solid;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,36 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
defineProps<{
|
import { onKeyStroke } from '@vueuse/core';
|
||||||
question: AdvancedQuestion | undefined;
|
|
||||||
|
const props = defineProps<{
|
||||||
|
question: Question;
|
||||||
|
phase: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const answer = defineModel<string | null | undefined>();
|
const answer = defineModel<string | null | undefined>();
|
||||||
|
|
||||||
|
const aButton = useTemplateRef('A-button');
|
||||||
|
|
||||||
|
onKeyStroke(['A', 'a'], () => {
|
||||||
|
if (props.phase != 'result') {
|
||||||
|
aButton.value[0].click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const bButton = useTemplateRef('B-button');
|
||||||
|
|
||||||
|
onKeyStroke(['B', 'b'], () => {
|
||||||
|
if (props.phase != 'result') {
|
||||||
|
bButton.value[0].click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const cButton = useTemplateRef('C-button');
|
||||||
|
|
||||||
|
onKeyStroke(['C', 'c'], () => {
|
||||||
|
if (props.phase != 'result') {
|
||||||
|
cButton.value[0].click();
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -16,14 +43,15 @@ const answer = defineModel<string | null | undefined>();
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
<div
|
<div
|
||||||
v-for="[element, value] of Object.entries({
|
v-for="[element, value] of Object.entries({
|
||||||
A: question?.answer_a,
|
A: (question as AdvancedQuestion)?.answer_a,
|
||||||
B: question?.answer_b,
|
B: (question as AdvancedQuestion)?.answer_b,
|
||||||
C: question?.answer_c,
|
C: (question as AdvancedQuestion)?.answer_c,
|
||||||
})"
|
})"
|
||||||
:key="`btn_answer_${element}_${value}`"
|
:key="`btn_answer_${element}_${value}`"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
:id="`odp_${element}`"
|
:id="`odp_${element}`"
|
||||||
|
:ref="`${element}-button`"
|
||||||
v-model="answer"
|
v-model="answer"
|
||||||
type="radio"
|
type="radio"
|
||||||
name="abc"
|
name="abc"
|
||||||
|
|
@ -32,7 +60,13 @@ const answer = defineModel<string | null | undefined>();
|
||||||
/>
|
/>
|
||||||
<label :for="`odp_${element}`">
|
<label :for="`odp_${element}`">
|
||||||
<div
|
<div
|
||||||
:class="answer === element ? ' !btn-secondary' : ''"
|
:class="
|
||||||
|
phase == 'exam'
|
||||||
|
? answer === element
|
||||||
|
? ' !btn-secondary'
|
||||||
|
: ''
|
||||||
|
: `${answer === element ? 'outline-set-solid outline-2' : ''} ${element == question?.correct_answer ? 'btn-success' : 'btn-error'}`
|
||||||
|
"
|
||||||
class="btn btn-primary btn-lg"
|
class="btn btn-primary btn-lg"
|
||||||
>
|
>
|
||||||
{{ element }}
|
{{ element }}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,28 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
defineProps<{
|
import { onKeyStroke } from '@vueuse/core';
|
||||||
question: BasicQuestion | undefined;
|
|
||||||
|
const props = defineProps<{
|
||||||
|
question: Question;
|
||||||
|
phase: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const answer = defineModel<string | null | undefined>();
|
const answer = defineModel<string | null | undefined>();
|
||||||
|
|
||||||
|
const yesButton = useTemplateRef('true-button');
|
||||||
|
|
||||||
|
onKeyStroke(['T', 't', 'Y', 'y'], () => {
|
||||||
|
if (props.phase != 'result') {
|
||||||
|
yesButton.value[0].click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const noButton = useTemplateRef('false-button');
|
||||||
|
|
||||||
|
onKeyStroke(['N', 'n'], () => {
|
||||||
|
if (props.phase != 'result') {
|
||||||
|
noButton.value[0].click();
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -18,6 +37,7 @@ const answer = defineModel<string | null | undefined>();
|
||||||
<input
|
<input
|
||||||
v-for="[element, value] of Object.entries({ TAK: true, NIE: false })"
|
v-for="[element, value] of Object.entries({ TAK: true, NIE: false })"
|
||||||
:id="`odp_${element}`"
|
:id="`odp_${element}`"
|
||||||
|
:ref="`${value}-button`"
|
||||||
:key="`btn_answer_${element}`"
|
:key="`btn_answer_${element}`"
|
||||||
v-model="answer"
|
v-model="answer"
|
||||||
type="radio"
|
type="radio"
|
||||||
|
|
@ -26,11 +46,21 @@ const answer = defineModel<string | null | undefined>();
|
||||||
class="btn btn-primary btn-xl"
|
class="btn btn-primary btn-xl"
|
||||||
:aria-label="element"
|
:aria-label="element"
|
||||||
:class="
|
:class="
|
||||||
answer == null
|
phase == 'exam'
|
||||||
? false
|
? answer == null
|
||||||
: answer === value.toString()
|
? false
|
||||||
? '!btn-secondary'
|
: answer === value.toString()
|
||||||
: ''
|
? '!btn-secondary'
|
||||||
|
: ''
|
||||||
|
: `${
|
||||||
|
answer === value.toString()
|
||||||
|
? 'outline-set-solid outline-2'
|
||||||
|
: ''
|
||||||
|
} ${
|
||||||
|
question?.correct_answer?.toString() == value.toString()
|
||||||
|
? ' btn-success'
|
||||||
|
: ' btn-error'
|
||||||
|
}`
|
||||||
"
|
"
|
||||||
:checked="answer == null ? false : answer === value.toString()"
|
:checked="answer == null ? false : answer === value.toString()"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
BIN
db/database.db
Normal file
BIN
db/database.db
Normal file
Binary file not shown.
36
db/schema.ts
Normal file
36
db/schema.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { sqliteTable, text, int } from 'drizzle-orm/sqlite-core';
|
||||||
|
|
||||||
|
|
||||||
|
export const tasks = sqliteTable('tasks', {
|
||||||
|
id: int().notNull(),
|
||||||
|
correct_answer: text(),
|
||||||
|
media_url: text(),
|
||||||
|
weight: int(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const questions = sqliteTable('questions', {
|
||||||
|
task_id: int(),
|
||||||
|
lang: text(),
|
||||||
|
text: text(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const tasks_advanced = sqliteTable('tasks_advanced', {
|
||||||
|
id: int().notNull(),
|
||||||
|
correct_answer: text(),
|
||||||
|
media_url: text(),
|
||||||
|
weight: int(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const questions_advanced = sqliteTable('questions_advanced', {
|
||||||
|
task_id: int(),
|
||||||
|
lang: text(),
|
||||||
|
text: text(),
|
||||||
|
answer_a: text(),
|
||||||
|
answer_b: text(),
|
||||||
|
answer_c: text(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const categories_db = sqliteTable('categories', {
|
||||||
|
name: text(),
|
||||||
|
task_id: int(),
|
||||||
|
});
|
||||||
|
|
@ -2,9 +2,9 @@ import 'dotenv/config';
|
||||||
import { defineConfig } from 'drizzle-kit';
|
import { defineConfig } from 'drizzle-kit';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
dialect: 'postgresql',
|
|
||||||
schema: './src/db/schema.ts',
|
|
||||||
out: './drizzle',
|
out: './drizzle',
|
||||||
|
schema: './db/schema.ts',
|
||||||
|
dialect: 'sqlite',
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
url: process.env.DATABASE_URL!,
|
url: process.env.DATABASE_URL!,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
export default defineNuxtRouteMiddleware(async () => {
|
export default defineNuxtRouteMiddleware(async () => {
|
||||||
const examStore = useExamStore();
|
const examStore = useExamStore();
|
||||||
|
if (examStore.end) {
|
||||||
if (examStore.category === '') {
|
return '/result';
|
||||||
examStore.resetExam();
|
}
|
||||||
return navigateTo('/');
|
if (examStore.category === '') {
|
||||||
|
return '/anomaly';
|
||||||
}
|
}
|
||||||
examStore.mildReset();
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
export default defineNuxtRouteMiddleware(() => {
|
export default defineNuxtRouteMiddleware(async () => {
|
||||||
const examStore = useExamStore();
|
const examStore = useExamStore();
|
||||||
|
if (!examStore.end || examStore.category === '') {
|
||||||
if (!examStore.end) {
|
return '/anomaly';
|
||||||
examStore.resetExam();
|
|
||||||
return navigateTo('/');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@ export default defineNuxtConfig({
|
||||||
'@nuxtjs/tailwindcss',
|
'@nuxtjs/tailwindcss',
|
||||||
'@nuxt/fonts',
|
'@nuxt/fonts',
|
||||||
'@pinia/nuxt',
|
'@pinia/nuxt',
|
||||||
|
'pinia-plugin-persistedstate/nuxt',
|
||||||
'@nuxt/eslint',
|
'@nuxt/eslint',
|
||||||
'@nuxt/image',
|
'@nuxt/image',
|
||||||
],
|
],
|
||||||
ssr: true,
|
ssr: false,
|
||||||
imports: {
|
imports: {
|
||||||
dirs: ['types/*.ts', 'store/*.ts', 'types/**/*.ts'],
|
dirs: ['types/*.ts', 'store/*.ts', 'types/**/*.ts'],
|
||||||
},
|
},
|
||||||
|
|
@ -46,4 +47,7 @@ export default defineNuxtConfig({
|
||||||
},
|
},
|
||||||
provider: 'selfhost',
|
provider: 'selfhost',
|
||||||
},
|
},
|
||||||
|
pinia: {
|
||||||
|
storesDirs: ['./store/**'],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,12 @@
|
||||||
"tsc": "nuxi typecheck"
|
"tsc": "nuxi typecheck"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@libsql/client": "^0.15.15",
|
||||||
"@nuxt/fonts": "0.11.1",
|
"@nuxt/fonts": "0.11.1",
|
||||||
"@nuxt/image": "1.10.0",
|
"@nuxt/image": "1.10.0",
|
||||||
"@nuxtjs/tailwindcss": "6.13.2",
|
"@nuxtjs/tailwindcss": "6.13.2",
|
||||||
"@pinia/nuxt": "0.11.0",
|
"@pinia/nuxt": "0.11.0",
|
||||||
|
"@vueuse/core": "^14.1.0",
|
||||||
"array-shuffle": "^3.0.0",
|
"array-shuffle": "^3.0.0",
|
||||||
"daisyui": "^5.0.27",
|
"daisyui": "^5.0.27",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
|
|
@ -27,8 +29,8 @@
|
||||||
"eslint": "^9.24.0",
|
"eslint": "^9.24.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"nuxt": "~3.16.2",
|
"nuxt": "~3.16.2",
|
||||||
"pg": "^8.14.1",
|
|
||||||
"pinia": "^3.0.2",
|
"pinia": "^3.0.2",
|
||||||
|
"pinia-plugin-persistedstate": "^4.7.1",
|
||||||
"ufo": "^1.6.1",
|
"ufo": "^1.6.1",
|
||||||
"vue": "latest",
|
"vue": "latest",
|
||||||
"vue-router": "latest"
|
"vue-router": "latest"
|
||||||
|
|
@ -37,7 +39,6 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/eslint": "1.3.0",
|
"@nuxt/eslint": "1.3.0",
|
||||||
"@types/lodash": "^4.17.16",
|
"@types/lodash": "^4.17.16",
|
||||||
"@types/pg": "^8.11.13",
|
|
||||||
"eslint-config-prettier": "^10.1.2",
|
"eslint-config-prettier": "^10.1.2",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"tsx": "^4.19.3",
|
"tsx": "^4.19.3",
|
||||||
|
|
|
||||||
22
pages/anomaly.vue
Normal file
22
pages/anomaly.vue
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
const examStore = useExamStore();
|
||||||
|
const basicStore = useBasicStore();
|
||||||
|
const advancedStore = useAdvancedStore();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex flex-col gap-2 items-start m-2">
|
||||||
|
<h1 class="text-2xl">Nastąpiła anomalia</h1>
|
||||||
|
<br />
|
||||||
|
Przekierowanie z: {{ useRoute().redirectedFrom ?? '""' }} <br />
|
||||||
|
Kategoria:
|
||||||
|
{{ examStore.category != '' ? examStore.category : '""' }}
|
||||||
|
<br />
|
||||||
|
Koniec: {{ examStore.end }} <br />
|
||||||
|
Pytania podstawowe: <code class="text-xs">{{ basicStore.basic }}</code>
|
||||||
|
<br />
|
||||||
|
Pytania specjalistyczne:
|
||||||
|
<code class="text-xs">{{ advancedStore.advanced }}</code> <br />
|
||||||
|
<NuxtLink to="/" class="btn btn-primary"> Wróć na stronę główną </NuxtLink>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
179
pages/exam.vue
179
pages/exam.vue
|
|
@ -1,32 +1,92 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { intervalToDuration, addMinutes, addSeconds, isEqual } from 'date-fns';
|
import { intervalToDuration, addMinutes, addSeconds, isAfter } from 'date-fns';
|
||||||
|
import { useNow } from '@vueuse/core';
|
||||||
import { useExamStore } from '~/store/examStore';
|
import { useExamStore } from '~/store/examStore';
|
||||||
|
|
||||||
definePageMeta({ middleware: ['exam'] });
|
definePageMeta({ middleware: 'exam' });
|
||||||
|
|
||||||
useHead({
|
const examStore = useExamStore();
|
||||||
title: 'Pytanie 1/20',
|
const basicStore = useBasicStore();
|
||||||
});
|
const advancedStore = useAdvancedStore();
|
||||||
|
await callOnce(() => examStore.mildReset(), { mode: 'navigation' });
|
||||||
|
|
||||||
const nowTime = ref(new Date());
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
function preventRefresh(e: any) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.returnValue = ''; // polyfill for older chrome
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = ref('basic');
|
||||||
|
|
||||||
|
const nowTime = useNow();
|
||||||
const timeEnd = addMinutes(new Date(), 25);
|
const timeEnd = addMinutes(new Date(), 25);
|
||||||
|
|
||||||
const timeRemainingTotal = computed(() =>
|
const questionEnd = ref(addSeconds(new Date(), 20));
|
||||||
intervalToDuration({
|
|
||||||
start: nowTime.value,
|
const mediaLoaded = ref(false);
|
||||||
end: timeEnd,
|
|
||||||
|
const time = ref({
|
||||||
|
total: computed(() =>
|
||||||
|
intervalToDuration({
|
||||||
|
start: nowTime.value,
|
||||||
|
end: timeEnd,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
question: computed(() => {
|
||||||
|
const interval = intervalToDuration({
|
||||||
|
start: nowTime.value,
|
||||||
|
end: questionEnd.value,
|
||||||
|
});
|
||||||
|
if (Object.hasOwn(interval, 'seconds') && interval.seconds != undefined) {
|
||||||
|
return interval.seconds;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
phase: 'set-basic',
|
||||||
// const timeRemainingQuestion - to implement
|
});
|
||||||
|
|
||||||
|
function changeQuestionTimeAfterNext() {
|
||||||
|
if (time.value.phase == 'set-basic') {
|
||||||
|
time.value.phase = 'start-basic';
|
||||||
|
questionEnd.value = addSeconds(new Date(), 15);
|
||||||
|
} else if (time.value.phase == 'start-basic') {
|
||||||
|
if (now.value == 'basic') {
|
||||||
|
time.value.phase = 'set-basic';
|
||||||
|
mediaLoaded.value = false;
|
||||||
|
questionEnd.value = addSeconds(new Date(), 20);
|
||||||
|
} else {
|
||||||
|
time.value.phase = 'set-advanced';
|
||||||
|
questionEnd.value = addSeconds(new Date(), 50);
|
||||||
|
}
|
||||||
|
} else if (time.value.phase == 'set-advanced') {
|
||||||
|
questionEnd.value = addSeconds(new Date(), 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMediaLoad() {
|
||||||
|
mediaLoaded.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickNext() {
|
||||||
|
if (ending.value) {
|
||||||
|
endExam();
|
||||||
|
}
|
||||||
|
if (time.value.phase != 'set-basic') {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
changeQuestionTimeAfterNext();
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const endInterval = setInterval(() => {
|
useHead({
|
||||||
nowTime.value = addSeconds(nowTime.value, 1);
|
title: 'Pytanie 1/20',
|
||||||
if (isEqual(nowTime.value, timeEnd)) {
|
});
|
||||||
clearInterval(endInterval);
|
window.addEventListener('beforeunload', preventRefresh);
|
||||||
endExam();
|
|
||||||
}
|
watchEffect(() => {
|
||||||
}, 1000);
|
if (isAfter(nowTime.value, timeEnd)) endExam();
|
||||||
|
});
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (now.value === 'basic')
|
if (now.value === 'basic')
|
||||||
|
|
@ -34,9 +94,20 @@ onMounted(() => {
|
||||||
if (now.value === 'advanced')
|
if (now.value === 'advanced')
|
||||||
useHead({ title: `Pytanie ${countAdvanced.value + 1}/12` });
|
useHead({ title: `Pytanie ${countAdvanced.value + 1}/12` });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
if (mediaLoaded.value == false && time.value.phase == 'start-basic') {
|
||||||
|
questionEnd.value = addSeconds(new Date(), 15);
|
||||||
|
}
|
||||||
|
if (time.value.question < 0 && ending.value == false) {
|
||||||
|
clickNext();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const examStore = useExamStore();
|
onBeforeUnmount(() => {
|
||||||
|
window.removeEventListener('beforeunload', preventRefresh);
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: dataBasic,
|
data: dataBasic,
|
||||||
|
|
@ -61,7 +132,6 @@ const {
|
||||||
const countBasic = ref(0);
|
const countBasic = ref(0);
|
||||||
const countAdvanced = ref(-1);
|
const countAdvanced = ref(-1);
|
||||||
|
|
||||||
const now = ref('basic');
|
|
||||||
const answer = ref<string>('');
|
const answer = ref<string>('');
|
||||||
|
|
||||||
const ending = ref(false);
|
const ending = ref(false);
|
||||||
|
|
@ -84,28 +154,30 @@ const result: Ref<ResultEndType> = ref({
|
||||||
advanced: [],
|
advanced: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
async function next() {
|
function next() {
|
||||||
if (now.value === 'basic' || now.value === 'advanced') {
|
if (examStore.end == false) {
|
||||||
result.value[now.value].push({
|
result.value[now.value as keyof ResultEndType].push({
|
||||||
question: question.value,
|
question: question.value,
|
||||||
chosen_answer: answer.value,
|
chosen_answer: answer.value,
|
||||||
chosen_is_correct: answer.value === question.value?.correct_answer,
|
correct_answer: question.value?.correct_answer ?? null,
|
||||||
|
chosen_is_correct: answer.value == question.value?.correct_answer,
|
||||||
});
|
});
|
||||||
|
answer.value = '';
|
||||||
|
} else {
|
||||||
|
console.error('next() incorrectly executed - exam has already ended.');
|
||||||
}
|
}
|
||||||
answer.value = '';
|
|
||||||
|
|
||||||
if (now.value === 'basic') {
|
if (now.value === 'basic') {
|
||||||
if (countBasic.value < 19) {
|
if (countBasic.value + 1 <= 19) {
|
||||||
countBasic.value++;
|
countBasic.value++;
|
||||||
} else {
|
} else {
|
||||||
now.value = 'advanced';
|
now.value = 'advanced';
|
||||||
countAdvanced.value++;
|
countAdvanced.value++;
|
||||||
}
|
}
|
||||||
} else if (now.value === 'advanced') {
|
} else if (now.value === 'advanced') {
|
||||||
if (countAdvanced.value < 11) {
|
if (countAdvanced.value + 1 <= 11) {
|
||||||
countAdvanced.value++;
|
countAdvanced.value++;
|
||||||
}
|
}
|
||||||
if (countAdvanced.value >= 11) {
|
if (countAdvanced.value + 1 >= 12) {
|
||||||
ending.value = true;
|
ending.value = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -113,20 +185,30 @@ async function next() {
|
||||||
|
|
||||||
function endExam() {
|
function endExam() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
while (!ending.value) {
|
while (ending.value == false) {
|
||||||
next();
|
if (time.value.phase != 'set-basic') {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
changeQuestionTimeAfterNext();
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
examStore.setResult(result.value);
|
basicStore.set(result.value.basic);
|
||||||
|
advancedStore.set(result.value.advanced);
|
||||||
examStore.setEnd(true);
|
examStore.setEnd(true);
|
||||||
while (true) {
|
if (
|
||||||
if (examStore.result == result.value && examStore.end) {
|
basicStore.basic == result.value.basic &&
|
||||||
return navigateTo('/result', { replace: true });
|
advancedStore.advanced == result.value.advanced &&
|
||||||
}
|
examStore.end
|
||||||
|
) {
|
||||||
|
return navigateTo(`/result`, { replace: true });
|
||||||
|
} else {
|
||||||
|
return navigateTo(`/anomaly`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const showEndModal = ref(false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -139,28 +221,38 @@ const loading = ref(false);
|
||||||
<BarTop
|
<BarTop
|
||||||
:points="question?.weight"
|
:points="question?.weight"
|
||||||
:category="examStore.category"
|
:category="examStore.category"
|
||||||
:time-remaining="timeRemainingTotal"
|
:time-remaining="time.total"
|
||||||
|
/>
|
||||||
|
<MediaBox
|
||||||
|
:media-path="question?.media_url"
|
||||||
|
:phase="time.phase"
|
||||||
|
@mediaload="onMediaLoad()"
|
||||||
/>
|
/>
|
||||||
<MediaBox :media-path="question?.media_url" />
|
|
||||||
<QuestionBasic
|
<QuestionBasic
|
||||||
v-if="now === 'basic'"
|
v-if="now === 'basic'"
|
||||||
v-model="answer"
|
v-model="answer"
|
||||||
|
phase="exam"
|
||||||
:question="questionBasic"
|
:question="questionBasic"
|
||||||
/>
|
/>
|
||||||
<QuestionAdvanced
|
<QuestionAdvanced
|
||||||
v-else-if="now === 'advanced'"
|
v-else-if="now === 'advanced'"
|
||||||
v-model="answer"
|
v-model="answer"
|
||||||
|
phase="exam"
|
||||||
:question="questionAdvanced"
|
:question="questionAdvanced"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BarRightExam
|
<BarRightExam
|
||||||
:count-basic="countBasic"
|
:count-basic="countBasic"
|
||||||
:count-advanced="countAdvanced"
|
:count-advanced="countAdvanced"
|
||||||
:now="now"
|
:now="now"
|
||||||
:ending="ending"
|
:ending="ending"
|
||||||
@next-question="next()"
|
:set-basic="time.phase == 'set-basic'"
|
||||||
|
:time="time.question"
|
||||||
|
:phase="time.phase"
|
||||||
|
@show-end-modal="showEndModal = true"
|
||||||
|
@next-question="clickNext()"
|
||||||
@end-exam="endExam()"
|
@end-exam="endExam()"
|
||||||
|
@next-time="changeQuestionTimeAfterNext()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -168,5 +260,10 @@ const loading = ref(false);
|
||||||
An API error occurred: {{ errorBasic }} {{ errorAdvanced }}
|
An API error occurred: {{ errorBasic }} {{ errorAdvanced }}
|
||||||
</div>
|
</div>
|
||||||
<LoadingScreen v-else />
|
<LoadingScreen v-else />
|
||||||
|
<EndModal
|
||||||
|
:show-modal="showEndModal"
|
||||||
|
@hide-end-modal="showEndModal = false"
|
||||||
|
@end-exam="endExam()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import categories from '~/categories';
|
import categories, { opis, wiek } from '~/categories';
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
useHead({
|
useHead({
|
||||||
|
|
@ -10,6 +10,7 @@ onMounted(() => {
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
const examStore = useExamStore();
|
const examStore = useExamStore();
|
||||||
|
await callOnce(() => examStore.resetExam(), { mode: 'navigation' });
|
||||||
|
|
||||||
function setAndGo(category: string) {
|
function setAndGo(category: string) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
@ -24,22 +25,24 @@ function setAndGo(category: string) {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="!loading" class="text-3xl">
|
<div v-if="!loading" class="text-3xl m-2 flex flex-col gap-2">
|
||||||
<span>Test na prawo jazdy</span>
|
<span>Test na prawo jazdy</span>
|
||||||
<p>
|
<div
|
||||||
Witaj w teście na prawo jazdy, aby rozpocząć, naciśnij jeden z
|
class="flex flex-col flex-wrap gap-2 items-start p-4 bg-slate-100 border-1 border-slate-500 rounded-xl w-fit"
|
||||||
poniższych przycisków:
|
>
|
||||||
<br />
|
<div
|
||||||
</p>
|
v-for="[index, category] of categories.entries()"
|
||||||
<div class="flex flex-row flex-wrap gap-2">
|
|
||||||
<button
|
|
||||||
v-for="category in categories"
|
|
||||||
:key="`btn-${category}`"
|
:key="`btn-${category}`"
|
||||||
class="btn btn-xl btn-secondary"
|
class="flex flex-row gap-3 items-center"
|
||||||
@click="setAndGo(category)"
|
|
||||||
>
|
>
|
||||||
{{ category }}
|
<button class="btn btn-xl btn-secondary" @click="setAndGo(category)">
|
||||||
</button>
|
{{ category }}
|
||||||
|
</button>
|
||||||
|
<div class="flex flex-col text-sm">
|
||||||
|
<div>{{ opis[index] }}</div>
|
||||||
|
<div>{{ wiek[index] }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<LoadingScreen v-else />
|
<LoadingScreen v-else />
|
||||||
|
|
|
||||||
114
pages/result.vue
114
pages/result.vue
|
|
@ -5,14 +5,19 @@ definePageMeta({ middleware: ['result'] });
|
||||||
|
|
||||||
const examStore = useExamStore();
|
const examStore = useExamStore();
|
||||||
|
|
||||||
|
const basicStore = useBasicStore();
|
||||||
|
const advancedStore = useAdvancedStore();
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
const points = ref<number>(0);
|
const points = ref<number>(0);
|
||||||
|
|
||||||
examStore.result.basic.forEach((answer) => {
|
basicStore.basic.forEach((answer) => {
|
||||||
if (answer.chosen_is_correct) {
|
if (answer.chosen_is_correct) {
|
||||||
points.value += answer.question?.weight ?? 0;
|
points.value += answer.question?.weight ?? 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
examStore.result.advanced.forEach((answer) => {
|
advancedStore.advanced.forEach((answer) => {
|
||||||
if (answer.chosen_is_correct) {
|
if (answer.chosen_is_correct) {
|
||||||
points.value += answer.question?.weight ?? 0;
|
points.value += answer.question?.weight ?? 0;
|
||||||
}
|
}
|
||||||
|
|
@ -32,17 +37,17 @@ onMounted(() => {
|
||||||
const countBasic = ref(0);
|
const countBasic = ref(0);
|
||||||
const countAdvanced = ref(0);
|
const countAdvanced = ref(0);
|
||||||
|
|
||||||
const resultQuestionBasic = computed<ResultType<BasicQuestion> | undefined>(
|
const resultQuestionBasic = computed<ResultType | undefined>(() =>
|
||||||
() => examStore.result.basic.at(countBasic.value),
|
basicStore.basic.at(countBasic.value),
|
||||||
|
);
|
||||||
|
const resultQuestionAdvanced = computed<ResultType | undefined>(() =>
|
||||||
|
advancedStore.advanced.at(countAdvanced.value),
|
||||||
);
|
);
|
||||||
const resultQuestionAdvanced = computed<
|
|
||||||
ResultType<AdvancedQuestion> | undefined
|
|
||||||
>(() => examStore.result.advanced.at(countAdvanced.value));
|
|
||||||
|
|
||||||
const questionBasic = computed<BasicQuestion | undefined>(
|
const questionBasic = computed<Question>(
|
||||||
() => resultQuestionBasic.value?.question,
|
() => resultQuestionBasic.value?.question,
|
||||||
);
|
);
|
||||||
const questionAdvanced = computed<AdvancedQuestion | undefined>(
|
const questionAdvanced = computed<Question>(
|
||||||
() => resultQuestionAdvanced.value?.question,
|
() => resultQuestionAdvanced.value?.question,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -81,46 +86,67 @@ function changeCount(num: number) {
|
||||||
countAdvanced.value = num;
|
countAdvanced.value = num;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function again() {
|
||||||
|
loading.value = true;
|
||||||
|
await examStore.mildReset();
|
||||||
|
return await navigateTo('/exam');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function home() {
|
||||||
|
loading.value = true;
|
||||||
|
await examStore.resetExam();
|
||||||
|
return await navigateTo('/');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<ResultModal>
|
<LoadingScreen v-if="loading" />
|
||||||
<template #title>Egzamin teorytyczny</template>
|
<div v-else>
|
||||||
<template #category>{{ examStore.category }}</template>
|
<ResultModal @again="again" @home="home">
|
||||||
<template #points>{{ points }}</template>
|
<template #title>Egzamin teorytyczny</template>
|
||||||
<template #resultTrueFalse>{{ resultTrueFalse }}</template>
|
<template #category>{{ examStore.category }}</template>
|
||||||
</ResultModal>
|
<template #points>{{ points }}</template>
|
||||||
<div>
|
<template #resultTrueFalse>{{ resultTrueFalse }} </template>
|
||||||
<div class="grid grid-cols-4 min-h-dvh">
|
</ResultModal>
|
||||||
<div class="col-span-3 flex flex-col">
|
<div>
|
||||||
<BarTop :points="question?.weight" :category="examStore.category" />
|
<div class="grid grid-cols-4 min-h-dvh">
|
||||||
<MediaBox :media-path="question?.media_url" />
|
<div class="col-span-3 flex flex-col">
|
||||||
<QuestionBasic
|
<BarTop :points="question?.weight" :category="examStore.category" />
|
||||||
v-if="now === 'basic'"
|
<MediaBox :media-path="question?.media_url" phase="" />
|
||||||
v-model="answer"
|
<QuestionBasic
|
||||||
:question="questionBasic"
|
v-if="now === 'basic'"
|
||||||
class="select-none z-[-1]"
|
v-model="answer"
|
||||||
/>
|
:question="questionBasic"
|
||||||
<QuestionAdvanced
|
phase="result"
|
||||||
v-else-if="now === 'advanced'"
|
class="select-none z-[-1]"
|
||||||
v-model="answer"
|
/>
|
||||||
:question="questionAdvanced"
|
<QuestionAdvanced
|
||||||
class="select-none z-[-1]"
|
v-else-if="now === 'advanced'"
|
||||||
/>
|
v-model="answer"
|
||||||
|
:question="questionAdvanced"
|
||||||
|
phase="result"
|
||||||
|
class="select-none z-[-1]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<BarRightResult
|
||||||
|
:result="{
|
||||||
|
basic: basicStore.basic,
|
||||||
|
advanced: advancedStore.advanced,
|
||||||
|
}"
|
||||||
|
:count-basic="countBasic"
|
||||||
|
:count-advanced="countAdvanced"
|
||||||
|
:now="now"
|
||||||
|
@change-now="changeNow"
|
||||||
|
@change-count="changeCount"
|
||||||
|
@home="home"
|
||||||
|
@again="again"
|
||||||
|
>
|
||||||
|
<template #points>{{ points }}</template>
|
||||||
|
<template #resultTrueFalse>{{ resultTrueFalse }}</template>
|
||||||
|
</BarRightResult>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BarRightResult
|
|
||||||
:result="examStore.result"
|
|
||||||
:count-basic="countBasic"
|
|
||||||
:count-advanced="countAdvanced"
|
|
||||||
:now="now"
|
|
||||||
@change-now="changeNow"
|
|
||||||
@change-count="changeCount"
|
|
||||||
>
|
|
||||||
<template #points>{{ points }}</template>
|
|
||||||
<template #resultTrueFalse>{{ resultTrueFalse }}</template>
|
|
||||||
</BarRightResult>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
388
pnpm-lock.yaml
generated
388
pnpm-lock.yaml
generated
|
|
@ -8,24 +8,30 @@ importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@libsql/client':
|
||||||
|
specifier: ^0.15.15
|
||||||
|
version: 0.15.15
|
||||||
'@nuxt/fonts':
|
'@nuxt/fonts':
|
||||||
specifier: 0.11.1
|
specifier: 0.11.1
|
||||||
version: 0.11.1(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)(magicast@0.3.5)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))
|
version: 0.11.1(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)(magicast@0.3.5)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))
|
||||||
'@nuxt/image':
|
'@nuxt/image':
|
||||||
specifier: 1.10.0
|
specifier: 1.10.0
|
||||||
version: 1.10.0(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)(magicast@0.3.5)
|
version: 1.10.0(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)(magicast@0.3.5)
|
||||||
'@nuxtjs/tailwindcss':
|
'@nuxtjs/tailwindcss':
|
||||||
specifier: 6.13.2
|
specifier: 6.13.2
|
||||||
version: 6.13.2(magicast@0.3.5)
|
version: 6.13.2(magicast@0.3.5)
|
||||||
'@pinia/nuxt':
|
'@pinia/nuxt':
|
||||||
specifier: 0.11.0
|
specifier: 0.11.0
|
||||||
version: 0.11.0(magicast@0.3.5)(pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)))
|
version: 0.11.0(magicast@0.3.5)(pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)))
|
||||||
|
'@vueuse/core':
|
||||||
|
specifier: ^14.1.0
|
||||||
|
version: 14.1.0(vue@3.5.13(typescript@5.8.3))
|
||||||
array-shuffle:
|
array-shuffle:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
daisyui:
|
daisyui:
|
||||||
specifier: ^5.0.23
|
specifier: ^5.0.27
|
||||||
version: 5.0.23
|
version: 5.2.3
|
||||||
date-fns:
|
date-fns:
|
||||||
specifier: ^4.1.0
|
specifier: ^4.1.0
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
|
|
@ -37,7 +43,7 @@ importers:
|
||||||
version: 0.31.0
|
version: 0.31.0
|
||||||
drizzle-orm:
|
drizzle-orm:
|
||||||
specifier: ^0.42.0
|
specifier: ^0.42.0
|
||||||
version: 0.42.0(@types/pg@8.11.13)(pg@8.14.1)
|
version: 0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^9.24.0
|
specifier: ^9.24.0
|
||||||
version: 9.24.0(jiti@2.4.2)
|
version: 9.24.0(jiti@2.4.2)
|
||||||
|
|
@ -46,13 +52,13 @@ importers:
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
nuxt:
|
nuxt:
|
||||||
specifier: ~3.16.2
|
specifier: ~3.16.2
|
||||||
version: 3.16.2(@parcel/watcher@2.5.1)(@types/node@22.14.1)(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1))(eslint@9.24.0(jiti@2.4.2))(ioredis@5.6.1)(lightningcss@1.29.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.0)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.3)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))(yaml@2.7.1)
|
version: 3.16.2(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@22.14.1)(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1))(eslint@9.24.0(jiti@2.4.2))(ioredis@5.6.1)(lightningcss@1.29.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.0)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.3)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))(yaml@2.7.1)
|
||||||
pg:
|
|
||||||
specifier: ^8.14.1
|
|
||||||
version: 8.14.1
|
|
||||||
pinia:
|
pinia:
|
||||||
specifier: ^3.0.2
|
specifier: ^3.0.2
|
||||||
version: 3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))
|
version: 3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))
|
||||||
|
pinia-plugin-persistedstate:
|
||||||
|
specifier: ^4.7.1
|
||||||
|
version: 4.7.1(@nuxt/kit@3.16.2(magicast@0.3.5))(@pinia/nuxt@0.11.0(magicast@0.3.5)(pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))))(pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)))
|
||||||
ufo:
|
ufo:
|
||||||
specifier: ^1.6.1
|
specifier: ^1.6.1
|
||||||
version: 1.6.1
|
version: 1.6.1
|
||||||
|
|
@ -69,9 +75,6 @@ importers:
|
||||||
'@types/lodash':
|
'@types/lodash':
|
||||||
specifier: ^4.17.16
|
specifier: ^4.17.16
|
||||||
version: 4.17.16
|
version: 4.17.16
|
||||||
'@types/pg':
|
|
||||||
specifier: ^8.11.13
|
|
||||||
version: 8.11.13
|
|
||||||
eslint-config-prettier:
|
eslint-config-prettier:
|
||||||
specifier: ^10.1.2
|
specifier: ^10.1.2
|
||||||
version: 10.1.2(eslint@9.24.0(jiti@2.4.2))
|
version: 10.1.2(eslint@9.24.0(jiti@2.4.2))
|
||||||
|
|
@ -678,6 +681,67 @@ packages:
|
||||||
'@kwsites/promise-deferred@1.1.1':
|
'@kwsites/promise-deferred@1.1.1':
|
||||||
resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
|
resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
|
||||||
|
|
||||||
|
'@libsql/client@0.15.15':
|
||||||
|
resolution: {integrity: sha512-twC0hQxPNHPKfeOv3sNT6u2pturQjLcI+CnpTM0SjRpocEGgfiZ7DWKXLNnsothjyJmDqEsBQJ5ztq9Wlu470w==}
|
||||||
|
|
||||||
|
'@libsql/core@0.15.15':
|
||||||
|
resolution: {integrity: sha512-C88Z6UKl+OyuKKPwz224riz02ih/zHYI3Ho/LAcVOgjsunIRZoBw7fjRfaH9oPMmSNeQfhGklSG2il1URoOIsA==}
|
||||||
|
|
||||||
|
'@libsql/darwin-arm64@0.5.22':
|
||||||
|
resolution: {integrity: sha512-4B8ZlX3nIDPndfct7GNe0nI3Yw6ibocEicWdC4fvQbSs/jdq/RC2oCsoJxJ4NzXkvktX70C1J4FcmmoBy069UA==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@libsql/darwin-x64@0.5.22':
|
||||||
|
resolution: {integrity: sha512-ny2HYWt6lFSIdNFzUFIJ04uiW6finXfMNJ7wypkAD8Pqdm6nAByO+Fdqu8t7sD0sqJGeUCiOg480icjyQ2/8VA==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@libsql/hrana-client@0.7.0':
|
||||||
|
resolution: {integrity: sha512-OF8fFQSkbL7vJY9rfuegK1R7sPgQ6kFMkDamiEccNUvieQ+3urzfDFI616oPl8V7T9zRmnTkSjMOImYCAVRVuw==}
|
||||||
|
|
||||||
|
'@libsql/isomorphic-fetch@0.3.1':
|
||||||
|
resolution: {integrity: sha512-6kK3SUK5Uu56zPq/Las620n5aS9xJq+jMBcNSOmjhNf/MUvdyji4vrMTqD7ptY7/4/CAVEAYDeotUz60LNQHtw==}
|
||||||
|
engines: {node: '>=18.0.0'}
|
||||||
|
|
||||||
|
'@libsql/isomorphic-ws@0.1.5':
|
||||||
|
resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==}
|
||||||
|
|
||||||
|
'@libsql/linux-arm-gnueabihf@0.5.22':
|
||||||
|
resolution: {integrity: sha512-3Uo3SoDPJe/zBnyZKosziRGtszXaEtv57raWrZIahtQDsjxBVjuzYQinCm9LRCJCUT5t2r5Z5nLDPJi2CwZVoA==}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@libsql/linux-arm-musleabihf@0.5.22':
|
||||||
|
resolution: {integrity: sha512-LCsXh07jvSojTNJptT9CowOzwITznD+YFGGW+1XxUr7fS+7/ydUrpDfsMX7UqTqjm7xG17eq86VkWJgHJfvpNg==}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@libsql/linux-arm64-gnu@0.5.22':
|
||||||
|
resolution: {integrity: sha512-KSdnOMy88c9mpOFKUEzPskSaF3VLflfSUCBwas/pn1/sV3pEhtMF6H8VUCd2rsedwoukeeCSEONqX7LLnQwRMA==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@libsql/linux-arm64-musl@0.5.22':
|
||||||
|
resolution: {integrity: sha512-mCHSMAsDTLK5YH//lcV3eFEgiR23Ym0U9oEvgZA0667gqRZg/2px+7LshDvErEKv2XZ8ixzw3p1IrBzLQHGSsw==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@libsql/linux-x64-gnu@0.5.22':
|
||||||
|
resolution: {integrity: sha512-kNBHaIkSg78Y4BqAdgjcR2mBilZXs4HYkAmi58J+4GRwDQZh5fIUWbnQvB9f95DkWUIGVeenqLRFY2pcTmlsew==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@libsql/linux-x64-musl@0.5.22':
|
||||||
|
resolution: {integrity: sha512-UZ4Xdxm4pu3pQXjvfJiyCzZop/9j/eA2JjmhMaAhe3EVLH2g11Fy4fwyUp9sT1QJYR1kpc2JLuybPM0kuXv/Tg==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@libsql/win32-x64-msvc@0.5.22':
|
||||||
|
resolution: {integrity: sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
'@mapbox/node-pre-gyp@2.0.0':
|
'@mapbox/node-pre-gyp@2.0.0':
|
||||||
resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==}
|
resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
@ -686,6 +750,9 @@ packages:
|
||||||
'@napi-rs/wasm-runtime@0.2.8':
|
'@napi-rs/wasm-runtime@0.2.8':
|
||||||
resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==}
|
resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==}
|
||||||
|
|
||||||
|
'@neon-rs/load@0.0.4':
|
||||||
|
resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==}
|
||||||
|
|
||||||
'@netlify/functions@3.0.4':
|
'@netlify/functions@3.0.4':
|
||||||
resolution: {integrity: sha512-Ox8+ABI+nsLK+c4/oC5dpquXuEIjzfTlJrdQKgQijCsDQoje7inXFAtKDLvvaGvuvE+PVpMLwQcIUL6P9Ob1hQ==}
|
resolution: {integrity: sha512-Ox8+ABI+nsLK+c4/oC5dpquXuEIjzfTlJrdQKgQijCsDQoje7inXFAtKDLvvaGvuvE+PVpMLwQcIUL6P9Ob1hQ==}
|
||||||
engines: {node: '>=18.0.0'}
|
engines: {node: '>=18.0.0'}
|
||||||
|
|
@ -1209,6 +1276,12 @@ packages:
|
||||||
'@types/resolve@1.20.2':
|
'@types/resolve@1.20.2':
|
||||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||||
|
|
||||||
|
'@types/web-bluetooth@0.0.21':
|
||||||
|
resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
|
||||||
|
|
||||||
|
'@types/ws@8.18.1':
|
||||||
|
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.30.1':
|
'@typescript-eslint/eslint-plugin@8.30.1':
|
||||||
resolution: {integrity: sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==}
|
resolution: {integrity: sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
@ -1431,6 +1504,19 @@ packages:
|
||||||
'@vue/shared@3.5.13':
|
'@vue/shared@3.5.13':
|
||||||
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
|
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
|
||||||
|
|
||||||
|
'@vueuse/core@14.1.0':
|
||||||
|
resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.5.0
|
||||||
|
|
||||||
|
'@vueuse/metadata@14.1.0':
|
||||||
|
resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==}
|
||||||
|
|
||||||
|
'@vueuse/shared@14.1.0':
|
||||||
|
resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.5.0
|
||||||
|
|
||||||
abbrev@3.0.1:
|
abbrev@3.0.1:
|
||||||
resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==}
|
resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==}
|
||||||
engines: {node: ^18.17.0 || >=20.5.0}
|
engines: {node: ^18.17.0 || >=20.5.0}
|
||||||
|
|
@ -1911,8 +1997,12 @@ packages:
|
||||||
csstype@3.1.3:
|
csstype@3.1.3:
|
||||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||||
|
|
||||||
daisyui@5.0.23:
|
daisyui@5.2.3:
|
||||||
resolution: {integrity: sha512-SIR8yAneeNxvrpaR5kREG1DrPK8XFyfmyvqyZEUTJ2e6tv4Pp56/w+52Vdv34hmSmtAyDldTCEPWx+GvPyp0Yg==}
|
resolution: {integrity: sha512-sldBQUIFCsSPoF4LvoHhIi9GnvBX/3aZD9NoTOvpTSX8sDjO484wQx7yEvRyREMpn4rZMvQSKKskHAHdM8+B4Q==}
|
||||||
|
|
||||||
|
data-uri-to-buffer@4.0.1:
|
||||||
|
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
|
||||||
|
engines: {node: '>= 12'}
|
||||||
|
|
||||||
date-fns@4.1.0:
|
date-fns@4.1.0:
|
||||||
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
|
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
|
||||||
|
|
@ -2021,6 +2111,10 @@ packages:
|
||||||
engines: {node: '>=0.10'}
|
engines: {node: '>=0.10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
detect-libc@2.0.2:
|
||||||
|
resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
detect-libc@2.0.3:
|
detect-libc@2.0.3:
|
||||||
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
@ -2423,6 +2517,10 @@ packages:
|
||||||
picomatch:
|
picomatch:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
fetch-blob@3.2.0:
|
||||||
|
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
|
||||||
|
engines: {node: ^12.20 || >= 14.13}
|
||||||
|
|
||||||
file-entry-cache@8.0.0:
|
file-entry-cache@8.0.0:
|
||||||
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
|
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
|
||||||
engines: {node: '>=16.0.0'}
|
engines: {node: '>=16.0.0'}
|
||||||
|
|
@ -2463,6 +2561,10 @@ packages:
|
||||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
|
formdata-polyfill@4.0.10:
|
||||||
|
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
||||||
|
engines: {node: '>=12.20.0'}
|
||||||
|
|
||||||
fraction.js@4.3.7:
|
fraction.js@4.3.7:
|
||||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||||
|
|
||||||
|
|
@ -2819,6 +2921,9 @@ packages:
|
||||||
resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
|
resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
js-base64@3.7.8:
|
||||||
|
resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==}
|
||||||
|
|
||||||
js-tokens@4.0.0:
|
js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
|
||||||
|
|
@ -2915,6 +3020,10 @@ packages:
|
||||||
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
||||||
|
libsql@0.5.22:
|
||||||
|
resolution: {integrity: sha512-NscWthMQt7fpU8lqd7LXMvT9pi+KhhmTHAJWUB/Lj6MWa0MKFv0F2V4C6WKKpjCVZl0VwcDz4nOI3CyaT1DDiA==}
|
||||||
|
os: [darwin, linux, win32]
|
||||||
|
|
||||||
lightningcss-darwin-arm64@1.29.2:
|
lightningcss-darwin-arm64@1.29.2:
|
||||||
resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==}
|
resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
|
|
@ -3209,6 +3318,11 @@ packages:
|
||||||
node-addon-api@7.1.1:
|
node-addon-api@7.1.1:
|
||||||
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
||||||
|
|
||||||
|
node-domexception@1.0.0:
|
||||||
|
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
||||||
|
engines: {node: '>=10.5.0'}
|
||||||
|
deprecated: Use your platform's native DOMException instead
|
||||||
|
|
||||||
node-fetch-native@1.6.6:
|
node-fetch-native@1.6.6:
|
||||||
resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==}
|
resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==}
|
||||||
|
|
||||||
|
|
@ -3221,6 +3335,10 @@ packages:
|
||||||
encoding:
|
encoding:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
node-fetch@3.3.2:
|
||||||
|
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
|
||||||
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
node-forge@1.3.1:
|
node-forge@1.3.1:
|
||||||
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
|
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
|
||||||
engines: {node: '>= 6.13.0'}
|
engines: {node: '>= 6.13.0'}
|
||||||
|
|
@ -3490,6 +3608,20 @@ packages:
|
||||||
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
|
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
pinia-plugin-persistedstate@4.7.1:
|
||||||
|
resolution: {integrity: sha512-WHOqh2esDlR3eAaknPbqXrkkj0D24h8shrDPqysgCFR6ghqP/fpFfJmMPJp0gETHsvrh9YNNg6dQfo2OEtDnIQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@nuxt/kit': '>=3.0.0'
|
||||||
|
'@pinia/nuxt': '>=0.10.0'
|
||||||
|
pinia: '>=3.0.0'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@nuxt/kit':
|
||||||
|
optional: true
|
||||||
|
'@pinia/nuxt':
|
||||||
|
optional: true
|
||||||
|
pinia:
|
||||||
|
optional: true
|
||||||
|
|
||||||
pinia@3.0.2:
|
pinia@3.0.2:
|
||||||
resolution: {integrity: sha512-sH2JK3wNY809JOeiiURUR0wehJ9/gd9qFN2Y828jCbxEzKEmEt0pzCXwqiSTfuRsK9vQsOflSdnbdBOGrhtn+g==}
|
resolution: {integrity: sha512-sH2JK3wNY809JOeiiURUR0wehJ9/gd9qFN2Y828jCbxEzKEmEt0pzCXwqiSTfuRsK9vQsOflSdnbdBOGrhtn+g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -3790,6 +3922,9 @@ packages:
|
||||||
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
|
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
|
||||||
engines: {node: '>= 0.6.0'}
|
engines: {node: '>= 0.6.0'}
|
||||||
|
|
||||||
|
promise-limit@2.7.0:
|
||||||
|
resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==}
|
||||||
|
|
||||||
prompts@2.4.2:
|
prompts@2.4.2:
|
||||||
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
|
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
@ -4625,6 +4760,10 @@ packages:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
web-streams-polyfill@3.3.3:
|
||||||
|
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
|
||||||
webidl-conversions@3.0.1:
|
webidl-conversions@3.0.1:
|
||||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
|
|
||||||
|
|
@ -5273,6 +5412,68 @@ snapshots:
|
||||||
|
|
||||||
'@kwsites/promise-deferred@1.1.1': {}
|
'@kwsites/promise-deferred@1.1.1': {}
|
||||||
|
|
||||||
|
'@libsql/client@0.15.15':
|
||||||
|
dependencies:
|
||||||
|
'@libsql/core': 0.15.15
|
||||||
|
'@libsql/hrana-client': 0.7.0
|
||||||
|
js-base64: 3.7.8
|
||||||
|
libsql: 0.5.22
|
||||||
|
promise-limit: 2.7.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
|
'@libsql/core@0.15.15':
|
||||||
|
dependencies:
|
||||||
|
js-base64: 3.7.8
|
||||||
|
|
||||||
|
'@libsql/darwin-arm64@0.5.22':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@libsql/darwin-x64@0.5.22':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@libsql/hrana-client@0.7.0':
|
||||||
|
dependencies:
|
||||||
|
'@libsql/isomorphic-fetch': 0.3.1
|
||||||
|
'@libsql/isomorphic-ws': 0.1.5
|
||||||
|
js-base64: 3.7.8
|
||||||
|
node-fetch: 3.3.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
|
'@libsql/isomorphic-fetch@0.3.1': {}
|
||||||
|
|
||||||
|
'@libsql/isomorphic-ws@0.1.5':
|
||||||
|
dependencies:
|
||||||
|
'@types/ws': 8.18.1
|
||||||
|
ws: 8.18.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
|
'@libsql/linux-arm-gnueabihf@0.5.22':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@libsql/linux-arm-musleabihf@0.5.22':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@libsql/linux-arm64-gnu@0.5.22':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@libsql/linux-arm64-musl@0.5.22':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@libsql/linux-x64-gnu@0.5.22':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@libsql/linux-x64-musl@0.5.22':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@libsql/win32-x64-msvc@0.5.22':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@mapbox/node-pre-gyp@2.0.0':
|
'@mapbox/node-pre-gyp@2.0.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
consola: 3.4.2
|
consola: 3.4.2
|
||||||
|
|
@ -5293,6 +5494,8 @@ snapshots:
|
||||||
'@tybys/wasm-util': 0.9.0
|
'@tybys/wasm-util': 0.9.0
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@neon-rs/load@0.0.4': {}
|
||||||
|
|
||||||
'@netlify/functions@3.0.4':
|
'@netlify/functions@3.0.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@netlify/serverless-functions-api': 1.36.0
|
'@netlify/serverless-functions-api': 1.36.0
|
||||||
|
|
@ -5480,7 +5683,7 @@ snapshots:
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
- vite
|
- vite
|
||||||
|
|
||||||
'@nuxt/fonts@0.11.1(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)(magicast@0.3.5)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))':
|
'@nuxt/fonts@0.11.1(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)(magicast@0.3.5)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nuxt/devtools-kit': 2.4.0(magicast@0.3.5)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))
|
'@nuxt/devtools-kit': 2.4.0(magicast@0.3.5)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))
|
||||||
'@nuxt/kit': 3.16.2(magicast@0.3.5)
|
'@nuxt/kit': 3.16.2(magicast@0.3.5)
|
||||||
|
|
@ -5501,7 +5704,7 @@ snapshots:
|
||||||
ufo: 1.6.1
|
ufo: 1.6.1
|
||||||
unifont: 0.1.7
|
unifont: 0.1.7
|
||||||
unplugin: 2.3.2
|
unplugin: 2.3.2
|
||||||
unstorage: 1.15.0(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
unstorage: 1.15.0(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@azure/app-configuration'
|
- '@azure/app-configuration'
|
||||||
- '@azure/cosmos'
|
- '@azure/cosmos'
|
||||||
|
|
@ -5525,7 +5728,7 @@ snapshots:
|
||||||
- uploadthing
|
- uploadthing
|
||||||
- vite
|
- vite
|
||||||
|
|
||||||
'@nuxt/image@1.10.0(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)(magicast@0.3.5)':
|
'@nuxt/image@1.10.0(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)(magicast@0.3.5)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nuxt/kit': 3.16.2(magicast@0.3.5)
|
'@nuxt/kit': 3.16.2(magicast@0.3.5)
|
||||||
consola: 3.4.2
|
consola: 3.4.2
|
||||||
|
|
@ -5538,7 +5741,7 @@ snapshots:
|
||||||
std-env: 3.9.0
|
std-env: 3.9.0
|
||||||
ufo: 1.6.1
|
ufo: 1.6.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
ipx: 2.1.0(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
ipx: 2.1.0(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@azure/app-configuration'
|
- '@azure/app-configuration'
|
||||||
- '@azure/cosmos'
|
- '@azure/cosmos'
|
||||||
|
|
@ -5999,9 +6202,16 @@ snapshots:
|
||||||
'@types/node': 22.14.1
|
'@types/node': 22.14.1
|
||||||
pg-protocol: 1.8.0
|
pg-protocol: 1.8.0
|
||||||
pg-types: 4.0.2
|
pg-types: 4.0.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@types/resolve@1.20.2': {}
|
'@types/resolve@1.20.2': {}
|
||||||
|
|
||||||
|
'@types/web-bluetooth@0.0.21': {}
|
||||||
|
|
||||||
|
'@types/ws@8.18.1':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 22.14.1
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.30.1(@typescript-eslint/parser@8.30.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)':
|
'@typescript-eslint/eslint-plugin@8.30.1(@typescript-eslint/parser@8.30.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/regexpp': 4.12.1
|
'@eslint-community/regexpp': 4.12.1
|
||||||
|
|
@ -6295,6 +6505,19 @@ snapshots:
|
||||||
|
|
||||||
'@vue/shared@3.5.13': {}
|
'@vue/shared@3.5.13': {}
|
||||||
|
|
||||||
|
'@vueuse/core@14.1.0(vue@3.5.13(typescript@5.8.3))':
|
||||||
|
dependencies:
|
||||||
|
'@types/web-bluetooth': 0.0.21
|
||||||
|
'@vueuse/metadata': 14.1.0
|
||||||
|
'@vueuse/shared': 14.1.0(vue@3.5.13(typescript@5.8.3))
|
||||||
|
vue: 3.5.13(typescript@5.8.3)
|
||||||
|
|
||||||
|
'@vueuse/metadata@14.1.0': {}
|
||||||
|
|
||||||
|
'@vueuse/shared@14.1.0(vue@3.5.13(typescript@5.8.3))':
|
||||||
|
dependencies:
|
||||||
|
vue: 3.5.13(typescript@5.8.3)
|
||||||
|
|
||||||
abbrev@3.0.1: {}
|
abbrev@3.0.1: {}
|
||||||
|
|
||||||
abort-controller@3.0.0:
|
abort-controller@3.0.0:
|
||||||
|
|
@ -6791,13 +7014,16 @@ snapshots:
|
||||||
|
|
||||||
csstype@3.1.3: {}
|
csstype@3.1.3: {}
|
||||||
|
|
||||||
daisyui@5.0.23: {}
|
daisyui@5.2.3: {}
|
||||||
|
|
||||||
|
data-uri-to-buffer@4.0.1: {}
|
||||||
|
|
||||||
date-fns@4.1.0: {}
|
date-fns@4.1.0: {}
|
||||||
|
|
||||||
db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)):
|
db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
drizzle-orm: 0.42.0(@types/pg@8.11.13)(pg@8.14.1)
|
'@libsql/client': 0.15.15
|
||||||
|
drizzle-orm: 0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)
|
||||||
|
|
||||||
debug@3.2.7:
|
debug@3.2.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -6848,6 +7074,8 @@ snapshots:
|
||||||
|
|
||||||
detect-libc@1.0.3: {}
|
detect-libc@1.0.3: {}
|
||||||
|
|
||||||
|
detect-libc@2.0.2: {}
|
||||||
|
|
||||||
detect-libc@2.0.3: {}
|
detect-libc@2.0.3: {}
|
||||||
|
|
||||||
devalue@5.1.1: {}
|
devalue@5.1.1: {}
|
||||||
|
|
@ -6897,8 +7125,9 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1):
|
drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
|
'@libsql/client': 0.15.15
|
||||||
'@types/pg': 8.11.13
|
'@types/pg': 8.11.13
|
||||||
pg: 8.14.1
|
pg: 8.14.1
|
||||||
|
|
||||||
|
|
@ -7267,6 +7496,11 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
picomatch: 4.0.2
|
picomatch: 4.0.2
|
||||||
|
|
||||||
|
fetch-blob@3.2.0:
|
||||||
|
dependencies:
|
||||||
|
node-domexception: 1.0.0
|
||||||
|
web-streams-polyfill: 3.3.3
|
||||||
|
|
||||||
file-entry-cache@8.0.0:
|
file-entry-cache@8.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
flat-cache: 4.0.1
|
flat-cache: 4.0.1
|
||||||
|
|
@ -7326,6 +7560,10 @@ snapshots:
|
||||||
cross-spawn: 7.0.6
|
cross-spawn: 7.0.6
|
||||||
signal-exit: 4.1.0
|
signal-exit: 4.1.0
|
||||||
|
|
||||||
|
formdata-polyfill@4.0.10:
|
||||||
|
dependencies:
|
||||||
|
fetch-blob: 3.2.0
|
||||||
|
|
||||||
fraction.js@4.3.7: {}
|
fraction.js@4.3.7: {}
|
||||||
|
|
||||||
fresh@0.5.2: {}
|
fresh@0.5.2: {}
|
||||||
|
|
@ -7585,7 +7823,7 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
ipx@2.1.0(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1):
|
ipx@2.1.0(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@fastify/accept-negotiator': 1.1.0
|
'@fastify/accept-negotiator': 1.1.0
|
||||||
citty: 0.1.6
|
citty: 0.1.6
|
||||||
|
|
@ -7601,7 +7839,7 @@ snapshots:
|
||||||
sharp: 0.32.6
|
sharp: 0.32.6
|
||||||
svgo: 3.3.2
|
svgo: 3.3.2
|
||||||
ufo: 1.6.1
|
ufo: 1.6.1
|
||||||
unstorage: 1.15.0(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
unstorage: 1.15.0(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
||||||
xss: 1.0.15
|
xss: 1.0.15
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@azure/app-configuration'
|
- '@azure/app-configuration'
|
||||||
|
|
@ -7725,6 +7963,8 @@ snapshots:
|
||||||
|
|
||||||
jiti@2.4.2: {}
|
jiti@2.4.2: {}
|
||||||
|
|
||||||
|
js-base64@3.7.8: {}
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
|
|
||||||
js-tokens@9.0.1: {}
|
js-tokens@9.0.1: {}
|
||||||
|
|
@ -7838,6 +8078,21 @@ snapshots:
|
||||||
prelude-ls: 1.2.1
|
prelude-ls: 1.2.1
|
||||||
type-check: 0.4.0
|
type-check: 0.4.0
|
||||||
|
|
||||||
|
libsql@0.5.22:
|
||||||
|
dependencies:
|
||||||
|
'@neon-rs/load': 0.0.4
|
||||||
|
detect-libc: 2.0.2
|
||||||
|
optionalDependencies:
|
||||||
|
'@libsql/darwin-arm64': 0.5.22
|
||||||
|
'@libsql/darwin-x64': 0.5.22
|
||||||
|
'@libsql/linux-arm-gnueabihf': 0.5.22
|
||||||
|
'@libsql/linux-arm-musleabihf': 0.5.22
|
||||||
|
'@libsql/linux-arm64-gnu': 0.5.22
|
||||||
|
'@libsql/linux-arm64-musl': 0.5.22
|
||||||
|
'@libsql/linux-x64-gnu': 0.5.22
|
||||||
|
'@libsql/linux-x64-musl': 0.5.22
|
||||||
|
'@libsql/win32-x64-msvc': 0.5.22
|
||||||
|
|
||||||
lightningcss-darwin-arm64@1.29.2:
|
lightningcss-darwin-arm64@1.29.2:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
@ -8075,7 +8330,7 @@ snapshots:
|
||||||
|
|
||||||
negotiator@0.6.3: {}
|
negotiator@0.6.3: {}
|
||||||
|
|
||||||
nitropack@2.11.9(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)):
|
nitropack@2.11.9(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@cloudflare/kv-asset-handler': 0.4.0
|
'@cloudflare/kv-asset-handler': 0.4.0
|
||||||
'@netlify/functions': 3.0.4
|
'@netlify/functions': 3.0.4
|
||||||
|
|
@ -8097,7 +8352,7 @@ snapshots:
|
||||||
cookie-es: 2.0.0
|
cookie-es: 2.0.0
|
||||||
croner: 9.0.0
|
croner: 9.0.0
|
||||||
crossws: 0.3.4
|
crossws: 0.3.4
|
||||||
db0: 0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1))
|
db0: 0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1))
|
||||||
defu: 6.1.4
|
defu: 6.1.4
|
||||||
destr: 2.0.5
|
destr: 2.0.5
|
||||||
dot-prop: 9.0.0
|
dot-prop: 9.0.0
|
||||||
|
|
@ -8143,7 +8398,7 @@ snapshots:
|
||||||
unenv: 2.0.0-rc.15
|
unenv: 2.0.0-rc.15
|
||||||
unimport: 5.0.0
|
unimport: 5.0.0
|
||||||
unplugin-utils: 0.2.4
|
unplugin-utils: 0.2.4
|
||||||
unstorage: 1.15.0(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
unstorage: 1.15.0(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
||||||
untyped: 2.0.0
|
untyped: 2.0.0
|
||||||
unwasm: 0.3.9
|
unwasm: 0.3.9
|
||||||
youch: 4.1.0-beta.7
|
youch: 4.1.0-beta.7
|
||||||
|
|
@ -8185,12 +8440,20 @@ snapshots:
|
||||||
|
|
||||||
node-addon-api@7.1.1: {}
|
node-addon-api@7.1.1: {}
|
||||||
|
|
||||||
|
node-domexception@1.0.0: {}
|
||||||
|
|
||||||
node-fetch-native@1.6.6: {}
|
node-fetch-native@1.6.6: {}
|
||||||
|
|
||||||
node-fetch@2.7.0:
|
node-fetch@2.7.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
whatwg-url: 5.0.0
|
whatwg-url: 5.0.0
|
||||||
|
|
||||||
|
node-fetch@3.3.2:
|
||||||
|
dependencies:
|
||||||
|
data-uri-to-buffer: 4.0.1
|
||||||
|
fetch-blob: 3.2.0
|
||||||
|
formdata-polyfill: 4.0.10
|
||||||
|
|
||||||
node-forge@1.3.1: {}
|
node-forge@1.3.1: {}
|
||||||
|
|
||||||
node-gyp-build@4.8.4: {}
|
node-gyp-build@4.8.4: {}
|
||||||
|
|
@ -8226,7 +8489,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
boolbase: 1.0.0
|
boolbase: 1.0.0
|
||||||
|
|
||||||
nuxt@3.16.2(@parcel/watcher@2.5.1)(@types/node@22.14.1)(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1))(eslint@9.24.0(jiti@2.4.2))(ioredis@5.6.1)(lightningcss@1.29.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.0)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.3)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))(yaml@2.7.1):
|
nuxt@3.16.2(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@22.14.1)(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1))(eslint@9.24.0(jiti@2.4.2))(ioredis@5.6.1)(lightningcss@1.29.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.0)(terser@5.39.0)(tsx@4.19.3)(typescript@5.8.3)(vite@6.2.6(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(tsx@4.19.3)(yaml@2.7.1))(yaml@2.7.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nuxt/cli': 3.24.1(magicast@0.3.5)
|
'@nuxt/cli': 3.24.1(magicast@0.3.5)
|
||||||
'@nuxt/devalue': 2.0.2
|
'@nuxt/devalue': 2.0.2
|
||||||
|
|
@ -8263,7 +8526,7 @@ snapshots:
|
||||||
mlly: 1.7.4
|
mlly: 1.7.4
|
||||||
mocked-exports: 0.1.1
|
mocked-exports: 0.1.1
|
||||||
nanotar: 0.2.0
|
nanotar: 0.2.0
|
||||||
nitropack: 2.11.9(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1))
|
nitropack: 2.11.9(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1))
|
||||||
nypm: 0.6.0
|
nypm: 0.6.0
|
||||||
ofetch: 1.4.1
|
ofetch: 1.4.1
|
||||||
ohash: 2.0.11
|
ohash: 2.0.11
|
||||||
|
|
@ -8285,7 +8548,7 @@ snapshots:
|
||||||
unimport: 4.2.0
|
unimport: 4.2.0
|
||||||
unplugin: 2.3.2
|
unplugin: 2.3.2
|
||||||
unplugin-vue-router: 0.12.0(vue-router@4.5.0(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3))
|
unplugin-vue-router: 0.12.0(vue-router@4.5.0(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3))
|
||||||
unstorage: 1.15.0(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
unstorage: 1.15.0(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1)
|
||||||
untyped: 2.0.0
|
untyped: 2.0.0
|
||||||
vue: 3.5.13(typescript@5.8.3)
|
vue: 3.5.13(typescript@5.8.3)
|
||||||
vue-bundle-renderer: 2.1.1
|
vue-bundle-renderer: 2.1.1
|
||||||
|
|
@ -8359,7 +8622,8 @@ snapshots:
|
||||||
|
|
||||||
object-hash@3.0.0: {}
|
object-hash@3.0.0: {}
|
||||||
|
|
||||||
obuf@1.1.2: {}
|
obuf@1.1.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
ofetch@1.4.1:
|
ofetch@1.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -8511,17 +8775,22 @@ snapshots:
|
||||||
pg-cloudflare@1.1.1:
|
pg-cloudflare@1.1.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
pg-connection-string@2.7.0: {}
|
pg-connection-string@2.7.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
pg-int8@1.0.1: {}
|
pg-int8@1.0.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
pg-numeric@1.0.2: {}
|
pg-numeric@1.0.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
pg-pool@3.8.0(pg@8.14.1):
|
pg-pool@3.8.0(pg@8.14.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
pg: 8.14.1
|
pg: 8.14.1
|
||||||
|
optional: true
|
||||||
|
|
||||||
pg-protocol@1.8.0: {}
|
pg-protocol@1.8.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
pg-types@2.2.0:
|
pg-types@2.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -8530,6 +8799,7 @@ snapshots:
|
||||||
postgres-bytea: 1.0.0
|
postgres-bytea: 1.0.0
|
||||||
postgres-date: 1.0.7
|
postgres-date: 1.0.7
|
||||||
postgres-interval: 1.2.0
|
postgres-interval: 1.2.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
pg-types@4.0.2:
|
pg-types@4.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -8540,6 +8810,7 @@ snapshots:
|
||||||
postgres-date: 2.1.0
|
postgres-date: 2.1.0
|
||||||
postgres-interval: 3.0.0
|
postgres-interval: 3.0.0
|
||||||
postgres-range: 1.1.4
|
postgres-range: 1.1.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
pg@8.14.1:
|
pg@8.14.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -8550,10 +8821,12 @@ snapshots:
|
||||||
pgpass: 1.0.5
|
pgpass: 1.0.5
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
pg-cloudflare: 1.1.1
|
pg-cloudflare: 1.1.1
|
||||||
|
optional: true
|
||||||
|
|
||||||
pgpass@1.0.5:
|
pgpass@1.0.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
split2: 4.2.0
|
split2: 4.2.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
|
|
||||||
|
|
@ -8563,6 +8836,14 @@ snapshots:
|
||||||
|
|
||||||
pify@2.3.0: {}
|
pify@2.3.0: {}
|
||||||
|
|
||||||
|
pinia-plugin-persistedstate@4.7.1(@nuxt/kit@3.16.2(magicast@0.3.5))(@pinia/nuxt@0.11.0(magicast@0.3.5)(pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))))(pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))):
|
||||||
|
dependencies:
|
||||||
|
defu: 6.1.4
|
||||||
|
optionalDependencies:
|
||||||
|
'@nuxt/kit': 3.16.2(magicast@0.3.5)
|
||||||
|
'@pinia/nuxt': 0.11.0(magicast@0.3.5)(pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)))
|
||||||
|
pinia: 3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))
|
||||||
|
|
||||||
pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)):
|
pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/devtools-api': 7.7.2
|
'@vue/devtools-api': 7.7.2
|
||||||
|
|
@ -8791,27 +9072,36 @@ snapshots:
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
|
|
||||||
postgres-array@2.0.0: {}
|
postgres-array@2.0.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
postgres-array@3.0.4: {}
|
postgres-array@3.0.4:
|
||||||
|
optional: true
|
||||||
|
|
||||||
postgres-bytea@1.0.0: {}
|
postgres-bytea@1.0.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
postgres-bytea@3.0.0:
|
postgres-bytea@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
obuf: 1.1.2
|
obuf: 1.1.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
postgres-date@1.0.7: {}
|
postgres-date@1.0.7:
|
||||||
|
optional: true
|
||||||
|
|
||||||
postgres-date@2.1.0: {}
|
postgres-date@2.1.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
postgres-interval@1.2.0:
|
postgres-interval@1.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
xtend: 4.0.2
|
xtend: 4.0.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
postgres-interval@3.0.0: {}
|
postgres-interval@3.0.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
postgres-range@1.1.4: {}
|
postgres-range@1.1.4:
|
||||||
|
optional: true
|
||||||
|
|
||||||
prebuild-install@7.1.3:
|
prebuild-install@7.1.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -8839,6 +9129,8 @@ snapshots:
|
||||||
|
|
||||||
process@0.11.10: {}
|
process@0.11.10: {}
|
||||||
|
|
||||||
|
promise-limit@2.7.0: {}
|
||||||
|
|
||||||
prompts@2.4.2:
|
prompts@2.4.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
kleur: 3.0.3
|
kleur: 3.0.3
|
||||||
|
|
@ -9177,7 +9469,8 @@ snapshots:
|
||||||
|
|
||||||
speakingurl@14.0.1: {}
|
speakingurl@14.0.1: {}
|
||||||
|
|
||||||
split2@4.2.0: {}
|
split2@4.2.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
stable-hash@0.0.5: {}
|
stable-hash@0.0.5: {}
|
||||||
|
|
||||||
|
|
@ -9590,7 +9883,7 @@ snapshots:
|
||||||
'@unrs/resolver-binding-win32-ia32-msvc': 1.5.0
|
'@unrs/resolver-binding-win32-ia32-msvc': 1.5.0
|
||||||
'@unrs/resolver-binding-win32-x64-msvc': 1.5.0
|
'@unrs/resolver-binding-win32-x64-msvc': 1.5.0
|
||||||
|
|
||||||
unstorage@1.15.0(db0@0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1):
|
unstorage@1.15.0(db0@0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1)))(ioredis@5.6.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
anymatch: 3.1.3
|
anymatch: 3.1.3
|
||||||
chokidar: 4.0.3
|
chokidar: 4.0.3
|
||||||
|
|
@ -9601,7 +9894,7 @@ snapshots:
|
||||||
ofetch: 1.4.1
|
ofetch: 1.4.1
|
||||||
ufo: 1.6.1
|
ufo: 1.6.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
db0: 0.3.1(drizzle-orm@0.42.0(@types/pg@8.11.13)(pg@8.14.1))
|
db0: 0.3.1(@libsql/client@0.15.15)(drizzle-orm@0.42.0(@libsql/client@0.15.15)(@types/pg@8.11.13)(pg@8.14.1))
|
||||||
ioredis: 5.6.1
|
ioredis: 5.6.1
|
||||||
|
|
||||||
untun@0.1.3:
|
untun@0.1.3:
|
||||||
|
|
@ -9788,6 +10081,8 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.8.3
|
typescript: 5.8.3
|
||||||
|
|
||||||
|
web-streams-polyfill@3.3.3: {}
|
||||||
|
|
||||||
webidl-conversions@3.0.1: {}
|
webidl-conversions@3.0.1: {}
|
||||||
|
|
||||||
webpack-virtual-modules@0.6.2: {}
|
webpack-virtual-modules@0.6.2: {}
|
||||||
|
|
@ -9831,7 +10126,8 @@ snapshots:
|
||||||
cssfilter: 0.0.10
|
cssfilter: 0.0.10
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
xtend@4.0.2: {}
|
xtend@4.0.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
y18n@5.0.8: {}
|
y18n@5.0.8: {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
import 'dotenv/config';
|
import 'dotenv/config';
|
||||||
import { drizzle } from 'drizzle-orm/node-postgres';
|
import { drizzle } from 'drizzle-orm/libsql';
|
||||||
import { sql, eq, and } from 'drizzle-orm';
|
import { sql, eq, and } from 'drizzle-orm';
|
||||||
import arrayShuffle from 'array-shuffle';
|
import arrayShuffle from 'array-shuffle';
|
||||||
import {
|
import { tasks_advanced, questions_advanced, categories_db } from '~/db/schema';
|
||||||
tasks_advanced,
|
|
||||||
questions_advanced,
|
|
||||||
categories_db,
|
|
||||||
} from '@/src/db/schema';
|
|
||||||
import type { AdvancedQuestion } from '~/types';
|
import type { AdvancedQuestion } from '~/types';
|
||||||
import categories from '~/categories';
|
import categories from '~/categories';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import 'dotenv/config';
|
import 'dotenv/config';
|
||||||
import { drizzle } from 'drizzle-orm/node-postgres';
|
import { drizzle } from 'drizzle-orm/libsql';
|
||||||
import { sql, eq, and } from 'drizzle-orm';
|
import { sql, eq, and } from 'drizzle-orm';
|
||||||
import arrayShuffle from 'array-shuffle';
|
import arrayShuffle from 'array-shuffle';
|
||||||
import { tasks, questions, categories_db } from '@/src/db/schema';
|
import { tasks, questions, categories_db } from '~/db/schema';
|
||||||
import type { BasicQuestion } from '~/types';
|
import type { BasicQuestion } from '~/types';
|
||||||
import categories from '~/categories';
|
import categories from '~/categories';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import { integer, pgTable, text, smallint, char } from 'drizzle-orm/pg-core';
|
|
||||||
|
|
||||||
export const tasks = pgTable('tasks', {
|
|
||||||
id: integer().notNull(),
|
|
||||||
correct_answer: text(),
|
|
||||||
media_url: text(),
|
|
||||||
weight: smallint(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const questions = pgTable('questions', {
|
|
||||||
task_id: integer(),
|
|
||||||
lang: char({ length: 2 }),
|
|
||||||
text: text(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const tasks_advanced = pgTable('tasks_advanced', {
|
|
||||||
id: integer().notNull(),
|
|
||||||
correct_answer: char({ length: 1 }),
|
|
||||||
media_url: text(),
|
|
||||||
weight: smallint(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const questions_advanced = pgTable('questions_advanced', {
|
|
||||||
task_id: integer(),
|
|
||||||
lang: char({ length: 2 }),
|
|
||||||
text: text(),
|
|
||||||
answer_a: text(),
|
|
||||||
answer_b: text(),
|
|
||||||
answer_c: text(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const categories_db = pgTable('categories', {
|
|
||||||
name: text(),
|
|
||||||
task_id: integer(),
|
|
||||||
});
|
|
||||||
|
|
@ -1,43 +1,54 @@
|
||||||
import { defineStore } from 'pinia';
|
export const useBasicStore = defineStore('basicStore', {
|
||||||
|
state: () => ({
|
||||||
export const useExamStore = defineStore('exam-store', () => {
|
basic: [] as ResultType[],
|
||||||
const category = ref('');
|
}),
|
||||||
const end = ref(false);
|
actions: {
|
||||||
const result: Ref<ResultEndType> = ref({
|
async set(basic: ResultType[]) {
|
||||||
basic: [],
|
this.basic = basic;
|
||||||
advanced: [],
|
},
|
||||||
});
|
},
|
||||||
function resetExam() {
|
persist: {
|
||||||
category.value = '';
|
storage: piniaPluginPersistedstate.localStorage(),
|
||||||
mildReset();
|
},
|
||||||
}
|
});
|
||||||
function mildReset() {
|
|
||||||
end.value = false;
|
export const useAdvancedStore = defineStore('advancedStore', {
|
||||||
result.value = {
|
state: () => ({
|
||||||
basic: [],
|
advanced: [] as ResultType[],
|
||||||
advanced: [],
|
}),
|
||||||
};
|
actions: {
|
||||||
}
|
async set(advanced: ResultType[]) {
|
||||||
function setEnd(value: boolean) {
|
this.advanced = advanced;
|
||||||
end.value = value;
|
},
|
||||||
return end.value;
|
},
|
||||||
}
|
persist: {
|
||||||
function setCategory(value: string) {
|
storage: piniaPluginPersistedstate.localStorage(),
|
||||||
category.value = value;
|
},
|
||||||
return category.value;
|
});
|
||||||
}
|
|
||||||
function setResult(value: ResultEndType) {
|
export const useExamStore = defineStore('examStore', {
|
||||||
result.value = value;
|
state: () => ({
|
||||||
return result.value;
|
category: '',
|
||||||
}
|
end: false,
|
||||||
return {
|
}),
|
||||||
category,
|
actions: {
|
||||||
end,
|
async setCategory(category: string) {
|
||||||
result,
|
this.category = category;
|
||||||
resetExam,
|
},
|
||||||
mildReset,
|
async setEnd(end: boolean) {
|
||||||
setEnd,
|
this.end = end;
|
||||||
setCategory,
|
},
|
||||||
setResult,
|
async mildReset() {
|
||||||
};
|
this.end = false;
|
||||||
|
useBasicStore().set([]);
|
||||||
|
useAdvancedStore().set([]);
|
||||||
|
},
|
||||||
|
async resetExam() {
|
||||||
|
this.category = '';
|
||||||
|
this.mildReset();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
persist: {
|
||||||
|
storage: piniaPluginPersistedstate.cookies(),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,16 @@ export interface AdvancedQuestion extends BasicQuestion {
|
||||||
answer_c: string | null;
|
answer_c: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResultType<T> {
|
export type Question = BasicQuestion | AdvancedQuestion | null | undefined;
|
||||||
question: T | undefined;
|
|
||||||
|
export interface ResultType {
|
||||||
|
question: Question;
|
||||||
chosen_answer: string;
|
chosen_answer: string;
|
||||||
|
correct_answer: string | null;
|
||||||
chosen_is_correct: boolean | undefined;
|
chosen_is_correct: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResultEndType {
|
export interface ResultEndType {
|
||||||
basic: ResultType<BasicQuestion>[];
|
basic: ResultType[];
|
||||||
advanced: ResultType<AdvancedQuestion>[];
|
advanced: ResultType[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue