fixup result, add totaltime in exam, add todo in readme
This commit is contained in:
parent
2d3854a4fe
commit
cf868f7d65
8 changed files with 125 additions and 53 deletions
12
README.md
12
README.md
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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> -->
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
1
public/placeholder.svg
Normal 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 |
Loading…
Add table
Reference in a new issue