i18n: questions in all langs
minor: readme tweaks
This commit is contained in:
parent
6f87d74c34
commit
36c8115bb6
4 changed files with 58 additions and 29 deletions
17
README.md
17
README.md
|
|
@ -35,19 +35,18 @@ The newest at the moment of me writing this (December 16th 2025) are the (visual
|
|||
- [x] en
|
||||
- [ ] de
|
||||
- [ ] ua
|
||||
- [ ] db: examstore add language field, api handle languages
|
||||
- [ ] db: (revise) script for processing, (revise and) share appropriate files
|
||||
- [x] db: examstore add language field, api handle languages (questions lang)
|
||||
- [ ] clean up js code in exam.vue and result.vue (currently a little bit of a mess)
|
||||
|
||||
## Some information about the project
|
||||
|
||||
My intention is, to share access to test exams free of charge, you don't have to pay me - although you can, I greatly appreciate if you donate!
|
||||
|
||||
In the future I will host this project publicly `aaS`, and will probably put non-invasive, privacy friendly ads if it gains enough traction
|
||||
I'm planning to host this project publicly and to put non-invasive ads if it gains enough traction
|
||||
|
||||
All data used by this software is public information by definition provided in the Polish Constitution - (article 61.)[https://www.sejm.gov.pl/prawo/konst/polski/kon1.htm], and can be acquired by either checking above links on the gov website, or by writing to the Ministry ((if something happened to be missing))[placeholder_for_post_about_missing_points_column]
|
||||
All data used by this software is public information by definition provided in the Polish Constitution - [article 61.](https://www.sejm.gov.pl/prawo/konst/polski/kon1.htm), and can be acquired by either checking above links on the gov website, or by writing to the Ministry [(if something happened to be missing)](placeholder_for_post_about_missing_points_column) ==> (blog post to write in the future)
|
||||
|
||||
This project is a website mimicking an official driver's license theoritical exam (for different license categories) with a seperate media server, connected using drizzle ORM to a SQLite database
|
||||
This project is a website mimicking an official driver's license theoritical exam (for all license categories provided by the Ministry: A, A1, A2, AM, B, B1, C, C1, D, D1, T, PT) with a seperate media http server (not included here), connected using drizzle ORM to a SQLite database
|
||||
|
||||
## Setup
|
||||
|
||||
|
|
@ -57,7 +56,11 @@ This project utilizes `pnpm`, thus it is recommended
|
|||
pnpm install
|
||||
```
|
||||
|
||||
## Development Server
|
||||
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`:
|
||||
|
||||
|
|
@ -65,7 +68,7 @@ Start the development server on `http://localhost:3000`:
|
|||
pnpm run dev
|
||||
```
|
||||
|
||||
## Production
|
||||
### Production
|
||||
|
||||
Build the application for production:
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ const {
|
|||
} = await useLazyFetch<BasicQuestion[]>(`/api/basic`, {
|
||||
query: {
|
||||
category: examStore.category,
|
||||
lang: examStore.lang,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -126,6 +127,7 @@ const {
|
|||
} = await useLazyFetch<AdvancedQuestion[]>(`/api/advanced`, {
|
||||
query: {
|
||||
category: examStore.category,
|
||||
lang: examStore.lang,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -9,22 +9,34 @@ import categories from '~/categories';
|
|||
export default defineEventHandler(async (event) => {
|
||||
const query = getQuery(event);
|
||||
const category = query.category;
|
||||
const lang = query.lang;
|
||||
|
||||
if (category === '' || typeof category !== 'string') {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage:
|
||||
'category argument has to be string (or not to be defined at all)',
|
||||
});
|
||||
}
|
||||
if (!categories.includes(`${category.toUpperCase()}`)) {
|
||||
if (
|
||||
typeof category !== 'string' ||
|
||||
!categories.includes(`${category.toUpperCase()}`)
|
||||
) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: `category argument has to be equal to either: ${categories}`,
|
||||
});
|
||||
}
|
||||
|
||||
async function getFromDb(points: number, limit: number, category: string) {
|
||||
if (
|
||||
typeof lang !== 'string' ||
|
||||
!['PL', 'EN', 'DE', 'UA'].includes(`${lang.toUpperCase()}`)
|
||||
) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: `lang argument has to be equal to either: pl, en, de, ua`,
|
||||
});
|
||||
}
|
||||
|
||||
async function getFromDb(
|
||||
points: number,
|
||||
limit: number,
|
||||
category: string,
|
||||
lang: string,
|
||||
) {
|
||||
return await db
|
||||
.select({
|
||||
id: tasks_advanced.id,
|
||||
|
|
@ -45,7 +57,7 @@ export default defineEventHandler(async (event) => {
|
|||
.where(
|
||||
and(
|
||||
eq(categories_db.name, category.toUpperCase()),
|
||||
eq(questions_advanced.lang, 'PL'),
|
||||
eq(questions_advanced.lang, lang.toUpperCase()),
|
||||
eq(tasks_advanced.weight, points),
|
||||
),
|
||||
)
|
||||
|
|
@ -57,7 +69,7 @@ export default defineEventHandler(async (event) => {
|
|||
const randomizedQuestions: AdvancedQuestion[] = [];
|
||||
|
||||
for (const [key, value] of Object.entries({ 1: 2, 2: 4, 3: 6 })) {
|
||||
randomizedQuestions.push(...(await getFromDb(+key, value, category)));
|
||||
randomizedQuestions.push(...(await getFromDb(+key, value, category, lang)));
|
||||
}
|
||||
return arrayShuffle(randomizedQuestions);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,22 +9,34 @@ import categories from '~/categories';
|
|||
export default defineEventHandler(async (event) => {
|
||||
const query = getQuery(event);
|
||||
const category = query.category;
|
||||
const lang = query.lang;
|
||||
|
||||
if (category === '' || typeof category !== 'string') {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage:
|
||||
'category argument has to be string (or not to be defined at all)',
|
||||
});
|
||||
}
|
||||
if (!categories.includes(`${category.toUpperCase()}`)) {
|
||||
if (
|
||||
typeof category !== 'string' ||
|
||||
!categories.includes(`${category.toUpperCase()}`)
|
||||
) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: `category argument has to be equal to either: ${categories}`,
|
||||
});
|
||||
}
|
||||
|
||||
async function getFromDb(points: number, limit: number, category: string) {
|
||||
if (
|
||||
typeof lang !== 'string' ||
|
||||
!['PL', 'EN', 'DE', 'UA'].includes(`${lang.toUpperCase()}`)
|
||||
) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: `lang argument has to be equal to either: pl, en, de, ua`,
|
||||
});
|
||||
}
|
||||
|
||||
async function getFromDb(
|
||||
points: number,
|
||||
limit: number,
|
||||
category: string,
|
||||
lang: string,
|
||||
) {
|
||||
return await db
|
||||
.select({
|
||||
id: tasks.id,
|
||||
|
|
@ -39,7 +51,7 @@ export default defineEventHandler(async (event) => {
|
|||
.where(
|
||||
and(
|
||||
eq(categories_db.name, category.toUpperCase()),
|
||||
eq(questions.lang, 'PL'),
|
||||
eq(questions.lang, lang.toUpperCase()),
|
||||
eq(tasks.weight, points),
|
||||
),
|
||||
)
|
||||
|
|
@ -51,7 +63,7 @@ export default defineEventHandler(async (event) => {
|
|||
const randomizedQuestions: BasicQuestion[] = [];
|
||||
|
||||
for (const [key, value] of Object.entries({ 1: 4, 2: 6, 3: 10 })) {
|
||||
randomizedQuestions.push(...(await getFromDb(+key, value, category)));
|
||||
randomizedQuestions.push(...(await getFromDb(+key, value, category, lang)));
|
||||
}
|
||||
return arrayShuffle(randomizedQuestions);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue