diff --git a/README.md b/README.md index d34ba1c..5e897e0 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,12 @@ The newest at the moment of me writing this (December 13th 2025) are the (visual - 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 + - [ ] UI i18n + - [x] pl + - [ ] en + - [ ] de + - [ ] ua + - [ ] 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) diff --git a/categories.ts b/categories.ts index 4127f23..7a888b7 100644 --- a/categories.ts +++ b/categories.ts @@ -12,33 +12,3 @@ export default [ 'D1', '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)', -]; diff --git a/components/EndModal.vue b/components/EndModal.vue index 430cf49..7b75a00 100644 --- a/components/EndModal.vue +++ b/components/EndModal.vue @@ -18,8 +18,8 @@ watchEffect(() => { class="flex justify-center items-center backdrop-blur-sm modal" > diff --git a/components/ResultModal.vue b/components/ResultModal.vue index cd97fe9..28db928 100644 --- a/components/ResultModal.vue +++ b/components/ResultModal.vue @@ -17,18 +17,24 @@ defineEmits(['again', 'home']);

-
Kategoria:
-
Punkty: / 74
-
Wynik:
+
+ {{ $t('categoryWord') }}: +
+
+ {{ $t('points') }}: / 74 +
+
+ {{ $t('result') }}: +
- Wróć na stronę główną + {{ $t('goBackToHomePage') }}
- Rozpocznij jeszcze raz + {{ $t('startAgain') }}
diff --git a/components/bar/Top.vue b/components/bar/Top.vue index b9630b9..baf4f39 100644 --- a/components/bar/Top.vue +++ b/components/bar/Top.vue @@ -23,19 +23,19 @@ const timeRemainingFriendly = computed(() => { class="flex flex-none flex-row gap-4 *:flex *:items-center *:gap-3 border-b p-4 border-base-300 bg-base-100" >
- Wartość punktowa + {{ $t('pointValue') }}
{{ points }}
- Aktualna kategoria + {{ $t('currentCategory') }}
{{ category }}
- Czas do końca egzaminu + {{ $t('timeToExamEnd') }}
{{ timeRemainingFriendly }}
diff --git a/components/bar/right/Exam.vue b/components/bar/right/Exam.vue index 7f78205..9e4db66 100644 --- a/components/bar/right/Exam.vue +++ b/components/bar/right/Exam.vue @@ -54,21 +54,25 @@ onKeyStroke(['X', 'x'], () => { class="btn btn-warning btn-xl" @click="tryEndExam()" > - Zakończ egzamin + {{ $t('endExam') }}
- + - +
@@ -77,14 +81,16 @@ onKeyStroke(['X', 'x'], () => { v-if="phase == 'set-basic'" class="text-center text-xl flex flex-col gap-2" > - Czas na zapoznanie się z pytaniem + + {{ $t('timeToGetAcquaintedWithTheQuestion') }} +
- START + {{ $t('startBtn') }}
{ max="20" > - {{ time >= 0 ? time : 0 }}s + {{ time >= 0 ? time : 0 }} {{ $t('second') }}
- Czas na udzielenie odpowiedzi + + {{ $t('timeForAnswer') }} +
{ :max="phase == 'start-basic' ? 15 : 45" > - {{ time >= 0 ? time : 0 }}s + {{ time >= 0 ? time : 0 }} {{ $t('second') }}
- Skróty klawiszowe + + {{ $t('keybinds') }} + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +
Sniebieski przycisk start
Dnastępne pytanie
Xzakończ egzamin
T / YTak
NNie
AA
BB
CC
{{ key }}{{ $t(`bindedKeys.${key}`) }}
@@ -159,7 +144,7 @@ onKeyStroke(['X', 'x'], () => { :disabled="ending || setBasic" @click="emit('nextQuestion')" > - Następne pytanie + {{ $t('nextQuestion') }}
diff --git a/components/bar/right/Result.vue b/components/bar/right/Result.vue index 277793f..e795707 100644 --- a/components/bar/right/Result.vue +++ b/components/bar/right/Result.vue @@ -21,11 +21,11 @@ const emit = defineEmits<{ class="flex flex-col items-stretch p-4 gap-6 border-l border-base-300 bg-base-100" >
- Wróć na stronę główną + {{ $t('goBackToHomePage') }}
-
Punkty: / 74
-
Wynik:
+
+ {{ $t('points') }}: / 74 +
+
+ {{ $t('result') }}: +
- Rozpocznij jeszcze raz + {{ $t('startAgain') }}
diff --git a/i18n/locales/de.json b/i18n/locales/de.json index 31ee939..ca3d723 100644 --- a/i18n/locales/de.json +++ b/i18n/locales/de.json @@ -1,15 +1,73 @@ { - "mainTitle": "die testenrn", - "categoryDescriptionA": "motocykle bez ograniczeń mocy", - "categoryDescriptionB": "⭐ samochody osobowe do 3,5 t", - "categoryDescriptionC": "pojazdy ciężarowe powyżej 3,5 t", - "categoryDescriptionD": "autobusy", - "categoryDescriptionT": "ciągniki rolnicze i pojazdy wolnobieżne", - "categoryDescriptionAM": "motorowery i lekkie czterokołowce", - "categoryDescriptionA1": "motocykle do 125 cm³ i 11 kW", - "categoryDescriptionA2": "motocykle do 35 kW", - "categoryDescriptionB1": "czterokołowce (np. quady)", - "categoryDescriptionC1": "pojazdy od 3,5 t do 7,5 t", - "categoryDescriptionD1": "autobusy do 16 pasażerów", - "categoryDescriptionPT": "tramwaje" + "mainTitle": "Test na prawo jazdy", + "loading": "Ładowanie", + "keybinds": "Skróty klawiszowe", + "bindedKeys": { + "S": "niebieski przycisk start", + "D": "następne pytanie", + "X": "zakończ egzamin", + "T / Y": "Tak", + "N": "Nie", + "A": "A", + "B": "B", + "C": "C" + }, + "endExam": "Zakończ egzamin", + "examEnd": "Koniec egzaminu", + "basicQuestions": "Pytania podstawowe", + "advancedQuestions": "Pytania specjalistyczne", + "timeToGetAcquaintedWithTheQuestion": "Czas na zapoznanie się z pytaniem", + "timeForAnswer": "Czas na udzielenie odpowiedzi", + "startBtn": "START", + "second": "s", + "nextQuestion": "Następne pytanie", + "goBackToHomePage": "Wróć na stronę główną", + "points": "Punkty", + "pointValue": "Wartość punktowa", + "currentCategory": "Aktualna kategoria", + "timeToExamEnd": "Czas do końca egzaminu", + "result": "Wynik", + "startAgain": "Rozpocznij jeszcze raz", + "viewAnswers": "Przejrzyj odpowiedzi", + "doYouReallyWantToEndExam": "Czy na pewno chcesz zakończyć egzamin?", + "questionWithoutVisual": "Pytanie bez wizualizacji", + "categoryWord": "Kategoria", + "anAnomalyHasOccured": "Nastąpiła anomalia", + "redirectFrom": "Przekierowanie z", + "end": "Koniec", + "question": "Pytanie", + "anAPIErrorOccured": "Wystąpił błąd z API", + "positive": "pozytywny", + "negative": "negatywny", + "theoreticalExam": "Egzamin teorytyczny", + "category": { + "description": { + "A": "motocykle bez ograniczeń mocy", + "B": "⭐ samochody osobowe do 3,5 t", + "C": "pojazdy ciężarowe powyżej 3,5 t", + "D": "autobusy", + "T": "ciągniki rolnicze i pojazdy wolnobieżne", + "AM": "motorowery i lekkie czterokołowce", + "A1": "motocykle do 125 cm³ i 11 kW", + "A2": "motocykle do 35 kW", + "B1": "czterokołowce (np. quady)", + "C1": "pojazdy od 3,5 t do 7,5 t", + "D1": "autobusy do 16 pasażerów", + "PT": "tramwaje" + }, + "age": { + "A": "(24 lata; lub 20 lat jeśli masz kat. A2 min. 2 lata)", + "B": "(18 lat)", + "C": "(21 lat; lub 18 lat z kwalifikacją wstępną)", + "D": "(24 lata; lub 21 lat z kwalifikacją wstępną)", + "T": "(16 lat)", + "AM": "(14 lat)", + "A1": "(16 lat)", + "A2": "(18 lat)", + "B1": "(16 lat)", + "C1": "(18 lat)", + "D1": "(21 lat; lub 18 lat z kwalifikacją wstępną)", + "PT": "(21 lat)" + } + } } diff --git a/i18n/locales/en.json b/i18n/locales/en.json index b87b3c1..ca3d723 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -1,15 +1,73 @@ { - "mainTitle": "Test for exam drievrsdy", - "categoryDescriptionA": "motocykle bez ograniczeń mocy", - "categoryDescriptionB": "⭐ samochody osobowe do 3,5 t", - "categoryDescriptionC": "pojazdy ciężarowe powyżej 3,5 t", - "categoryDescriptionD": "autobusy", - "categoryDescriptionT": "ciągniki rolnicze i pojazdy wolnobieżne", - "categoryDescriptionAM": "motorowery i lekkie czterokołowce", - "categoryDescriptionA1": "motocykle do 125 cm³ i 11 kW", - "categoryDescriptionA2": "motocykle do 35 kW", - "categoryDescriptionB1": "czterokołowce (np. quady)", - "categoryDescriptionC1": "pojazdy od 3,5 t do 7,5 t", - "categoryDescriptionD1": "autobusy do 16 pasażerów", - "categoryDescriptionPT": "tramwaje" + "mainTitle": "Test na prawo jazdy", + "loading": "Ładowanie", + "keybinds": "Skróty klawiszowe", + "bindedKeys": { + "S": "niebieski przycisk start", + "D": "następne pytanie", + "X": "zakończ egzamin", + "T / Y": "Tak", + "N": "Nie", + "A": "A", + "B": "B", + "C": "C" + }, + "endExam": "Zakończ egzamin", + "examEnd": "Koniec egzaminu", + "basicQuestions": "Pytania podstawowe", + "advancedQuestions": "Pytania specjalistyczne", + "timeToGetAcquaintedWithTheQuestion": "Czas na zapoznanie się z pytaniem", + "timeForAnswer": "Czas na udzielenie odpowiedzi", + "startBtn": "START", + "second": "s", + "nextQuestion": "Następne pytanie", + "goBackToHomePage": "Wróć na stronę główną", + "points": "Punkty", + "pointValue": "Wartość punktowa", + "currentCategory": "Aktualna kategoria", + "timeToExamEnd": "Czas do końca egzaminu", + "result": "Wynik", + "startAgain": "Rozpocznij jeszcze raz", + "viewAnswers": "Przejrzyj odpowiedzi", + "doYouReallyWantToEndExam": "Czy na pewno chcesz zakończyć egzamin?", + "questionWithoutVisual": "Pytanie bez wizualizacji", + "categoryWord": "Kategoria", + "anAnomalyHasOccured": "Nastąpiła anomalia", + "redirectFrom": "Przekierowanie z", + "end": "Koniec", + "question": "Pytanie", + "anAPIErrorOccured": "Wystąpił błąd z API", + "positive": "pozytywny", + "negative": "negatywny", + "theoreticalExam": "Egzamin teorytyczny", + "category": { + "description": { + "A": "motocykle bez ograniczeń mocy", + "B": "⭐ samochody osobowe do 3,5 t", + "C": "pojazdy ciężarowe powyżej 3,5 t", + "D": "autobusy", + "T": "ciągniki rolnicze i pojazdy wolnobieżne", + "AM": "motorowery i lekkie czterokołowce", + "A1": "motocykle do 125 cm³ i 11 kW", + "A2": "motocykle do 35 kW", + "B1": "czterokołowce (np. quady)", + "C1": "pojazdy od 3,5 t do 7,5 t", + "D1": "autobusy do 16 pasażerów", + "PT": "tramwaje" + }, + "age": { + "A": "(24 lata; lub 20 lat jeśli masz kat. A2 min. 2 lata)", + "B": "(18 lat)", + "C": "(21 lat; lub 18 lat z kwalifikacją wstępną)", + "D": "(24 lata; lub 21 lat z kwalifikacją wstępną)", + "T": "(16 lat)", + "AM": "(14 lat)", + "A1": "(16 lat)", + "A2": "(18 lat)", + "B1": "(16 lat)", + "C1": "(18 lat)", + "D1": "(21 lat; lub 18 lat z kwalifikacją wstępną)", + "PT": "(21 lat)" + } + } } diff --git a/i18n/locales/pl.json b/i18n/locales/pl.json index 0864a0c..ca3d723 100644 --- a/i18n/locales/pl.json +++ b/i18n/locales/pl.json @@ -28,6 +28,18 @@ "timeToExamEnd": "Czas do końca egzaminu", "result": "Wynik", "startAgain": "Rozpocznij jeszcze raz", + "viewAnswers": "Przejrzyj odpowiedzi", + "doYouReallyWantToEndExam": "Czy na pewno chcesz zakończyć egzamin?", + "questionWithoutVisual": "Pytanie bez wizualizacji", + "categoryWord": "Kategoria", + "anAnomalyHasOccured": "Nastąpiła anomalia", + "redirectFrom": "Przekierowanie z", + "end": "Koniec", + "question": "Pytanie", + "anAPIErrorOccured": "Wystąpił błąd z API", + "positive": "pozytywny", + "negative": "negatywny", + "theoreticalExam": "Egzamin teorytyczny", "category": { "description": { "A": "motocykle bez ograniczeń mocy", diff --git a/i18n/locales/ua.json b/i18n/locales/ua.json index 6e1fa69..ca3d723 100644 --- a/i18n/locales/ua.json +++ b/i18n/locales/ua.json @@ -1,16 +1,73 @@ { - "mainTitle": "ykrainska mova test", - "categoryDescriptionA": "motocykle bez ograniczeń mocy", - "categoryDescriptionB": "⭐ samochody osobowe do 3,5 t", - "categoryDescriptionC": "pojazdy ciężarowe powyżej 3,5 t", - "categoryDescriptionD": "autobusy", - "categoryDescriptionT": "ciągniki rolnicze i pojazdy wolnobieżne", - "categoryDescriptionAM": "motorowery i lekkie czterokołowce", - "categoryDescriptionA1": "motocykle do 125 cm³ i 11 kW", - "categoryDescriptionA2": "motocykle do 35 kW", - "categoryDescriptionB1": "czterokołowce (np. quady)", - "categoryDescriptionC1": "pojazdy od 3,5 t do 7,5 t", - "categoryDescriptionD1": "autobusy do 16 pasażerów", - "categoryDescriptionPT": "tramwaje", - "second": "с" + "mainTitle": "Test na prawo jazdy", + "loading": "Ładowanie", + "keybinds": "Skróty klawiszowe", + "bindedKeys": { + "S": "niebieski przycisk start", + "D": "następne pytanie", + "X": "zakończ egzamin", + "T / Y": "Tak", + "N": "Nie", + "A": "A", + "B": "B", + "C": "C" + }, + "endExam": "Zakończ egzamin", + "examEnd": "Koniec egzaminu", + "basicQuestions": "Pytania podstawowe", + "advancedQuestions": "Pytania specjalistyczne", + "timeToGetAcquaintedWithTheQuestion": "Czas na zapoznanie się z pytaniem", + "timeForAnswer": "Czas na udzielenie odpowiedzi", + "startBtn": "START", + "second": "s", + "nextQuestion": "Następne pytanie", + "goBackToHomePage": "Wróć na stronę główną", + "points": "Punkty", + "pointValue": "Wartość punktowa", + "currentCategory": "Aktualna kategoria", + "timeToExamEnd": "Czas do końca egzaminu", + "result": "Wynik", + "startAgain": "Rozpocznij jeszcze raz", + "viewAnswers": "Przejrzyj odpowiedzi", + "doYouReallyWantToEndExam": "Czy na pewno chcesz zakończyć egzamin?", + "questionWithoutVisual": "Pytanie bez wizualizacji", + "categoryWord": "Kategoria", + "anAnomalyHasOccured": "Nastąpiła anomalia", + "redirectFrom": "Przekierowanie z", + "end": "Koniec", + "question": "Pytanie", + "anAPIErrorOccured": "Wystąpił błąd z API", + "positive": "pozytywny", + "negative": "negatywny", + "theoreticalExam": "Egzamin teorytyczny", + "category": { + "description": { + "A": "motocykle bez ograniczeń mocy", + "B": "⭐ samochody osobowe do 3,5 t", + "C": "pojazdy ciężarowe powyżej 3,5 t", + "D": "autobusy", + "T": "ciągniki rolnicze i pojazdy wolnobieżne", + "AM": "motorowery i lekkie czterokołowce", + "A1": "motocykle do 125 cm³ i 11 kW", + "A2": "motocykle do 35 kW", + "B1": "czterokołowce (np. quady)", + "C1": "pojazdy od 3,5 t do 7,5 t", + "D1": "autobusy do 16 pasażerów", + "PT": "tramwaje" + }, + "age": { + "A": "(24 lata; lub 20 lat jeśli masz kat. A2 min. 2 lata)", + "B": "(18 lat)", + "C": "(21 lat; lub 18 lat z kwalifikacją wstępną)", + "D": "(24 lata; lub 21 lat z kwalifikacją wstępną)", + "T": "(16 lat)", + "AM": "(14 lat)", + "A1": "(16 lat)", + "A2": "(18 lat)", + "B1": "(16 lat)", + "C1": "(18 lat)", + "D1": "(21 lat; lub 18 lat z kwalifikacją wstępną)", + "PT": "(21 lat)" + } + } } diff --git a/nuxt.config.ts b/nuxt.config.ts index b9bcf32..71cd33b 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -9,6 +9,7 @@ export default defineNuxtConfig({ 'pinia-plugin-persistedstate/nuxt', '@nuxt/eslint', '@nuxt/image', + '@nuxtjs/i18n', ], ssr: false, imports: { @@ -35,6 +36,15 @@ export default defineNuxtConfig({ }, }, }, + i18n: { + locales: [ + { code: 'pl', language: 'pl-PL', file: 'pl.json' }, + { code: 'en', language: 'en-GB', file: 'en.json' }, + { code: 'de', language: 'de-DE', file: 'de.json' }, + { code: 'ua', language: 'uk-UK', file: 'ua.json' }, + ], + defaultLocale: 'pl', + }, image: { providers: { selfhost: { diff --git a/package.json b/package.json index 553781e..b3592f1 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@libsql/client": "^0.15.15", "@nuxt/fonts": "0.11.1", "@nuxt/image": "1.10.0", + "@nuxtjs/i18n": "10.2.1", "@nuxtjs/tailwindcss": "6.13.2", "@pinia/nuxt": "0.11.0", "@vueuse/core": "^14.1.0", @@ -33,6 +34,7 @@ "pinia-plugin-persistedstate": "^4.7.1", "ufo": "^1.6.1", "vue": "latest", + "vue-country-flag-next": "^2.3.2", "vue-router": "latest" }, "packageManager": "pnpm@10.4.1+sha512.c753b6c3ad7afa13af388fa6d808035a008e30ea9993f58c6663e2bc5ff21679aa834db094987129aa4d488b86df57f7b634981b2f827cdcacc698cc0cfb88af", diff --git a/pages/anomaly.vue b/pages/anomaly.vue index e1dd3fd..5aedc05 100644 --- a/pages/anomaly.vue +++ b/pages/anomaly.vue @@ -6,17 +6,20 @@ const advancedStore = useAdvancedStore(); diff --git a/pages/exam.vue b/pages/exam.vue index 8208621..f191038 100644 --- a/pages/exam.vue +++ b/pages/exam.vue @@ -80,7 +80,7 @@ function clickNext() { onMounted(() => { useHead({ - title: 'Pytanie 1/20', + title: `${$t('question')} 1/20`, }); window.addEventListener('beforeunload', preventRefresh); @@ -90,9 +90,9 @@ onMounted(() => { watchEffect(() => { if (now.value === 'basic') - useHead({ title: `Pytanie ${countBasic.value + 1}/20` }); + useHead({ title: `${$t('question')} ${countBasic.value + 1}/20` }); if (now.value === 'advanced') - useHead({ title: `Pytanie ${countAdvanced.value + 1}/12` }); + useHead({ title: `${$t('question')} ${countAdvanced.value + 1}/12` }); }); watchEffect(() => { @@ -257,7 +257,10 @@ const showEndModal = ref(false);
- An API error occurred: {{ errorBasic }} {{ errorAdvanced }} + {{ $t('anAPIErrorOccured') }}:
+ {{ errorBasic }} +
+ {{ errorAdvanced }}
-import categories, { opis, wiek } from '~/categories'; +import CountryFlag from 'vue-country-flag-next'; +import categories from '~/categories'; onMounted(() => { useHead({ - title: 'Test na prawo jazdy', + title: $t('mainTitle'), }); }); +const { setLocale } = useI18n(); + const loading = ref(false); const examStore = useExamStore(); @@ -21,17 +24,37 @@ function setAndGo(category: string) { } } } + +const langSelect = ref(examStore.lang); + +function changeLanguage() { + examStore.setLang(langSelect.value); + setLocale(langSelect.value as 'pl' | 'en' | 'de' | 'ua'); +}