fixup result, add totaltime in exam, add todo in readme

This commit is contained in:
NetMan 2025-03-05 23:42:40 +01:00
parent 2d3854a4fe
commit cf868f7d65
8 changed files with 125 additions and 53 deletions

View file

@ -8,7 +8,17 @@ This project utilizes `pnpm`, thus it is recommended
pnpm install
```
More information about setting up database will come here later
# To-do:
- [ ] re-forge database structure, script for processing, share appropriate files
- [ ] choose category
- [ ] beautify website
- [ ] better answer click recognition
- [ ] come up with how to show results appropriately
- [ ] i18n - pl, en, de, ua (not all questions are not available in ua, api handle)
- [ ] exam (maybe also results?) warning leave message on exit (refresh)
- [ ] lazy loading
- [ ] question timers, and at end of total timer show a message for a while before immediatly navigating to results (maybe sth similar also when normally ending exam)
## Development Server

View file

@ -15,8 +15,19 @@ defineProps<{
<div
class="select-none z-[-1] flex-1 flex items-stretch w-full justify-center *:object-contain"
>
<img :src="cdnUrl + media.ogName" alt="" v-if="media.fileType == 'jpg'" />
<video v-else-if="media.fileType == 'wmv'" :key="media.fileName" autoplay>
<!-- Reserved for getting to know the question (20s) in basic questions section
src="~/public/placeholder.svg" -->
<img
:src="cdnUrl + media.ogName"
alt=""
v-if="media.fileType == 'jpg'"
:key="`${media.ogName}-photo`"
/>
<video
v-else-if="media.fileType == 'wmv'"
:key="`${media.ogName}-video`"
autoplay
>
<source
:src="cdnUrl + [media.fileName, 'mp4'].join('.')"
type="video/mp4"

View file

@ -23,18 +23,21 @@ const emit = defineEmits<{
>
<h1 class="text-[1.5rem]">{{ title }}</h1>
<div class="*:inline">Punkty: <slot name="points" /> / 74</div>
<div class="*:inline">Wynik: pozytywny/negatywny</div>
<div class="*:inline">Wynik: <slot name="resultTrueFalse" /></div>
<div
class="flex flex-row gap-2 *:py-1 *:px-3 *:border *:border-1 *:border-slate-300 *:rounded-md *:bg-slate-100"
>
<button class="text-slate-600" @click="emit('homepage')">
<button
class="!border-slate-200 text-slate-600"
@click="emit('homepage')"
>
Wróć na stronę główną
</button>
<button class="border-slate-200 bg-slate-50" @click="emit('newExam')">
<button class="!bg-slate-200 text-slate-800" @click="emit('newExam')">
Rozpocznij jeszcze raz
</button>
<button
class="!border-slate-500 !bg-slate-700 text-white"
class="!border-2 !border-slate-200 !bg-slate-700 text-white"
@click="emit('close')"
>
Przejrzyj odpowiedzi
@ -42,14 +45,3 @@ const emit = defineEmits<{
</div>
</VueFinalModal>
</template>
<style>
.confirm-modal-content button {
padding: 0 8px;
border: 1px solid;
border-radius: 0.5rem;
}
.dark .confirm-modal-content {
background: #000;
}
</style>

View file

@ -1,8 +1,8 @@
<script setup lang="ts">
import * as _ from "lodash";
import { range } from "lodash";
const props = defineProps<{
// result: ResultEndType;
result: ResultEndType;
countBasic: number;
countAdvanced: number;
question: BasicQuestion | AdvancedQuestion | undefined;
@ -13,34 +13,48 @@ const props = defineProps<{
const isBasic = computed(() => props.now == "basic");
const isAdvanced = computed(() => props.now == "advanced");
const boxesAmount = computed(() => {
if (isBasic.value) {
return 20 + 1;
} else if (isAdvanced.value) {
return 12 + 1;
} else {
return 0;
}
});
</script>
<template>
<div
class="flex flex-col items-center p-4 gap-10 border-l border-slate-300 bg-slate-100"
class="flex flex-col items-center p-4 gap-6 border-l border-slate-300 bg-slate-100"
>
<div>
<button @click="$emit('end-exam')" class="btn-major">
Wróć na stronę główną
</button>
<button @click="$emit('end-exam')" class="btn-major">
Rozpocznij jeszcze raz
</button>
<button @click="" class="btn-major">Wróć na stronę główną</button>
<button @click="" class="btn-major">Rozpocznij jeszcze raz</button>
</div>
<div class="flex flex-row gap-6 *:flex-1 w-full">
<button class="text-md text-white bg-blue-400">Pytania podstawowe</button>
<button class="text-md text-white bg-blue-400">
<button
class="text-md text-white bg-blue-400"
@click="$emit('change-now', 'basic')"
>
Pytania podstawowe
</button>
<button
class="text-md text-white bg-blue-400"
@click="$emit('change-now', 'advanced')"
>
Pytania specjalistyczne
</button>
</div>
<div class="w-full flex justify-center items-center">
<div class="flex flex-row flex-wrap gap-2 items-stretch !w-max">
<div
v-for="num in _.range(1, 21)"
class="p-1 bg-blue-500 text-white w-8 aspect-square text-center"
>
{{ num }}
</div>
<div
class="grid grid-cols-[repeat(auto-fit,50px)] gap-2 justify-around w-full"
>
<div
v-for="num in range(1, boxesAmount)"
class="p-1 bg-blue-500 text-white text-center"
>
{{ num }}
</div>
</div>
<div class="flex flex-row gap-6 *:flex-1 w-full">
@ -51,7 +65,10 @@ const isAdvanced = computed(() => props.now == "advanced");
Pokaż poprawną odpowiedź
</button>
</div>
<div>
Poprawna odpowiedź
<br />
Zaznaczona odpowiedź
</div>
</div>
</template>
<!-- <style></style> -->

View file

@ -1,9 +1,20 @@
<script setup lang="ts">
defineProps<{
import type { Duration } from "date-fns";
const props = defineProps<{
points: number | undefined;
category: string | undefined;
timeRemaining?: string | undefined;
timeRemaining?: Duration | undefined;
}>();
const timeRemainingFriendly = computed(() => {
if (typeof props.timeRemaining !== "undefined") {
let seconds = props.timeRemaining.seconds ?? 0;
return `${props.timeRemaining.minutes ?? 0}:${
seconds >= 0 && seconds < 10 ? 0 : ""
}${seconds ?? 0}`;
}
});
</script>
<template>
@ -20,9 +31,11 @@ defineProps<{
<span class="block">Aktualna kategoria (implement)</span>
<div class="info-little-box">{{ category }}</div>
</div>
<div v-if="typeof timeRemaining === 'string'">
<span class="block">Czas do końca egzaminu (implement)</span>
<div class="info-little-box">{{ timeRemaining }}</div>
<div v-if="typeof timeRemaining !== 'undefined'">
<span class="block">Czas do końca egzaminu</span>
<div class="info-little-box w-18 text-center">
{{ timeRemainingFriendly }}
</div>
</div>
</div>
</template>

View file

@ -6,6 +6,29 @@ definePageMeta({
import "7.css/dist/7.scoped.css";
import { useExamStore } from "~/store/examResults";
import { intervalToDuration, addMinutes, addSeconds, isEqual } from "date-fns";
const nowTime = ref(new Date());
const timeEnd = addMinutes(new Date(), 25);
const timeRemainingTotal = computed(() =>
intervalToDuration({
start: nowTime.value,
end: timeEnd,
})
);
// const timeRemainingQuestion - to implement
onMounted(() => {
const endInterval = setInterval(() => {
nowTime.value = addSeconds(nowTime.value, 1);
if (isEqual(nowTime.value, timeEnd)) {
clearInterval(endInterval);
endExam();
}
}, 1000);
});
const examStore = useExamStore();
examStore.resetExam();
@ -90,7 +113,7 @@ function endExam() {
next();
examStore.result = result.value;
examStore.end = true;
return navigateTo("/result");
return navigateTo("/result", { replace: true });
}
const questionBasic = computed<BasicQuestion | undefined>(() =>
@ -133,7 +156,7 @@ const result: Ref<ResultEndType> = ref({
<TopBar
:points="question?.liczba_pkt"
:category="`B`"
:time-remaining="`25:00`"
:time-remaining="timeRemainingTotal"
/>
<Media :media="media" />
<BasicQuestionBlock

View file

@ -8,26 +8,26 @@ definePageMeta({
const examStore = useExamStore();
const points = ref<number>();
const points = ref<number>(0);
if (!examStore.end) {
examStore.resetExam();
await navigateTo("/");
} else {
let sum = 0;
examStore.result.basic.forEach((answer) => {
if (answer.chosen_is_correct) {
sum += answer.question?.liczba_pkt ?? 0;
points.value += answer.question?.liczba_pkt ?? 0;
}
});
examStore.result.advanced.forEach((answer) => {
if (answer.chosen_is_correct) {
sum += answer.question?.liczba_pkt ?? 0;
points.value += answer.question?.liczba_pkt ?? 0;
}
});
points.value = sum;
}
const resultTrueFalse = ref(points.value >= 68 ? "pozytywny" : "negatywny");
const countBasic = ref(0);
const countAdvanced = ref(0);
@ -89,9 +89,14 @@ const { open, close } = useModal({
},
slots: {
points: `${points.value}`,
resultTrueFalse: resultTrueFalse,
},
});
open();
function changeNow(to: string) {
now.value = to;
}
</script>
<template>
@ -117,15 +122,15 @@ open();
</div>
<RightBarResult
:result="examStore.result"
:question="question"
:question-basic="questionBasic"
:question-advanced="questionAdvanced"
:count-basic="countBasic"
:count-advanced="countAdvanced"
:now="now"
@change-now="changeNow"
/>
<!-- :result="result" -->
<!-- @next-question="next()" -->
</div>
</div>
</div>

1
public/placeholder.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="680.764" height="528.354" viewBox="0 0 180.119 139.794"><g transform="translate(-13.59 -66.639)" paint-order="fill markers stroke"><path fill="#d0d0d0" d="M13.591 66.639H193.71v139.794H13.591z"/><path d="m118.507 133.514-34.249 34.249-15.968-15.968-41.938 41.937H178.726z" opacity=".675" fill="#fff"/><circle cx="58.217" cy="108.555" r="11.773" opacity=".675" fill="#fff"/><path fill="none" d="M26.111 77.634h152.614v116.099H26.111z"/></g></svg>

After

Width:  |  Height:  |  Size: 492 B