i18n: german ui, readme overhaul
compose: unless-stopped add source code, license, author notice at the bottom of index page
This commit is contained in:
parent
1100abf141
commit
08e2060245
4 changed files with 148 additions and 127 deletions
33
README.md
33
README.md
|
|
@ -2,40 +2,35 @@
|
|||
|
||||
## 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
|
||||
### db
|
||||
|
||||
^^ Above is kind of outdated, project moved from PostgreSQL to SQLite - I included a `database.db` file in the `db/` folder, although it has older dataset of questions from the Ministry - foreshadowing...
|
||||
A python script at [db-prawo-jazdy](https://git.mandarynki.eu/netman/db-prawo-jazdy) is designed to convert the CSV(s) to a SQLite database for use here. When you acquire your database via that script, insert it at your desired path (default `./db/database.db`) and change the `DATABASE_URL` environment value in `.env`. Visit [db-prawo-jazdy](https://git.mandarynki.eu/netman/db-prawo-jazdy) 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 database from November 2025 is included here at `./db/database.db`
|
||||
|
||||
The newest at the moment of me writing this (December 16th 2025) are the (visualisations for questions from November 2025)[https://www.gov.pl/pliki/mi/pytania_egzaminacyjne_na_prawo_jazdy_11_2025.zip]
|
||||
### media
|
||||
|
||||
# To-do:
|
||||
A shell script at [media-prawo-jazdy](https://git.mandarynki.eu/netman/media-prawo-jazdy) for media files ([available on the website of the Ministry of Infrastructure](https://www.gov.pl/web/infrastruktura/prawo-jazdy) under the link title `Pytania egzaminacyjne na prawo jazdy`) will convert (copy) all `.wmv` files to `.mp4` and copy all `.jpeg` files to `.jpg`. When you have all media and the script completed successfully, host these files on a webserver of your choice (e.g. apache, nginx), and change the `CDN_URL` environment value in `.env` to your webserver URL including the folder path to the media files. Visit [media-prawo-jazdy](https://git.mandarynki.eu/netman/media-prawo-jazdy) for more details.
|
||||
|
||||
## 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] <b>Fixed?</b> Needs more testing, but should be fine. (question-mark?) - middleware between pages; finishing exam sometimes redirects to homepage instead of results, major issue
|
||||
- [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
|
||||
- S - start, D - next question, X - exam end, T/Y - yes, N - no, A - A, B - B, C - C
|
||||
- [ ] i18n - pl, en, de, ua (not all questions are available in ua, api handle)
|
||||
- [ ] UI i18n
|
||||
- [x] pl
|
||||
- [x] en
|
||||
- [ ] de
|
||||
- [x] de
|
||||
- [ ] ua
|
||||
- [x] db: examstore add language field, api handle languages (questions lang)
|
||||
- [ ] nuxt3 -> nuxt4
|
||||
- [ ] clean up js code in exam.vue and result.vue (currently a little bit of a mess)
|
||||
|
||||
## Some information about the project
|
||||
|
|
@ -50,16 +45,14 @@ This project is a website mimicking an official driver's license theoritical exa
|
|||
|
||||
## Setup
|
||||
|
||||
Copy `.env.example` to `.env` and modify it to values specified in the `Required#db` and `Required#media` sections according to your case.
|
||||
|
||||
This project utilizes `pnpm`, thus it is recommended
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
Check out `.env.example`, mainly CDN_URL for media http url
|
||||
|
||||
As of Dec. 16 2025 a test database is included at `./db/database.db`
|
||||
|
||||
### Development Server
|
||||
|
||||
Start the development server on `http://localhost:3000`:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
services:
|
||||
prawojazdy:
|
||||
restart: unless-stopped
|
||||
container_name: prawojazdy
|
||||
build: .
|
||||
ports:
|
||||
|
|
|
|||
|
|
@ -1,79 +1,79 @@
|
|||
{
|
||||
"mainTitle": "Test na prawo jazdy",
|
||||
"loading": "Ładowanie",
|
||||
"keybinds": "Skróty klawiszowe",
|
||||
"mainTitle": "Führerscheinprüfung",
|
||||
"loading": "Laden",
|
||||
"keybinds": "Tastenkürzel",
|
||||
"bindedKeys": {
|
||||
"S": "niebieski przycisk start",
|
||||
"D": "następne pytanie",
|
||||
"X": "zakończ egzamin",
|
||||
"T / Y": "Tak",
|
||||
"N": "Nie",
|
||||
"S": "blauer „Start“-Button",
|
||||
"D": "nächste Frage",
|
||||
"X": "Prüfung beenden",
|
||||
"T / Y": "Ja",
|
||||
"N": "Nein",
|
||||
"A": "A",
|
||||
"B": "B",
|
||||
"C": "C"
|
||||
},
|
||||
"yes": "Tak",
|
||||
"no": "Nie",
|
||||
"theme": "Motyw",
|
||||
"light": "Jasny",
|
||||
"dark": "Ciemny",
|
||||
"auto": "Automatyczny",
|
||||
"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",
|
||||
"yes": "Ja",
|
||||
"no": "Nein",
|
||||
"theme": "Design",
|
||||
"light": "Hell",
|
||||
"dark": "Dunkel",
|
||||
"auto": "Automatisch",
|
||||
"endExam": "Prüfung beenden",
|
||||
"examEnd": "Prüfung beendet",
|
||||
"basicQuestions": "Grundfragen",
|
||||
"advancedQuestions": "Spezialfragen",
|
||||
"timeToGetAcquaintedWithTheQuestion": "Zeit zum Lesen der Frage",
|
||||
"timeForAnswer": "Antwortzeit",
|
||||
"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",
|
||||
"nextQuestion": "Nächste Frage",
|
||||
"goBackToHomePage": "Zur Startseite",
|
||||
"points": "Punkte",
|
||||
"pointValue": "Punktwert",
|
||||
"currentCategory": "Aktuelle Kategorie",
|
||||
"timeToExamEnd": "Verbleibende Prüfungszeit",
|
||||
"result": "Ergebnis",
|
||||
"startAgain": "Erneut starten",
|
||||
"viewAnswers": "Antworten anzeigen",
|
||||
"doYouReallyWantToEndExam": "Möchten Sie die Prüfung wirklich beenden?",
|
||||
"questionWithoutVisual": "Frage ohne Visualisierung",
|
||||
"categoryWord": "Kategorie",
|
||||
"anAnomalyHasOccured": "Ein unerwarteter Fehler ist aufgetreten",
|
||||
"redirectFrom": "Weiterleitung von",
|
||||
"end": "Ende",
|
||||
"question": "Frage",
|
||||
"anAPIErrorOccured": "API-Fehler ist aufgetreten",
|
||||
"positive": "Positiv",
|
||||
"negative": "Negativ",
|
||||
"theoreticalExam": "Theoretische Prüfung",
|
||||
"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"
|
||||
"A": "Motorräder ohne Leistungsbegrenzung",
|
||||
"B": "⭐ Personenkraftwagen bis 3,5 t",
|
||||
"C": "Lastkraftwagen über 3,5 t",
|
||||
"D": "Busse",
|
||||
"T": "Landwirtschaftliche Traktoren und langsam fahrende Fahrzeuge",
|
||||
"AM": "Mopeds und leichte Quadricycles",
|
||||
"A1": "Motorräder bis 125 cm³ und 11 kW",
|
||||
"A2": "Motorräder bis 35 kW",
|
||||
"B1": "Quadricycles (z. B. Quads)",
|
||||
"C1": "Fahrzeuge von 3,5 t bis 7,5 t",
|
||||
"D1": "Busse mit bis zu 16 Fahrgastplätzen",
|
||||
"PT": "Straßenbahnen"
|
||||
},
|
||||
"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)"
|
||||
"A": "(24 Jahre alt; oder 20 Jahre bei mindestens 2 Jahren Besitz der Klasse A2)",
|
||||
"B": "(18 Jahre alt)",
|
||||
"C": "(21 Jahre alt; oder 18 Jahre mit Grundqualifikation)",
|
||||
"D": "(24 Jahre alt; oder 21 Jahre mit Grundqualifikation)",
|
||||
"T": "(16 Jahre alt)",
|
||||
"AM": "(14 Jahre alt)",
|
||||
"A1": "(16 Jahre alt)",
|
||||
"A2": "(18 Jahre alt)",
|
||||
"B1": "(16 Jahre alt)",
|
||||
"C1": "(18 Jahre alt)",
|
||||
"D1": "(21 Jahre alt; oder 18 Jahre alt mit Grundqualifikation)",
|
||||
"PT": "(21 Jahre alt)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
113
pages/index.vue
113
pages/index.vue
|
|
@ -63,53 +63,80 @@ function themeAuto() {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="!loading" class="text-3xl m-2 flex flex-col gap-2">
|
||||
<span>{{ $t('mainTitle') }}</span>
|
||||
<div class="flex gap-2">
|
||||
<CountryFlag
|
||||
class="block border border-1 border-black"
|
||||
:country="langSelect != 'en' ? langSelect : 'gb'"
|
||||
size="big"
|
||||
/>
|
||||
<select v-model="langSelect" class="select" @change="changeLanguage">
|
||||
<option value="pl">Polish (Polski)</option>
|
||||
<option value="en">English</option>
|
||||
<option value="de">German (Deutsch)</option>
|
||||
<option value="ua">Ukrainian (Українська)</option>
|
||||
</select>
|
||||
</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')"
|
||||
<div v-if="!loading" class="text-3xl flex flex-col gap-2 min-h-dvh">
|
||||
<div class="flex flex-col p-2 gap-2">
|
||||
<span>{{ $t('mainTitle') }}</span>
|
||||
<div class="flex gap-2">
|
||||
<CountryFlag
|
||||
class="block border border-1 border-black"
|
||||
:country="langSelect != 'en' ? langSelect : 'gb'"
|
||||
size="big"
|
||||
/>
|
||||
{{ $t('dark') }}
|
||||
</label>
|
||||
<div class="btn btn-soft btn-sm" @click="themeAuto()">
|
||||
{{ $t('auto') }}
|
||||
<select v-model="langSelect" class="select" @change="changeLanguage">
|
||||
<option value="pl">Polish (Polski)</option>
|
||||
<option value="en">English</option>
|
||||
<option value="de">German (Deutsch)</option>
|
||||
<option value="ua">Ukrainian (Українська)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
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
|
||||
v-for="category in categories"
|
||||
:key="`btn-${category}`"
|
||||
class="flex flex-row gap-3 items-center"
|
||||
>
|
||||
<button class="btn btn-xl btn-secondary" @click="setAndGo(category)">
|
||||
{{ category }}
|
||||
</button>
|
||||
<div class="flex flex-col text-sm">
|
||||
<div>{{ $t(`category.description.${category}`) }}</div>
|
||||
<div>{{ $t(`category.age.${category}`) }}</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
|
||||
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
|
||||
v-for="category in categories"
|
||||
:key="`btn-${category}`"
|
||||
class="flex flex-row gap-3 items-center"
|
||||
>
|
||||
<button
|
||||
class="btn btn-xl btn-secondary"
|
||||
@click="setAndGo(category)"
|
||||
>
|
||||
{{ category }}
|
||||
</button>
|
||||
<div class="flex flex-col text-sm">
|
||||
<div>{{ $t(`category.description.${category}`) }}</div>
|
||||
<div>{{ $t(`category.age.${category}`) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="text-sm text-center bg-base-200 p-1">
|
||||
<!--
|
||||
You need to leave such an unavoidable mention as one below of the
|
||||
original software, its creator and license - this is required under AGPL.
|
||||
START MENTION
|
||||
-->
|
||||
<NuxtLink
|
||||
class="link"
|
||||
to="https://git.mandarynki.eu/netman/nuxt-prawo-jazdy"
|
||||
>
|
||||
nuxt-prawo-jazdy
|
||||
</NuxtLink>
|
||||
by
|
||||
<NuxtLink class="link" to="https://netman.ovh">netman</NuxtLink>
|
||||
(<NuxtLink
|
||||
class="link"
|
||||
to="https://git.mandarynki.eu/netman/nuxt-prawo-jazdy/src/branch/main/LICENSE"
|
||||
>AGPL-3.0-only</NuxtLink
|
||||
>)
|
||||
<!-- END MENTION -->
|
||||
</div>
|
||||
</div>
|
||||
<LoadingScreen v-else />
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue