Skip to content

Commit dd0acd9

Browse files
h3cksShchepotin
authored andcommitted
feat(i18n): add Ukrainian language support and switcher (closes #351)
1 parent bad13ec commit dd0acd9

20 files changed

Lines changed: 646 additions & 2 deletions
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"use client";
2+
3+
import { usePathname, useRouter } from "next/navigation";
4+
import MenuItem from "@mui/material/MenuItem";
5+
import Select, { SelectChangeEvent } from "@mui/material/Select";
6+
7+
const languages = [
8+
{ code: "en", label: "English" },
9+
{ code: "uk", label: "Українська" },
10+
];
11+
12+
export default function LanguageSwitcher() {
13+
const pathname = usePathname();
14+
const router = useRouter();
15+
16+
const currentLang = pathname.split("/")[1] || "en";
17+
18+
const handleChange = (event: SelectChangeEvent) => {
19+
const newLang = event.target.value;
20+
21+
// Якщо шлях взагалі порожній app-bar.tsx(наприклад, просто /), то додаємо мову
22+
if (!pathname) {
23+
router.push(`/${newLang}`);
24+
return;
25+
}
26+
27+
const pathSegments = pathname.split("/");
28+
pathSegments[1] = newLang;
29+
const newPath = pathSegments.join("/");
30+
31+
router.push(newPath);
32+
};
33+
34+
return (
35+
<Select
36+
value={currentLang}
37+
onChange={handleChange}
38+
size="small"
39+
variant="outlined"
40+
sx={{
41+
minWidth: 120,
42+
color: "inherit",
43+
".MuiOutlinedInput-notchedOutline": {
44+
borderColor: "rgba(255, 255, 255, 0.5)",
45+
},
46+
"&:hover .MuiOutlinedInput-notchedOutline": {
47+
borderColor: "white",
48+
},
49+
".MuiSvgIcon-root ": {
50+
fill: "currentColor",
51+
},
52+
}}
53+
>
54+
{languages.map((lang) => (
55+
<MenuItem key={lang.code} value={lang.code}>
56+
{lang.label}
57+
</MenuItem>
58+
))}
59+
</Select>
60+
);
61+
}

src/components/app-bar.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import Link from "@/components/link";
2020
import { RoleEnum } from "@/services/api/types/role";
2121
import Divider from "@mui/material/Divider";
2222
import ThemeSwitchButton from "@/components/switch-theme-button";
23+
import LanguageSwitcher from "@/components/LanguageSwitcher";
2324
import { IS_SIGN_UP_ENABLED } from "@/services/auth/config";
2425

2526
function ResponsiveAppBar() {
@@ -193,10 +194,13 @@ function ResponsiveAppBar() {
193194
<Box
194195
sx={{
195196
display: "flex",
196-
mr: 1,
197+
alignItems: "center",
198+
gap: 2,
199+
mr: 2,
197200
}}
198201
>
199202
<ThemeSwitchButton />
203+
<LanguageSwitcher />
200204
</Box>
201205

202206
{!isLoaded ? (

src/services/i18n/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export const fallbackLanguage = "en" as const;
2-
export const languages = [fallbackLanguage] as const;
2+
export const languages = [fallbackLanguage, "uk"] as const;
33
export const defaultNamespace = "common";
44
export const cookieName = "i18next";
55

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"title": "Панель адміністратора",
3+
"description": "Ласкаво просимо до панелі адміністратора."
4+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"role": {
3+
"1": "Адміністратор",
4+
"2": "Користувач"
5+
}
6+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"title": "Створити користувача",
3+
"actions": {
4+
"submit": "Зберегти",
5+
"cancel": "Скасувати"
6+
},
7+
"inputs": {
8+
"email": {
9+
"label": "Email",
10+
"validation": {
11+
"invalid": "Недійсний email",
12+
"required": "Email є обов'язковим",
13+
"server": {
14+
"emailAlreadyExists": "Такий email вже існує"
15+
}
16+
}
17+
},
18+
"firstName": {
19+
"label": "Ім'я",
20+
"validation": {
21+
"required": "Ім'я є обов'язковим"
22+
}
23+
},
24+
"lastName": {
25+
"label": "Прізвище",
26+
"validation": {
27+
"required": "Прізвище є обов'язковим"
28+
}
29+
},
30+
"role": {
31+
"label": "Роль",
32+
"validation": {
33+
"required": "Роль є обов'язковою"
34+
},
35+
"options": {
36+
"1": "Адміністратор",
37+
"2": "Користувач"
38+
}
39+
},
40+
"password": {
41+
"label": "Пароль",
42+
"validation": {
43+
"required": "Пароль є обов'язковим",
44+
"min": "Пароль має містити щонайменше 6 символів"
45+
}
46+
},
47+
"passwordConfirmation": {
48+
"label": "Підтвердження пароля",
49+
"validation": {
50+
"required": "Підтвердження пароля є обов'язковим",
51+
"match": "Підтвердження пароля має збігатися з паролем"
52+
}
53+
},
54+
"<system>": "Do not remove this property"
55+
},
56+
"alerts": {
57+
"user": {
58+
"success": "Профіль користувача успішно створено"
59+
}
60+
}
61+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"title1": "Редагувати користувача",
3+
"title2": "Змінити пароль",
4+
"actions": {
5+
"submit": "Зберегти",
6+
"cancel": "Скасувати"
7+
},
8+
"inputs": {
9+
"email": {
10+
"label": "Email",
11+
"validation": {
12+
"invalid": "Недійсний email",
13+
"required": "Email є обов'язковим",
14+
"server": {
15+
"emailAlreadyExists": "Такий email вже існує"
16+
}
17+
}
18+
},
19+
"firstName": {
20+
"label": "Ім'я",
21+
"validation": {
22+
"required": "Ім'я є обов'язковим"
23+
}
24+
},
25+
"lastName": {
26+
"label": "Прізвище",
27+
"validation": {
28+
"required": "Прізвище є обов'язковим"
29+
}
30+
},
31+
"role": {
32+
"label": "Роль",
33+
"validation": {
34+
"required": "Роль є обов'язковою"
35+
},
36+
"options": {
37+
"1": "Адміністратор",
38+
"2": "Користувач"
39+
}
40+
},
41+
"password": {
42+
"label": "Пароль",
43+
"validation": {
44+
"required": "Пароль є обов'язковим",
45+
"min": "Пароль має містити щонайменше 6 символів"
46+
}
47+
},
48+
"passwordConfirmation": {
49+
"label": "Підтвердження пароля",
50+
"validation": {
51+
"required": "Підтвердження пароля є обов'язковим",
52+
"match": "Підтвердження пароля має збігатися з паролем"
53+
}
54+
},
55+
"<system>": "Do not remove this property"
56+
},
57+
"alerts": {
58+
"password": {
59+
"success": "Пароль успішно оновлено"
60+
},
61+
"user": {
62+
"success": "Профіль користувача успішно оновлено"
63+
}
64+
}
65+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"title": "Користувачі",
3+
"table": {
4+
"column1": "ID",
5+
"column2": "Ім'я",
6+
"column3": "Email",
7+
"column4": "Роль"
8+
},
9+
"actions": {
10+
"add": "Додати користувача",
11+
"edit": "Редагувати",
12+
"delete": "Видалити",
13+
"create": "Створити користувача"
14+
},
15+
"confirm": {
16+
"delete": {
17+
"title": "Видалити користувача",
18+
"message": "Ви впевнені, що хочете видалити цього користувача?"
19+
}
20+
},
21+
"filter": {
22+
"actions": {
23+
"filter": "Фільтр",
24+
"apply": "Застосувати"
25+
},
26+
"inputs": {
27+
"role": {
28+
"label": "Роль",
29+
"options": {
30+
"1": "Адміністратор",
31+
"2": "Користувач"
32+
}
33+
}
34+
}
35+
}
36+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"app-name": "ДОДАТОК",
3+
"loading": "Завантаження...",
4+
"navigation": {
5+
"home": "Головна",
6+
"signIn": "Увійти",
7+
"signUp": "Зареєструватися",
8+
"profile": "Профіль",
9+
"users": "Користувачі",
10+
"logout": "Вийти"
11+
},
12+
"formInputs": {
13+
"avatarInput": {
14+
"dropzoneText": "Перетягніть зображення сюди...",
15+
"dragAndDrop": "Або перетягніть якесь зображення сюди",
16+
"selectFile": "Виберіть зображення"
17+
},
18+
"multipleImageInput": {
19+
"dropzoneText": "Перетягніть зображення сюди...",
20+
"dragAndDrop": "Або перетягніть якісь зображення сюди",
21+
"selectFile": "Виберіть зображення"
22+
},
23+
"singleImageInput": {
24+
"dropzoneText": "Перетягніть зображення сюди...",
25+
"dragAndDrop": "Або перетягніть якесь зображення сюди",
26+
"selectFile": "Виберіть зображення"
27+
}
28+
},
29+
"leavePage": {
30+
"title": "Залишити цю сторінку?",
31+
"message": "Зміни, які ви зробили, можуть бути не збережені",
32+
"stay": "Залишитися на сторінці",
33+
"leave": "Залишити сторінку"
34+
},
35+
"auth": {
36+
"facebook": {
37+
"action": "Увійти через Facebook"
38+
}
39+
}
40+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"title": "Підтвердження",
3+
"message": "Ви впевнені, що хочете виконати цю дію?",
4+
"actions": {
5+
"yes": "Так",
6+
"no": "Ні"
7+
}
8+
}

0 commit comments

Comments
 (0)