From 53729813ff19125c4f1811ab9f7c7e1b99c2d9ef Mon Sep 17 00:00:00 2001 From: Vladislav Date: Thu, 24 Apr 2025 16:59:18 +0500 Subject: [PATCH] feat: add en language --- client/public/index.html | 2 +- client/src/components/ContentDrawer.tsx | 5 +- client/src/components/UserCreate.tsx | 42 +++++++------ client/src/components/UserEdit.tsx | 38 ++++++------ client/src/config/AppWrapper.tsx | 24 ++++++++ client/src/config/i18n.ts | 74 +++++++++++++++++++++++ client/src/pages/ConfigurationPage.tsx | 4 +- client/src/pages/EventsListPage.tsx | 4 +- client/src/pages/ProcessDiagramPage.tsx | 4 +- client/src/pages/RunningProcessesPage.tsx | 4 +- 10 files changed, 158 insertions(+), 43 deletions(-) create mode 100644 client/src/config/AppWrapper.tsx create mode 100644 client/src/config/i18n.ts diff --git a/client/public/index.html b/client/public/index.html index aa069f2..0fc0d9c 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + VORKOUT diff --git a/client/src/components/ContentDrawer.tsx b/client/src/components/ContentDrawer.tsx index 531ae40..f02b6f4 100644 --- a/client/src/components/ContentDrawer.tsx +++ b/client/src/components/ContentDrawer.tsx @@ -1,6 +1,7 @@ import { Drawer } from 'antd'; import { useEffect, useState } from 'react'; import { Avatar, Typography } from 'antd'; +import { useTranslation } from 'react-i18next'; interface ContentDrawerProps { open: boolean; @@ -15,6 +16,7 @@ export default function ContentDrawer({ children, type, }: ContentDrawerProps) { + const { t } = useTranslation(); const [width, setWidth] = useState('30%'); const calculateWidths = () => { @@ -123,7 +125,7 @@ export default function ContentDrawer({ fontSize: '20px', }} > - Новая учетная запись + {t('newAccount')}
=> }); export default function UserCreate() { + const { t } = useTranslation(); const [previewOpen, setPreviewOpen] = useState(false); const [previewImage, setPreviewImage] = useState(''); @@ -64,7 +66,9 @@ export default function UserCreate() { />
- Выбрать фото + + {t('selectPhoto')} + ); @@ -135,54 +139,54 @@ export default function UserCreate() { style={{ flex: 1, display: 'flex', flexDirection: 'column' }} > - @@ -190,11 +194,11 @@ export default function UserCreate() { - @@ -216,7 +220,7 @@ export default function UserCreate() { alt="save" style={{ height: '18px', width: '18px' }} />{' '} - Добавить аккаунт + {t('addAccount')} diff --git a/client/src/components/UserEdit.tsx b/client/src/components/UserEdit.tsx index c194bff..bd5e8f0 100644 --- a/client/src/components/UserEdit.tsx +++ b/client/src/components/UserEdit.tsx @@ -1,8 +1,10 @@ import { Button, Form, Input, Select } from 'antd'; +import { useTranslation } from 'react-i18next'; const { Option } = Select; export default function UserEdit() { + const { t } = useTranslation(); return (
- @@ -76,11 +78,11 @@ export default function UserEdit() { - @@ -102,7 +104,7 @@ export default function UserEdit() { alt="save" style={{ height: '18px', width: '18px' }} />{' '} - Сохранить изменения + {t('save')}
diff --git a/client/src/config/AppWrapper.tsx b/client/src/config/AppWrapper.tsx new file mode 100644 index 0000000..6bea4bc --- /dev/null +++ b/client/src/config/AppWrapper.tsx @@ -0,0 +1,24 @@ +import './i18n'; +import { ConfigProvider } from 'antd'; +import { useTranslation } from 'react-i18next'; + +import { theme } from './customTheme'; + +import en from 'antd/locale/en_US'; +import ru from 'antd/locale/ru_RU'; + +const antdLocales = { + en: en, + ru: ru, +}; + +export default function AppWrapper({ children }: any) { + const { i18n } = useTranslation(); + const currentLang = i18n.language.split('-')[0] as 'en' | 'ru'; + + return ( + + {children} + + ); +} diff --git a/client/src/config/i18n.ts b/client/src/config/i18n.ts new file mode 100644 index 0000000..09bd8b8 --- /dev/null +++ b/client/src/config/i18n.ts @@ -0,0 +1,74 @@ +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import LanguageDetector from 'i18next-browser-languagedetector'; + +i18n + .use(LanguageDetector) + .use(initReactI18next) + .init({ + fallbackLng: 'en', + supportedLngs: ['en', 'ru'], + interpolation: { escapeValue: false }, + resources: { + en: { + translation: { + accounts: 'Accounts', + processDiagrams: 'Process diagrams', + runningProcesses: 'Running processes', + settings: 'Settings', + eventsList: 'Events list', + configuration: 'Configuration', + selectPhoto: 'Select photo', + name: 'Name', + login: 'Login', + password: 'Password', + email: 'Email', + tenant: 'Tenant', + role: 'Role', + status: 'Status', + nameMessage: 'Enter name', + loginMessage: 'Enter login', + passwordMessage: 'Enter password', + emailMessage: 'Enter email', + emailErrorMessage: 'Incorrect email', + tenantMessage: 'Enter tenant', + roleMessage: 'Choose role', + statusMessage: 'Choose status', + addAccount: 'Add account', + save: 'Save changes', + newAccount: 'New account', + }, + }, + ru: { + translation: { + accounts: 'Учетные записи', + processDiagrams: 'Схемы процессов', + runningProcesses: 'Запущенные процессы', + settings: 'Настройки', + eventsList: 'Справочкин событий', + configuration: 'Конфигурация', + selectPhoto: 'Выбрать фото', + name: 'Имя', + login: 'Логин', + password: 'Пароль', + email: 'Имейл', + tenant: 'Привязка', + role: 'Роль', + status: 'Статус', + nameMessage: 'Введите имя', + loginMessage: 'Введите логин', + passwordMessage: 'Введите пароль', + emailMessage: 'Введите имейл', + emailErrorMessage: 'Некорректный имейл', + tenantMessage: 'Введите привязку', + roleMessage: 'Выберите роль', + statusMessage: 'Выберите статус', + addAccount: 'Добавить аккаунт', + save: 'Сохранить изменения', + newAccount: 'Новая учетная запись', + }, + }, + }, + }); + +export default i18n; diff --git a/client/src/pages/ConfigurationPage.tsx b/client/src/pages/ConfigurationPage.tsx index 186a170..b157e42 100644 --- a/client/src/pages/ConfigurationPage.tsx +++ b/client/src/pages/ConfigurationPage.tsx @@ -1,9 +1,11 @@ +import { useTranslation } from 'react-i18next'; import Header from '../components/Header'; export default function ConfigurationPage() { + const { t } = useTranslation(); return ( <> -
+
); } diff --git a/client/src/pages/EventsListPage.tsx b/client/src/pages/EventsListPage.tsx index 453381a..dd7d5d4 100644 --- a/client/src/pages/EventsListPage.tsx +++ b/client/src/pages/EventsListPage.tsx @@ -1,9 +1,11 @@ +import { useTranslation } from 'react-i18next'; import Header from '../components/Header'; export default function EventsListPage() { + const { t } = useTranslation(); return ( <> -
+
); } diff --git a/client/src/pages/ProcessDiagramPage.tsx b/client/src/pages/ProcessDiagramPage.tsx index 5f8d212..5ab0d5c 100644 --- a/client/src/pages/ProcessDiagramPage.tsx +++ b/client/src/pages/ProcessDiagramPage.tsx @@ -1,9 +1,11 @@ +import { useTranslation } from 'react-i18next'; import Header from '../components/Header'; export default function ProcessDiagramPage() { + const { t } = useTranslation(); return ( <> -
+
); } diff --git a/client/src/pages/RunningProcessesPage.tsx b/client/src/pages/RunningProcessesPage.tsx index 9063283..6da1e34 100644 --- a/client/src/pages/RunningProcessesPage.tsx +++ b/client/src/pages/RunningProcessesPage.tsx @@ -1,9 +1,11 @@ +import { useTranslation } from 'react-i18next'; import Header from '../components/Header'; export default function RunningProcessesPage() { + const { t } = useTranslation(); return ( <> -
+
); }