This commit is contained in:
Ildar Kamalov
2025-07-23 14:29:56 +03:00
parent e1d19f2b4d
commit 38cab630b8
6 changed files with 49 additions and 32 deletions

View File

@@ -1,13 +1,7 @@
import autoprefixer from 'autoprefixer';
import postcssImport from 'postcss-import';
import postcssCustomMedia from 'postcss-custom-media';
import postcssNested from 'postcss-nested';
export default {
plugins: [
postcssImport(),
postcssCustomMedia(),
postcssNested(),
autoprefixer({ overrideBrowserslist: ['last 2 versions'] }),
],
plugins: [postcssImport(), postcssNested(), autoprefixer({ overrideBrowserslist: ['last 2 versions'] })],
};

View File

@@ -634,6 +634,13 @@ class Api {
return this.makeRequest(path, method, config);
}
// Logout
LOGOUT_PATH = 'logout';
getLogoutUrl() {
return `${this.baseUrl}/${this.LOGOUT_PATH}`;
}
// Profile
GET_PROFILE = { path: 'profile', method: 'GET' };

View File

@@ -1,19 +1,20 @@
import React from 'react';
import { I18nInterface, translate } from '@adguard/translate';
import { BASE_LOCALE } from 'panel/helpers/twosky';
import en from '../../__locales/en.json';
import de from '../../__locales/de.json';
import es from '../../__locales/es.json';
import fr from '../../__locales/fr.json';
import it from '../../__locales/it.json';
import ja from '../../__locales/ja.json';
import ko from '../../__locales/ko.json';
import ptBr from '../../__locales/pt-br.json';
import ptPt from '../../__locales/pt-pt.json';
import ru from '../../__locales/ru.json';
import zhCn from '../../__locales/zh-cn.json';
import zhTw from '../../__locales/zh-tw.json';
import en from 'panel/__locales/en.json';
import de from 'panel/__locales/de.json';
import es from 'panel/__locales/es.json';
import fr from 'panel/__locales/fr.json';
import it from 'panel/__locales/it.json';
import ja from 'panel/__locales/ja.json';
import ko from 'panel/__locales/ko.json';
import ptBr from 'panel/__locales/pt-br.json';
import ptPt from 'panel/__locales/pt-pt.json';
import ru from 'panel/__locales/ru.json';
import zhCn from 'panel/__locales/zh-cn.json';
import zhTw from 'panel/__locales/zh-tw.json';
export type LocalesType = ReturnType<I18nInterface['getUILanguage']>;
@@ -40,10 +41,10 @@ export const i18n = (lang: LocalesType) => ({
getMessage: (key: string) => messages[lang]?.[key] || '',
getUILanguage: () => (lang.includes('zh') ? 'zh' : lang),
getBaseMessage: (key: string) => messages.en![key] || key,
getBaseUILanguage: () => 'en' as LocalesType,
getBaseUILanguage: () => BASE_LOCALE as LocalesType,
});
let currentLanguage: LocalesType = 'en';
let currentLanguage: LocalesType = BASE_LOCALE as LocalesType;
let translator = translate.createReactTranslator<any>(i18n(currentLanguage), React, {
tags: [
@@ -69,7 +70,7 @@ const intl = {
return messages.en?.[key] || key;
},
getBaseUILanguage: () => 'en' as LocalesType,
getBaseUILanguage: () => BASE_LOCALE as LocalesType,
changeLanguage: (newLang: LocalesType) => {
currentLanguage = newLang;

View File

@@ -9,7 +9,7 @@ import { Icon } from 'panel/common/ui/Icon';
import { REPOSITORY, PRIVACY_POLICY_LINK, THEMES } from '../../../helpers/constants';
import { LANGUAGES } from '../../../helpers/twosky';
import { setHtmlLangAttr, setUITheme } from '../../../helpers/helpers';
import { changeTheme } from '../../../actions';
import { changeTheme, changeLanguage as changeLanguageAction } from '../../../actions';
import { RootState } from '../../../initialState';
import s from './styles.module.pcss';
@@ -41,6 +41,8 @@ export const Footer = () => {
const currentTheme = useSelector((state: RootState) => (state.dashboard ? state.dashboard.theme : THEMES.auto));
const profileName = useSelector((state: RootState) => (state.dashboard ? state.dashboard.name : ''));
const currentLanguage =
useSelector((state: RootState) => (state.dashboard ? state.dashboard.language : '')) || intl.getUILanguage();
const isLoggedIn = profileName !== '';
const [currentThemeLocal, setCurrentThemeLocal] = useState(THEMES.auto);
const [themeDropdownOpen, setThemeDropdownOpen] = useState(false);
@@ -70,10 +72,16 @@ export const Footer = () => {
return 'theme_light';
};
const changeLanguage = (newLang: LocalesType) => {
const changeLanguage = async (newLang: LocalesType) => {
intl.changeLanguage(newLang);
setHtmlLangAttr(newLang);
window.location.reload();
try {
await dispatch(changeLanguageAction(newLang));
window.location.reload();
} catch (error) {
console.error('Failed to save language preference:', error);
}
};
const onThemeChange = (value: string) => {
@@ -146,7 +154,7 @@ export const Footer = () => {
type="button"
key={lang}
className={cn(theme.dropdown.item, {
[theme.dropdown.item_active]: intl.getUILanguage() === lang,
[theme.dropdown.item_active]: currentLanguage === lang,
})}
onClick={() => changeLanguage(lang as LocalesType)}>
{LANGUAGES[lang]}
@@ -159,7 +167,7 @@ export const Footer = () => {
position="bottomRight">
<div className={s.dropdownTrigger}>
<Icon icon="lang" className={s.icon} />
<span>{LANGUAGES[intl.getUILanguage()]}</span>
<span>{LANGUAGES[currentLanguage] || LANGUAGES[intl.getUILanguage()]}</span>
</div>
</Dropdown>
</div>

View File

@@ -6,6 +6,7 @@ import { Link } from 'panel/common/ui/Link';
import { Paths, RoutePath } from 'panel/components/Routes/Paths';
import theme from 'panel/lib/theme';
import intl from 'panel/common/intl';
import { apiClient } from 'panel/api/Api';
import { AccordionSection } from './AccordionSection';
import s from './styles.module.pcss';
@@ -123,7 +124,7 @@ export const Menu = ({ headerMenu }: Props) => {
</nav>
<div className={s.referenceWrapper}>
<div className={cn(s.menuLinkWrapper)}>
<a target="_blank" rel="noopener noreferrer" className={s.menuLink} href="">
<a href={apiClient.getLogoutUrl()} target="_blank" rel="noopener noreferrer" className={s.menuLink}>
<Icon className={s.linkIcon} icon="logout" />
<span className={theme.common.textOverflow}>{intl.getMessage('logout')}</span>
</a>

View File

@@ -1,4 +1,3 @@
@import './common/styles/custom-media.pcss';
@import './common/styles/vars.css';
@import './common/styles/colors/light.css';
@import './common/styles/colors/dark.css';
@@ -6,10 +5,12 @@
:root {
--font-family-monospace: Monaco, Menlo, 'Ubuntu Mono', Consolas, source-code-pro, monospace;
--font-family-system: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif
--font-family-system: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
}
*, *::after, *::before {
*,
*::after,
*::before {
box-sizing: border-box;
}
@@ -36,6 +37,11 @@ select {
font-family: var(--font-family-system);
}
h1, h2, h3, h4, h5, h6 {
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
}