design fixes
This commit is contained in:
@@ -24,6 +24,12 @@
|
|||||||
"bundle": {
|
"bundle": {
|
||||||
"active": true,
|
"active": true,
|
||||||
"targets": "all",
|
"targets": "all",
|
||||||
"icon": ["icons/icon.png"]
|
"icon": [
|
||||||
|
"icons/32x32.png",
|
||||||
|
"icons/128x128.png",
|
||||||
|
"icons/128x128@2x.png",
|
||||||
|
"icons/icon.ico",
|
||||||
|
"icons/icon.icns"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -12,13 +12,15 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<div className="min-h-screen w-full bg-background relative overflow-x-hidden">
|
<div className="fixed inset-0 h-screen w-full overflow-hidden bg-background">
|
||||||
<AnimatedBackground />
|
<AnimatedBackground />
|
||||||
<Header onMenuClick={() => setIsMenuOpen(!isMenuOpen)} />
|
|
||||||
|
<div className="bg-background">
|
||||||
|
<Header onMenuClick={() => setIsMenuOpen(!isMenuOpen)} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<BurgerMenu isOpen={isMenuOpen} onClose={() => setIsMenuOpen(false)} />
|
<BurgerMenu isOpen={isMenuOpen} onClose={() => setIsMenuOpen(false)} />
|
||||||
|
<main className="flex h-[calc(100vh-4rem)] flex-col items-center justify-center px-6 py-6 overflow-hidden">
|
||||||
<main className="flex flex-col items-center justify-center min-h-[calc(100vh-80px)] gap-[10px] p-6">
|
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Home />} />
|
<Route path="/" element={<Home />} />
|
||||||
<Route path="/settings" element={<Settings />} />
|
<Route path="/settings" element={<Settings />} />
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { cn } from "@/lib/utils";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
interface BurgerMenuProps {
|
interface BurgerMenuProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -8,34 +7,37 @@ interface BurgerMenuProps {
|
|||||||
|
|
||||||
export function BurgerMenu({ isOpen, onClose }: BurgerMenuProps) {
|
export function BurgerMenu({ isOpen, onClose }: BurgerMenuProps) {
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Затемнение фона при открытом меню */}
|
{/* затемнение только под хедером */}
|
||||||
<div
|
<div
|
||||||
className="fixed inset-0 z-30 bg-black/20 backdrop-blur-sm"
|
className="fixed inset-x-0 bottom-0 top-25 z-30 bg-black/20 backdrop-blur-sm"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="absolute left-0 top-16 z-40 w-64 h-[calc(100vh-4rem)] bg-card border-r p-6 shadow-xl animate-in slide-in-from-left">
|
{/* меню */}
|
||||||
|
<div className="fixed left-0 top-25 z-60 h-[calc(100vh-4rem)] w-64 bg-card border-r p-6 shadow-xl animate-in slide-in-from-left">
|
||||||
<nav className="flex flex-col gap-6" onClick={onClose}>
|
<nav className="flex flex-col gap-6" onClick={onClose}>
|
||||||
<Link
|
<Link
|
||||||
to="/"
|
to="/"
|
||||||
className="text-lg font-medium hover:text-primary transition-colors"
|
className="text-lg font-medium hover:text-primary transition-colors"
|
||||||
>
|
>
|
||||||
Подключение
|
{t("home_label")}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
to="/settings"
|
to="/settings"
|
||||||
className="text-lg font-medium hover:text-primary transition-colors"
|
className="text-lg font-medium hover:text-primary transition-colors"
|
||||||
>
|
>
|
||||||
Настройки
|
{t("settings")}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
to="/about"
|
to="/about"
|
||||||
className="text-lg font-medium hover:text-primary transition-colors"
|
className="text-lg font-medium hover:text-primary transition-colors"
|
||||||
>
|
>
|
||||||
О программе
|
{t("about_title")}
|
||||||
</Link>
|
</Link>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { ThemeToggle } from "./ThemeToggle";
|
|||||||
|
|
||||||
export function Header({ onMenuClick }: { onMenuClick: () => void }) {
|
export function Header({ onMenuClick }: { onMenuClick: () => void }) {
|
||||||
return (
|
return (
|
||||||
<header className="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 shadow-sm">
|
<header className="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 shadow-sm pt-[env(safe-area-inset-top)]">
|
||||||
{/* Используем grid для идеальной центровки */}
|
{/* Используем grid для идеальной центровки */}
|
||||||
<div className="grid h-16 w-full grid-cols-[auto_1fr_auto] items-center px-4">
|
<div className="grid h-16 w-full grid-cols-[auto_1fr_auto] items-center px-4">
|
||||||
{/* Слева: Бургер (занимает место по контенту) */}
|
{/* Слева: Бургер (занимает место по контенту) */}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export function VpnControl() {
|
|||||||
cx="130"
|
cx="130"
|
||||||
cy="130"
|
cy="130"
|
||||||
r="140"
|
r="140"
|
||||||
className="stroke-primary/80 fill-none drop-shadow-[0_0_10px_var(--color-primary)]"
|
className="stroke-primary/80 fill-none drop-shadow-[0_0_3px_var(--color-primary)]"
|
||||||
strokeWidth="4"
|
strokeWidth="4"
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeDasharray="800"
|
strokeDasharray="800"
|
||||||
@@ -67,7 +67,7 @@ export function VpnControl() {
|
|||||||
cx="130"
|
cx="130"
|
||||||
cy="130"
|
cy="130"
|
||||||
r="140"
|
r="140"
|
||||||
className="stroke-primary/80 fill-none drop-shadow-[0_0_10px_var(--color-primary)]"
|
className="stroke-primary/80 fill-none drop-shadow-[0_0_3px_var(--color-primary)]"
|
||||||
strokeWidth="4"
|
strokeWidth="4"
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeDasharray="800"
|
strokeDasharray="800"
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
"version_info": "Version 1.0.0-stable | 2026",
|
"version_info": "Version 1.0.0-stable | 2026",
|
||||||
"footer_text": "Developed with care for network freedom.",
|
"footer_text": "Developed with care for network freedom.",
|
||||||
"select_location_placeholder": "Select a VPN location",
|
"select_location_placeholder": "Select a VPN location",
|
||||||
"settings": "Settings",
|
|
||||||
"section_network": "Network",
|
"section_network": "Network",
|
||||||
"kill_switch": "Kill Switch",
|
"kill_switch": "Kill Switch",
|
||||||
"kill_switch_desc": "Block internet on connection loss",
|
"kill_switch_desc": "Block internet on connection loss",
|
||||||
@@ -24,5 +23,8 @@
|
|||||||
"reduce_motion": "Reduce Motion",
|
"reduce_motion": "Reduce Motion",
|
||||||
"reduce_motion_desc": "For resource efficiency",
|
"reduce_motion_desc": "For resource efficiency",
|
||||||
"theme_toggle": "Appearance Theme",
|
"theme_toggle": "Appearance Theme",
|
||||||
"language_toggle": "Interface Language"
|
"language_toggle": "Interface Language",
|
||||||
|
"home_label": "Home",
|
||||||
|
"settings": "Settings",
|
||||||
|
"about_menu": "About"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
"version_info": "Версия 1.0.0-stable | 2026",
|
"version_info": "Версия 1.0.0-stable | 2026",
|
||||||
"footer_text": "Разработано с заботой о свободе в сети.",
|
"footer_text": "Разработано с заботой о свободе в сети.",
|
||||||
"select_location_placeholder": "Выберите локацию VPN",
|
"select_location_placeholder": "Выберите локацию VPN",
|
||||||
"settings": "Настройки",
|
|
||||||
"section_network": "Сеть",
|
"section_network": "Сеть",
|
||||||
"kill_switch": "Kill Switch",
|
"kill_switch": "Kill Switch",
|
||||||
"kill_switch_desc": "Блокировать интернет при обрыве",
|
"kill_switch_desc": "Блокировать интернет при обрыве",
|
||||||
@@ -24,5 +23,8 @@
|
|||||||
"reduce_motion": "Снизить анимации",
|
"reduce_motion": "Снизить анимации",
|
||||||
"reduce_motion_desc": "Для экономии ресурсов",
|
"reduce_motion_desc": "Для экономии ресурсов",
|
||||||
"theme_toggle": "Тема оформления",
|
"theme_toggle": "Тема оформления",
|
||||||
"language_toggle": "Язык интерфейса"
|
"language_toggle": "Язык интерфейса",
|
||||||
|
"home_label": "Главная",
|
||||||
|
"settings": "Настройки",
|
||||||
|
"about_menu": "О приложении"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import { CountrySelect } from "../features/CountrySelect";
|
|||||||
|
|
||||||
export function Home() {
|
export function Home() {
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="flex flex-col gap-1.75 items-center">
|
||||||
<VpnControl />
|
<VpnControl />
|
||||||
<CountrySelect />
|
<CountrySelect />
|
||||||
<VpnStats received="0" sent="0" />
|
<VpnStats received="0" sent="0" />
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user