ui i18n english, fix locale routes, theme toggle
minor: - change background for category list for dark theme compatibility - try to 'fix' video playback errors in console
This commit is contained in:
parent
19508f1148
commit
ccccf038d9
15 changed files with 205 additions and 101 deletions
11
app.vue
11
app.vue
|
|
@ -1,5 +1,14 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
const examStore = useExamStore();
|
||||||
|
const { setLocale } = useI18n();
|
||||||
|
|
||||||
|
setLocale(examStore.lang as 'pl' | 'en' | 'de' | 'ua');
|
||||||
|
|
||||||
|
const themeStore = useThemeStore();
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div :data-theme="themeStore.theme" class="min-h-dvh">
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,12 @@ watchEffect(() => {
|
||||||
<h1 class="text-[1.5rem]">{{ $t('examEnd') }}</h1>
|
<h1 class="text-[1.5rem]">{{ $t('examEnd') }}</h1>
|
||||||
<div class="*:inline">{{ $t('doYouReallyWantToEndExam') }}</div>
|
<div class="*:inline">{{ $t('doYouReallyWantToEndExam') }}</div>
|
||||||
<div class="flex flex-row gap-2 justify-around">
|
<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-success" @click="emit('endExam')">
|
||||||
<div class="btn btn-lg btn-error" @click="endModal?.close()">Nie</div>
|
{{ $t('yes') }}
|
||||||
|
</div>
|
||||||
|
<div class="btn btn-lg btn-error" @click="endModal?.close()">
|
||||||
|
{{ $t('no') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ import { joinURL } from 'ufo';
|
||||||
const runtimeConfig = useRuntimeConfig();
|
const runtimeConfig = useRuntimeConfig();
|
||||||
const cdnUrl = runtimeConfig.public.cdn_url;
|
const cdnUrl = runtimeConfig.public.cdn_url;
|
||||||
|
|
||||||
const route = useRoute();
|
|
||||||
|
|
||||||
const emit = defineEmits(['mediaload']);
|
const emit = defineEmits(['mediaload']);
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|
@ -25,18 +23,23 @@ const media = computed(() => {
|
||||||
return { name: dotSplit?.join('.'), type };
|
return { name: dotSplit?.join('.'), type };
|
||||||
});
|
});
|
||||||
|
|
||||||
const video = ref();
|
const video = useTemplateRef('video');
|
||||||
|
|
||||||
function onVideoLoad() {
|
function onVideoLoad() {
|
||||||
if (route.path === '/exam') {
|
if (props.phase != 'result') {
|
||||||
video.value.play();
|
const videoPlayInterval = setInterval(() => {
|
||||||
let duration = video.value.duration;
|
if (video.value) {
|
||||||
if (isNaN(duration) || duration == Infinity) {
|
video.value.play();
|
||||||
duration = 0;
|
let duration = video.value.duration;
|
||||||
}
|
if (isNaN(duration) || duration == Infinity) {
|
||||||
setTimeout(() => {
|
duration = 0;
|
||||||
emit('mediaload');
|
}
|
||||||
}, duration * 1000);
|
setTimeout(() => {
|
||||||
|
emit('mediaload');
|
||||||
|
}, duration * 1000);
|
||||||
|
clearInterval(videoPlayInterval);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -44,8 +47,11 @@ function onVideoLoad() {
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
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]' : ''"
|
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
class="w-full h-full opacity-0"
|
||||||
|
:class="phase != 'result' ? 'z-10' : 'z-[-10]'"
|
||||||
|
></div>
|
||||||
<img v-if="phase == 'set-basic'" src="/placeholder.svg" alt="placeholder" />
|
<img v-if="phase == 'set-basic'" src="/placeholder.svg" alt="placeholder" />
|
||||||
<NuxtImg
|
<NuxtImg
|
||||||
v-else-if="media.type === 'image'"
|
v-else-if="media.type === 'image'"
|
||||||
|
|
@ -59,7 +65,7 @@ function onVideoLoad() {
|
||||||
v-else-if="media.type === 'video'"
|
v-else-if="media.type === 'video'"
|
||||||
:key="`${mediaPath}-video`"
|
:key="`${mediaPath}-video`"
|
||||||
ref="video"
|
ref="video"
|
||||||
:controls="route.path === '/result'"
|
:controls="phase == 'result'"
|
||||||
@canplaythrough="onVideoLoad()"
|
@canplaythrough="onVideoLoad()"
|
||||||
>
|
>
|
||||||
<source :src="joinURL(cdnUrl, media.name + '.mp4')" type="video/mp4" />
|
<source :src="joinURL(cdnUrl, media.name + '.mp4')" type="video/mp4" />
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ onKeyStroke(['N', 'n'], () => {
|
||||||
<div>
|
<div>
|
||||||
<div class="flex flex-row justify-around">
|
<div class="flex flex-row justify-around">
|
||||||
<input
|
<input
|
||||||
v-for="[element, value] of Object.entries({ TAK: true, NIE: false })"
|
v-for="[element, value] of Object.entries({ yes: true, no: false })"
|
||||||
:id="`odp_${element}`"
|
:id="`odp_${element}`"
|
||||||
:ref="`${value}-button`"
|
:ref="`${value}-button`"
|
||||||
:key="`btn_answer_${element}`"
|
:key="`btn_answer_${element}`"
|
||||||
|
|
@ -44,7 +44,7 @@ onKeyStroke(['N', 'n'], () => {
|
||||||
name="tak_nie"
|
name="tak_nie"
|
||||||
:value="value.toString()"
|
:value="value.toString()"
|
||||||
class="btn btn-primary btn-xl"
|
class="btn btn-primary btn-xl"
|
||||||
:aria-label="element"
|
:aria-label="$t(element).toLocaleUpperCase()"
|
||||||
:class="
|
:class="
|
||||||
phase == 'exam'
|
phase == 'exam'
|
||||||
? answer == null
|
? answer == null
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@
|
||||||
"B": "B",
|
"B": "B",
|
||||||
"C": "C"
|
"C": "C"
|
||||||
},
|
},
|
||||||
|
"yes": "Tak",
|
||||||
|
"no": "Nie",
|
||||||
|
"theme": "Motyw",
|
||||||
|
"light": "Jasny",
|
||||||
|
"dark": "Ciemny",
|
||||||
|
"auto": "Automatyczny",
|
||||||
"endExam": "Zakończ egzamin",
|
"endExam": "Zakończ egzamin",
|
||||||
"examEnd": "Koniec egzaminu",
|
"examEnd": "Koniec egzaminu",
|
||||||
"basicQuestions": "Pytania podstawowe",
|
"basicQuestions": "Pytania podstawowe",
|
||||||
|
|
|
||||||
|
|
@ -1,73 +1,79 @@
|
||||||
{
|
{
|
||||||
"mainTitle": "Test na prawo jazdy",
|
"mainTitle": "Driving exam",
|
||||||
"loading": "Ładowanie",
|
"loading": "Loading",
|
||||||
"keybinds": "Skróty klawiszowe",
|
"keybinds": "Keybinds",
|
||||||
"bindedKeys": {
|
"bindedKeys": {
|
||||||
"S": "niebieski przycisk start",
|
"S": "blue \"start\" button",
|
||||||
"D": "następne pytanie",
|
"D": "next question",
|
||||||
"X": "zakończ egzamin",
|
"X": "finish exam",
|
||||||
"T / Y": "Tak",
|
"T / Y": "Yes",
|
||||||
"N": "Nie",
|
"N": "No",
|
||||||
"A": "A",
|
"A": "A",
|
||||||
"B": "B",
|
"B": "B",
|
||||||
"C": "C"
|
"C": "C"
|
||||||
},
|
},
|
||||||
"endExam": "Zakończ egzamin",
|
"yes": "Yes",
|
||||||
"examEnd": "Koniec egzaminu",
|
"no": "No",
|
||||||
"basicQuestions": "Pytania podstawowe",
|
"theme": "Theme",
|
||||||
"advancedQuestions": "Pytania specjalistyczne",
|
"light": "Light",
|
||||||
"timeToGetAcquaintedWithTheQuestion": "Czas na zapoznanie się z pytaniem",
|
"dark": "Dark",
|
||||||
"timeForAnswer": "Czas na udzielenie odpowiedzi",
|
"auto": "Auto",
|
||||||
|
"endExam": "Finish exam",
|
||||||
|
"examEnd": "Exam finished",
|
||||||
|
"basicQuestions": "Basic questions",
|
||||||
|
"advancedQuestions": "Advanced questions",
|
||||||
|
"timeToGetAcquaintedWithTheQuestion": "Time to get acquainted with the question",
|
||||||
|
"timeForAnswer": "Time to answer",
|
||||||
"startBtn": "START",
|
"startBtn": "START",
|
||||||
"second": "s",
|
"second": "s",
|
||||||
"nextQuestion": "Następne pytanie",
|
"nextQuestion": "Next question",
|
||||||
"goBackToHomePage": "Wróć na stronę główną",
|
"goBackToHomePage": "Back to homepage",
|
||||||
"points": "Punkty",
|
"points": "Points",
|
||||||
"pointValue": "Wartość punktowa",
|
"pointValue": "Point value",
|
||||||
"currentCategory": "Aktualna kategoria",
|
"currentCategory": "Current category",
|
||||||
"timeToExamEnd": "Czas do końca egzaminu",
|
"timeToExamEnd": "Time until the exam's finished",
|
||||||
"result": "Wynik",
|
"result": "Result",
|
||||||
"startAgain": "Rozpocznij jeszcze raz",
|
"startAgain": "Start again",
|
||||||
"viewAnswers": "Przejrzyj odpowiedzi",
|
"viewAnswers": "View answers",
|
||||||
"doYouReallyWantToEndExam": "Czy na pewno chcesz zakończyć egzamin?",
|
"doYouReallyWantToEndExam": "Are you sure you want to finish the exam?",
|
||||||
"questionWithoutVisual": "Pytanie bez wizualizacji",
|
"questionWithoutVisual": "Question without visualization",
|
||||||
"categoryWord": "Kategoria",
|
"categoryWord": "Category",
|
||||||
"anAnomalyHasOccured": "Nastąpiła anomalia",
|
"anAnomalyHasOccured": "An anomaly has occured",
|
||||||
"redirectFrom": "Przekierowanie z",
|
"redirectFrom": "Redirecting from",
|
||||||
"end": "Koniec",
|
"end": "End",
|
||||||
"question": "Pytanie",
|
"question": "Question",
|
||||||
"anAPIErrorOccured": "Wystąpił błąd z API",
|
"anAPIErrorOccured": "An API error has occured",
|
||||||
"positive": "pozytywny",
|
"positive": "positive",
|
||||||
"negative": "negatywny",
|
"negative": "negative",
|
||||||
"theoreticalExam": "Egzamin teorytyczny",
|
"theoreticalExam": "Theoretical exam",
|
||||||
"category": {
|
"category": {
|
||||||
"description": {
|
"description": {
|
||||||
"A": "motocykle bez ograniczeń mocy",
|
"A": "motorcycle without limited power",
|
||||||
"B": "⭐ samochody osobowe do 3,5 t",
|
"B": "⭐ passenger cars up to 3,5 t",
|
||||||
"C": "pojazdy ciężarowe powyżej 3,5 t",
|
"C": "trucks above 3,5 t",
|
||||||
"D": "autobusy",
|
"D": "buses",
|
||||||
"T": "ciągniki rolnicze i pojazdy wolnobieżne",
|
"T": "agricultural tractor and low-speed vehicles",
|
||||||
"AM": "motorowery i lekkie czterokołowce",
|
"AM": "motobikes and light quadricycles",
|
||||||
"A1": "motocykle do 125 cm³ i 11 kW",
|
"A1": "motorcycles up to 125 cm³ and 11 kW",
|
||||||
"A2": "motocykle do 35 kW",
|
"A2": "motorcycles up to 35 kW",
|
||||||
"B1": "czterokołowce (np. quady)",
|
"B1": "quadricycles (e.g quads)",
|
||||||
"C1": "pojazdy od 3,5 t do 7,5 t",
|
"C1": "vehicles from 3,5 t to 7,5 t",
|
||||||
"D1": "autobusy do 16 pasażerów",
|
"D1": "buses up to 16 passengers",
|
||||||
"PT": "tramwaje"
|
"PT": "trams"
|
||||||
},
|
},
|
||||||
"age": {
|
"age": {
|
||||||
"A": "(24 lata; lub 20 lat jeśli masz kat. A2 min. 2 lata)",
|
"A": "(24 years; or 20 years if you've had category A2 for at least 2 years)",
|
||||||
"B": "(18 lat)",
|
"B": "(18 years)",
|
||||||
"C": "(21 lat; lub 18 lat z kwalifikacją wstępną)",
|
"C": "(21 years; or 18 years with preliminary qualification)",
|
||||||
"D": "(24 lata; lub 21 lat z kwalifikacją wstępną)",
|
"D": "(24 years; or 21 years with preliminary qualification)",
|
||||||
"T": "(16 lat)",
|
"T": "(16 years)",
|
||||||
"AM": "(14 lat)",
|
"AM": "(14 years)",
|
||||||
"A1": "(16 lat)",
|
"A1": "(16 years)",
|
||||||
"A2": "(18 lat)",
|
"A2": "(18 years)",
|
||||||
"B1": "(16 lat)",
|
"B1": "(16 years)",
|
||||||
"C1": "(18 lat)",
|
"C1": "(18 years)",
|
||||||
"D1": "(21 lat; lub 18 lat z kwalifikacją wstępną)",
|
"D1": "(21 years; or 18 years with preliminary qualification)",
|
||||||
"PT": "(21 lat)"
|
"PT": "(21 years)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@
|
||||||
"B": "B",
|
"B": "B",
|
||||||
"C": "C"
|
"C": "C"
|
||||||
},
|
},
|
||||||
|
"yes": "Tak",
|
||||||
|
"no": "Nie",
|
||||||
|
"theme": "Motyw",
|
||||||
|
"light": "Jasny",
|
||||||
|
"dark": "Ciemny",
|
||||||
|
"auto": "Automatyczny",
|
||||||
"endExam": "Zakończ egzamin",
|
"endExam": "Zakończ egzamin",
|
||||||
"examEnd": "Koniec egzaminu",
|
"examEnd": "Koniec egzaminu",
|
||||||
"basicQuestions": "Pytania podstawowe",
|
"basicQuestions": "Pytania podstawowe",
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@
|
||||||
"B": "B",
|
"B": "B",
|
||||||
"C": "C"
|
"C": "C"
|
||||||
},
|
},
|
||||||
|
"yes": "Tak",
|
||||||
|
"no": "Nie",
|
||||||
|
"theme": "Motyw",
|
||||||
|
"light": "Jasny",
|
||||||
|
"dark": "Ciemny",
|
||||||
|
"auto": "Automatyczny",
|
||||||
"endExam": "Zakończ egzamin",
|
"endExam": "Zakończ egzamin",
|
||||||
"examEnd": "Koniec egzaminu",
|
"examEnd": "Koniec egzaminu",
|
||||||
"basicQuestions": "Pytania podstawowe",
|
"basicQuestions": "Pytania podstawowe",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
export default defineNuxtRouteMiddleware(async () => {
|
export default defineNuxtRouteMiddleware(async () => {
|
||||||
const examStore = useExamStore();
|
const examStore = useExamStore();
|
||||||
|
const localePath = useLocalePath();
|
||||||
|
|
||||||
if (examStore.end) {
|
if (examStore.end) {
|
||||||
return '/result';
|
return localePath('result');
|
||||||
}
|
}
|
||||||
if (examStore.category === '') {
|
if (examStore.category === '') {
|
||||||
return '/anomaly';
|
return localePath('anomaly');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
export default defineNuxtRouteMiddleware(async () => {
|
export default defineNuxtRouteMiddleware(async () => {
|
||||||
const examStore = useExamStore();
|
const examStore = useExamStore();
|
||||||
|
const localePath = useLocalePath();
|
||||||
if (!examStore.end || examStore.category === '') {
|
if (!examStore.end || examStore.category === '') {
|
||||||
return '/anomaly';
|
return localePath('anomaly');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const advancedStore = useAdvancedStore();
|
||||||
<br />
|
<br />
|
||||||
{{ $t('advancedQuestions') }}:
|
{{ $t('advancedQuestions') }}:
|
||||||
<code class="text-xs">{{ advancedStore.advanced }}</code> <br />
|
<code class="text-xs">{{ advancedStore.advanced }}</code> <br />
|
||||||
<NuxtLink to="/" class="btn btn-primary">
|
<NuxtLink :to="$localePath('index')" class="btn btn-primary">
|
||||||
{{ $t('goBackToHomePage') }}
|
{{ $t('goBackToHomePage') }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,8 @@ function next() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const localePath = useLocalePath();
|
||||||
|
|
||||||
function endExam() {
|
function endExam() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
while (ending.value == false) {
|
while (ending.value == false) {
|
||||||
|
|
@ -200,9 +202,9 @@ function endExam() {
|
||||||
advancedStore.advanced == result.value.advanced &&
|
advancedStore.advanced == result.value.advanced &&
|
||||||
examStore.end
|
examStore.end
|
||||||
) {
|
) {
|
||||||
return navigateTo(`/result`, { replace: true });
|
return navigateTo(localePath(`result`), { replace: true });
|
||||||
} else {
|
} else {
|
||||||
return navigateTo(`/anomaly`);
|
return navigateTo(localePath(`anomaly`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,14 @@ const loading = ref(false);
|
||||||
const examStore = useExamStore();
|
const examStore = useExamStore();
|
||||||
await callOnce(() => examStore.resetExam(), { mode: 'navigation' });
|
await callOnce(() => examStore.resetExam(), { mode: 'navigation' });
|
||||||
|
|
||||||
|
const localePath = useLocalePath();
|
||||||
|
|
||||||
function setAndGo(category: string) {
|
function setAndGo(category: string) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
examStore.setCategory(category);
|
examStore.setCategory(category);
|
||||||
while (true) {
|
while (true) {
|
||||||
if (examStore.category === category) {
|
if (examStore.category === category) {
|
||||||
return navigateTo('/exam');
|
return navigateTo(localePath('exam'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -31,6 +33,27 @@ function changeLanguage() {
|
||||||
examStore.setLang(langSelect.value);
|
examStore.setLang(langSelect.value);
|
||||||
setLocale(langSelect.value as 'pl' | 'en' | 'de' | 'ua');
|
setLocale(langSelect.value as 'pl' | 'en' | 'de' | 'ua');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dark = ref(false);
|
||||||
|
|
||||||
|
function getTheme() {
|
||||||
|
if (
|
||||||
|
window.matchMedia &&
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
) {
|
||||||
|
dark.value = true;
|
||||||
|
} else {
|
||||||
|
dark.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watchEffect(getTheme);
|
||||||
|
|
||||||
|
const themeStore = useThemeStore();
|
||||||
|
|
||||||
|
function themeAuto() {
|
||||||
|
themeStore.set('');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -50,8 +73,24 @@ function changeLanguage() {
|
||||||
<option value="ua">Ukrainian (Українська)</option>
|
<option value="ua">Ukrainian (Українська)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<label class="flex cursor-pointer gap-2 text-lg items-center">
|
||||||
|
{{ $t('theme') }}: {{ $t('light') }}
|
||||||
|
<input
|
||||||
|
v-model="dark"
|
||||||
|
type="checkbox"
|
||||||
|
value="dark"
|
||||||
|
class="toggle theme-controller"
|
||||||
|
@change="themeStore.set(dark ? 'dark' : 'light')"
|
||||||
|
/>
|
||||||
|
{{ $t('dark') }}
|
||||||
|
</label>
|
||||||
|
<div class="btn btn-soft btn-sm" @click="themeAuto()">
|
||||||
|
{{ $t('auto') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col flex-wrap gap-2 items-start p-4 bg-slate-100 border-1 border-slate-500 rounded-xl w-fit"
|
class="flex flex-col flex-wrap gap-2 items-start p-4 bg-base-300 border-1 border-slate-500 rounded-xl w-fit"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="category in categories"
|
v-for="category in categories"
|
||||||
|
|
|
||||||
|
|
@ -89,16 +89,18 @@ function changeCount(num: number) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const localePath = useLocalePath();
|
||||||
|
|
||||||
async function again() {
|
async function again() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await examStore.mildReset();
|
await examStore.mildReset();
|
||||||
return await navigateTo('/exam');
|
return await navigateTo(localePath('exam'));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function home() {
|
async function home() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await examStore.resetExam();
|
await examStore.resetExam();
|
||||||
return await navigateTo('/');
|
return await navigateTo(localePath('index'));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -117,20 +119,22 @@ async function home() {
|
||||||
<div class="col-span-3 flex flex-col">
|
<div class="col-span-3 flex flex-col">
|
||||||
<BarTop :points="question?.weight" :category="examStore.category" />
|
<BarTop :points="question?.weight" :category="examStore.category" />
|
||||||
<MediaBox :media-path="question?.media_url" phase="" />
|
<MediaBox :media-path="question?.media_url" phase="" />
|
||||||
<QuestionBasic
|
<div>
|
||||||
v-if="now === 'basic'"
|
<QuestionBasic
|
||||||
v-model="answer"
|
v-if="now === 'basic'"
|
||||||
:question="questionBasic"
|
v-model="answer"
|
||||||
phase="result"
|
:question="questionBasic"
|
||||||
class="select-none z-[-1]"
|
phase="result"
|
||||||
/>
|
class="select-none z-[-1]"
|
||||||
<QuestionAdvanced
|
/>
|
||||||
v-else-if="now === 'advanced'"
|
<QuestionAdvanced
|
||||||
v-model="answer"
|
v-else-if="now === 'advanced'"
|
||||||
:question="questionAdvanced"
|
v-model="answer"
|
||||||
phase="result"
|
:question="questionAdvanced"
|
||||||
class="select-none z-[-1]"
|
phase="result"
|
||||||
/>
|
class="select-none z-[-1]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<BarRightResult
|
<BarRightResult
|
||||||
:result="{
|
:result="{
|
||||||
|
|
|
||||||
13
store/themeStore.ts
Normal file
13
store/themeStore.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
export const useThemeStore = defineStore('themeStore', {
|
||||||
|
state: () => ({
|
||||||
|
theme: '',
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
async set(theme: string) {
|
||||||
|
this.theme = theme;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
persist: {
|
||||||
|
storage: piniaPluginPersistedstate.localStorage(),
|
||||||
|
},
|
||||||
|
});
|
||||||
Loading…
Add table
Reference in a new issue