krona-front/src/app/shell/BottomNav.tsx

109 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from 'react';
import { NavLink, useLocation, useNavigate } from 'react-router-dom';
import {
LayoutDashboard,
Grid,
CheckSquare,
MessageSquareText,
Menu,
} from 'lucide-react';
import { MobileMenuDrawer } from './MobileMenuDrawer';
export const BottomNav: React.FC = () => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const location = useLocation();
const navigate = useNavigate();
const isCatalogActive = location.pathname === '/' && !location.search.includes('tab=dashboard');
const isDashboardActive = location.pathname === '/' && location.search.includes('tab=dashboard');
return (
<>
<nav
aria-label="Мобильная навигация"
data-testid="bottom-nav"
className="fixed bottom-0 inset-x-0 bg-krona-surface text-krona-secondary border-t border-krona-border flex items-center justify-around z-40 px-1 pt-1 pb-[max(0.5rem,env(safe-area-inset-bottom))] shadow-lg backdrop-blur-md"
>
{/* 1. Главная (KPI Сводка) */}
<button
onClick={() => navigate('/?tab=dashboard')}
className={`flex-1 min-h-[48px] min-w-[44px] flex flex-col items-center justify-center gap-1 p-1 rounded-xl transition-colors select-none ${
isDashboardActive
? 'text-krona-gold font-bold bg-krona-gold/10'
: 'text-krona-secondary hover:text-krona-primary active:bg-krona-workspace'
}`}
data-testid="bottom-nav-dashboard"
>
<LayoutDashboard className="w-5 h-5 shrink-0" />
<span className="text-[10px] leading-none font-medium">Главная</span>
</button>
{/* 2. Модули (Единый каталог) */}
<button
onClick={() => navigate('/')}
className={`flex-1 min-h-[48px] min-w-[44px] flex flex-col items-center justify-center gap-1 p-1 rounded-xl transition-colors select-none ${
isCatalogActive
? 'text-krona-gold font-bold bg-krona-gold/10'
: 'text-krona-secondary hover:text-krona-primary active:bg-krona-workspace'
}`}
data-testid="bottom-nav-catalog"
>
<Grid className="w-5 h-5 shrink-0" />
<span className="text-[10px] leading-none font-medium">Модули</span>
</button>
{/* 3. Задачи */}
<NavLink
to="/tasks"
className={({ isActive }) =>
`flex-1 min-h-[48px] min-w-[44px] flex flex-col items-center justify-center gap-1 p-1 rounded-xl transition-colors select-none ${
isActive
? 'text-krona-gold font-bold bg-krona-gold/10'
: 'text-krona-secondary hover:text-krona-primary active:bg-krona-workspace'
}`
}
data-testid="bottom-nav-tasks"
>
<CheckSquare className="w-5 h-5 shrink-0" />
<span className="text-[10px] leading-none font-medium">Задачи</span>
</NavLink>
{/* 4. Коммуникации */}
<NavLink
to="/communications"
className={({ isActive }) =>
`flex-1 min-h-[48px] min-w-[44px] flex flex-col items-center justify-center gap-1 p-1 rounded-xl transition-colors select-none ${
isActive
? 'text-krona-gold font-bold bg-krona-gold/10'
: 'text-krona-secondary hover:text-krona-primary active:bg-krona-workspace'
}`
}
data-testid="bottom-nav-communications"
>
<MessageSquareText className="w-5 h-5 shrink-0" />
<span className="text-[10px] leading-none font-medium">Диалоги</span>
</NavLink>
{/* 5. Ещё */}
<button
onClick={() => setIsDrawerOpen(true)}
className={`flex-1 min-h-[48px] min-w-[44px] flex flex-col items-center justify-center gap-1 p-1 rounded-xl transition-colors select-none ${
isDrawerOpen
? 'text-krona-gold font-bold bg-krona-gold/10'
: 'text-krona-secondary hover:text-krona-primary active:bg-krona-workspace'
}`}
data-testid="bottom-nav-more"
>
<Menu className="w-5 h-5 shrink-0" />
<span className="text-[10px] leading-none font-medium">Ещё</span>
</button>
</nav>
{/* Slide-out Mobile Menu Drawer */}
<MobileMenuDrawer
isOpen={isDrawerOpen}
onClose={() => setIsDrawerOpen(false)}
/>
</>
);
};