170 lines
5.9 KiB
TypeScript
170 lines
5.9 KiB
TypeScript
import { useNavigate, useLocation } from "react-router-dom";
|
||
import { FaCode } from "react-icons/fa";
|
||
import {
|
||
FaHome,
|
||
FaServer,
|
||
FaUser,
|
||
FaUsers,
|
||
FaRocket,
|
||
FaKey,
|
||
FaFileAlt,
|
||
FaSun,
|
||
FaMoon,
|
||
} from "react-icons/fa";
|
||
import { useAuthStore } from "@/modules/auth/store/useAuthStore";
|
||
import { useThemeStore } from "@/modules/theme-bw/stores/theme.store";
|
||
|
||
export const Navigation = () => {
|
||
const navigate = useNavigate();
|
||
const location = useLocation();
|
||
const { user, logout } = useAuthStore();
|
||
const { toggleTheme, theme } = useThemeStore();
|
||
|
||
const isDark = theme === "dark";
|
||
|
||
const navItems = [
|
||
{ path: "/", label: "Главная", icon: FaHome },
|
||
{ path: "/add-agents", label: "Агенты", icon: FaServer },
|
||
{ path: "/templates", label: "Шаблоны", icon: FaCode },
|
||
{ path: "/add-agents", label: "Деплой", icon: FaRocket },
|
||
{ path: "/registration", label: "Регистрация", icon: FaKey },
|
||
{ path: "/logs", label: "Логи", icon: FaFileAlt },
|
||
{ path: "/admin", label: "Админка", icon: FaUsers, adminOnly: true },
|
||
];
|
||
|
||
const isActive = (path: string) => location.pathname === path;
|
||
|
||
return (
|
||
<div
|
||
className="flex-shrink-0 border-b"
|
||
style={{
|
||
backgroundColor: "var(--card-bg)",
|
||
borderColor: "var(--border)",
|
||
}}
|
||
>
|
||
<div className="flex items-center justify-between px-4 py-2.5">
|
||
{/* Навигация с горизонтальным скроллом */}
|
||
<div className="flex items-center flex-1 mx-4 overflow-x-auto scrollbar-hide">
|
||
<div className="flex items-center gap-1 whitespace-nowrap">
|
||
{navItems
|
||
.filter((item) => {
|
||
if (item.adminOnly && !user?.permission_admin) return false;
|
||
return true;
|
||
})
|
||
.map((item) => {
|
||
const Icon = item.icon;
|
||
const active = isActive(item.path);
|
||
return (
|
||
<button
|
||
key={item.path}
|
||
onClick={() => navigate(item.path)}
|
||
className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium transition-all flex-shrink-0"
|
||
style={{
|
||
backgroundColor: active ? "var(--accent)" : "transparent",
|
||
color: active
|
||
? "var(--accent-text)"
|
||
: "var(--text-secondary)",
|
||
}}
|
||
onMouseEnter={(e) => {
|
||
if (!active) {
|
||
e.currentTarget.style.backgroundColor =
|
||
"var(--bg-secondary)";
|
||
e.currentTarget.style.color = "var(--text-primary)";
|
||
}
|
||
}}
|
||
onMouseLeave={(e) => {
|
||
if (!active) {
|
||
e.currentTarget.style.backgroundColor = "transparent";
|
||
e.currentTarget.style.color = "var(--text-secondary)";
|
||
}
|
||
}}
|
||
>
|
||
<Icon size={12} />
|
||
<span>{item.label}</span>
|
||
</button>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Профиль пользователя */}
|
||
<div className="flex items-center gap-2">
|
||
{user && (
|
||
<div className="flex items-center gap-2">
|
||
<div
|
||
className="w-8 h-8 rounded-full flex items-center justify-center"
|
||
style={{ backgroundColor: "var(--bg-secondary)" }}
|
||
>
|
||
<FaUser size={12} style={{ color: "var(--accent)" }} />
|
||
</div>
|
||
<span
|
||
className="text-xs"
|
||
style={{ color: "var(--text-secondary)" }}
|
||
>
|
||
{user.name}
|
||
</span>
|
||
</div>
|
||
)}
|
||
|
||
{/* Переключатель темы */}
|
||
<button
|
||
onClick={toggleTheme}
|
||
className="p-1.5 rounded-lg transition-colors"
|
||
style={{
|
||
backgroundColor: "var(--bg-secondary)",
|
||
color: isDark ? "#fbbf24" : "#3b82f6",
|
||
border: "1px solid var(--border)",
|
||
}}
|
||
title={isDark ? "Светлая тема" : "Тёмная тема"}
|
||
>
|
||
{isDark ? <FaSun size={12} /> : <FaMoon size={12} />}
|
||
</button>
|
||
|
||
{/* Админка */}
|
||
<button
|
||
onClick={() => navigate("/admin")}
|
||
className="p-1.5 rounded-lg transition-colors"
|
||
style={{
|
||
backgroundColor:
|
||
location.pathname === "/admin"
|
||
? "var(--accent)"
|
||
: "var(--bg-secondary)",
|
||
color:
|
||
location.pathname === "/admin"
|
||
? "var(--accent-text)"
|
||
: "var(--text-secondary)",
|
||
border: "1px solid var(--border)",
|
||
}}
|
||
title="Админка"
|
||
>
|
||
<FaUsers size={12} />
|
||
</button>
|
||
|
||
<button
|
||
onClick={() => {
|
||
logout();
|
||
navigate("/auth");
|
||
}}
|
||
className="px-3 py-1.5 rounded-lg text-xs font-medium transition-colors"
|
||
style={{
|
||
backgroundColor: "var(--error-bg)",
|
||
color: "var(--error-text)",
|
||
border: "1px solid var(--error-border)",
|
||
}}
|
||
onMouseEnter={(e) => {
|
||
e.currentTarget.style.backgroundColor = "var(--error-text)";
|
||
e.currentTarget.style.color = "#fff";
|
||
}}
|
||
onMouseLeave={(e) => {
|
||
e.currentTarget.style.backgroundColor = "var(--error-bg)";
|
||
e.currentTarget.style.color = "var(--error-text)";
|
||
}}
|
||
>
|
||
Выйти
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|