feat: Integrate i18n support and enhance UI text localization
- Added internationalization (i18n) support across various components, enabling dynamic language switching and improved user experience. - Updated multiple components to utilize translation functions for labels, buttons, and messages, ensuring consistent language display. - Enhanced the user interface by refining text elements in the ChannelsTable, LogsTable, and various settings pages, improving clarity and accessibility. - Adjusted CSS styles for better responsiveness and layout consistency across different screen sizes.
This commit is contained in:
@@ -2,6 +2,7 @@ import React, { useContext, useEffect, useState } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { UserContext } from '../context/User';
|
||||
import { useSetTheme, useTheme } from '../context/Theme';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { API, getLogo, getSystemName, isMobile, showSuccess } from '../helpers';
|
||||
import '../index.css';
|
||||
@@ -16,7 +17,8 @@ import {
|
||||
IconKey, IconMenu,
|
||||
IconNoteMoneyStroked,
|
||||
IconPriceTag,
|
||||
IconUser
|
||||
IconUser,
|
||||
IconLanguage
|
||||
} from '@douyinfe/semi-icons';
|
||||
import { Avatar, Button, Dropdown, Layout, Nav, Switch } from '@douyinfe/semi-ui';
|
||||
import { stringToColor } from '../helpers/render';
|
||||
@@ -42,41 +44,45 @@ if (localStorage.getItem('chat_link')) {
|
||||
}
|
||||
|
||||
const HeaderBar = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const [userState, userDispatch] = useContext(UserContext);
|
||||
const [styleState, styleDispatch] = useContext(StyleContext);
|
||||
let navigate = useNavigate();
|
||||
const [currentLang, setCurrentLang] = useState(i18n.language);
|
||||
|
||||
const systemName = getSystemName();
|
||||
const logo = getLogo();
|
||||
const currentDate = new Date();
|
||||
// enable fireworks on new year(1.1 and 2.9-2.24)
|
||||
const isNewYear =
|
||||
(currentDate.getMonth() === 0 && currentDate.getDate() === 1) ||
|
||||
(currentDate.getMonth() === 1 &&
|
||||
currentDate.getDate() >= 9 &&
|
||||
currentDate.getDate() <= 24);
|
||||
(currentDate.getMonth() === 0 && currentDate.getDate() === 1);
|
||||
|
||||
let buttons = [
|
||||
{
|
||||
text: '首页',
|
||||
text: t('首页'),
|
||||
itemKey: 'home',
|
||||
to: '/',
|
||||
},
|
||||
{
|
||||
text: '控制台',
|
||||
text: t('控制台'),
|
||||
itemKey: 'detail',
|
||||
to: '/',
|
||||
},
|
||||
{
|
||||
text: '定价',
|
||||
text: t('定价'),
|
||||
itemKey: 'pricing',
|
||||
to: '/pricing',
|
||||
},
|
||||
{
|
||||
text: t('关于'),
|
||||
itemKey: 'about',
|
||||
to: '/about',
|
||||
},
|
||||
];
|
||||
|
||||
async function logout() {
|
||||
await API.get('/api/user/logout');
|
||||
showSuccess('注销成功!');
|
||||
showSuccess(t('注销成功!'));
|
||||
userDispatch({ type: 'logout' });
|
||||
localStorage.removeItem('user');
|
||||
navigate('/login');
|
||||
@@ -106,11 +112,28 @@ const HeaderBar = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handleLanguageChanged = (lng) => {
|
||||
setCurrentLang(lng);
|
||||
};
|
||||
|
||||
i18n.on('languageChanged', handleLanguageChanged);
|
||||
|
||||
return () => {
|
||||
i18n.off('languageChanged', handleLanguageChanged);
|
||||
};
|
||||
}, [i18n]);
|
||||
|
||||
const handleLanguageChange = (lang) => {
|
||||
i18n.changeLanguage(lang);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Layout>
|
||||
<div style={{ width: '100%' }}>
|
||||
<Nav
|
||||
className={'topnav'}
|
||||
mode={'horizontal'}
|
||||
renderWrapper={({ itemElement, isSubNav, isInSubNav, props }) => {
|
||||
const routerMap = {
|
||||
@@ -125,10 +148,10 @@ const HeaderBar = () => {
|
||||
<div onClick={(e) => {
|
||||
if (props.itemKey === 'home') {
|
||||
styleDispatch({ type: 'SET_INNER_PADDING', payload: false });
|
||||
styleDispatch({ type: 'SET_SIDER', payload: false });
|
||||
// styleDispatch({ type: 'SET_SIDER', payload: false });
|
||||
} else {
|
||||
styleDispatch({ type: 'SET_INNER_PADDING', payload: true });
|
||||
styleDispatch({ type: 'SET_SIDER', payload: true });
|
||||
// styleDispatch({ type: 'SET_SIDER', payload: true });
|
||||
}
|
||||
}}>
|
||||
<Link
|
||||
@@ -149,10 +172,10 @@ const HeaderBar = () => {
|
||||
<>
|
||||
{
|
||||
!styleState.showSider ?
|
||||
<Button icon={<IconMenu />} theme="light" aria-label="展开侧边栏" onClick={
|
||||
<Button icon={<IconMenu />} theme="light" aria-label={t('展开侧边栏')} onClick={
|
||||
() => styleDispatch({ type: 'SET_SIDER', payload: true })
|
||||
} />:
|
||||
<Button icon={<IconIndentLeft />} theme="light" aria-label="关闭侧边栏" onClick={
|
||||
<Button icon={<IconIndentLeft />} theme="light" aria-label={t('闭侧边栏')} onClick={
|
||||
() => styleDispatch({ type: 'SET_SIDER', payload: false })
|
||||
} />
|
||||
}
|
||||
@@ -182,7 +205,7 @@ const HeaderBar = () => {
|
||||
<Nav.Item itemKey={'new-year'} text={'🏮'} />
|
||||
</Dropdown>
|
||||
)}
|
||||
<Nav.Item itemKey={'about'} icon={<IconHelpCircle />} />
|
||||
{/* <Nav.Item itemKey={'about'} icon={<IconHelpCircle />} /> */}
|
||||
<>
|
||||
<Switch
|
||||
checkedText='🌞'
|
||||
@@ -194,13 +217,37 @@ const HeaderBar = () => {
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
<Dropdown
|
||||
position='bottomRight'
|
||||
render={
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Item
|
||||
onClick={() => handleLanguageChange('zh')}
|
||||
type={currentLang === 'zh' ? 'primary' : 'tertiary'}
|
||||
>
|
||||
中文
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
onClick={() => handleLanguageChange('en')}
|
||||
type={currentLang === 'en' ? 'primary' : 'tertiary'}
|
||||
>
|
||||
English
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Menu>
|
||||
}
|
||||
>
|
||||
<Nav.Item
|
||||
itemKey={'language'}
|
||||
icon={<IconLanguage />}
|
||||
/>
|
||||
</Dropdown>
|
||||
{userState.user ? (
|
||||
<>
|
||||
<Dropdown
|
||||
position='bottomRight'
|
||||
render={
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Item onClick={logout}>退出</Dropdown.Item>
|
||||
<Dropdown.Item onClick={logout}>{t('退出')}</Dropdown.Item>
|
||||
</Dropdown.Menu>
|
||||
}
|
||||
>
|
||||
@@ -218,14 +265,18 @@ const HeaderBar = () => {
|
||||
<>
|
||||
<Nav.Item
|
||||
itemKey={'login'}
|
||||
text={'登录'}
|
||||
// icon={<IconKey />}
|
||||
/>
|
||||
<Nav.Item
|
||||
itemKey={'register'}
|
||||
text={'注册'}
|
||||
text={!styleState.isMobile?t('登录'):null}
|
||||
icon={<IconUser />}
|
||||
/>
|
||||
{
|
||||
!styleState.isMobile && (
|
||||
<Nav.Item
|
||||
itemKey={'register'}
|
||||
text={t('注册')}
|
||||
icon={<IconKey />}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user