Files
grib/src/components/Header.tsx
Денис Шкабатур 72e07dad3d feat: Грибы Крыма — полная энциклопедия и справочник грибника
- Энциклопедия 20 видов грибов Крыма с детальными описаниями
- Интерактивный календарь грибника по месяцам
- Справочник: правила сбора, первая помощь, кулинария
- Поиск и фильтрация по съедобности и сезону
- Адаптивный дизайн, природная цветовая палитра
- Docker-конфигурация для деплоя

Tech: Next.js 15, TypeScript, Tailwind CSS 4, React 19
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 13:05:24 +03:00

99 lines
3.5 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.
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Menu, X, TreePine } from 'lucide-react';
import { cn } from '@/lib/utils';
const navigation = [
{ name: 'Главная', href: '/' },
{ name: 'Энциклопедия', href: '/encyclopedia' },
{ name: 'Календарь', href: '/calendar' },
{ name: 'Справочник', href: '/guide' },
];
export function Header() {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const pathname = usePathname();
return (
<header className="sticky top-0 z-50 border-b border-border bg-white/80 backdrop-blur-md">
<nav className="mx-auto flex max-w-7xl items-center justify-between px-4 py-3 sm:px-6 lg:px-8">
<Link href="/" className="flex items-center gap-2.5 group">
<div className="flex h-10 w-10 items-center justify-center rounded-xl bg-forest-600 text-white shadow-sm transition-transform group-hover:scale-105">
<TreePine className="h-5 w-5" />
</div>
<div>
<span className="block text-lg font-bold leading-tight text-forest-900">
Грибы Крыма
</span>
<span className="block text-[11px] font-medium leading-tight text-muted-foreground tracking-wide">
Энциклопедия грибника
</span>
</div>
</Link>
{/* Desktop nav */}
<div className="hidden md:flex md:items-center md:gap-1">
{navigation.map((item) => {
const isActive = pathname === item.href ||
(item.href !== '/' && pathname.startsWith(item.href));
return (
<Link
key={item.name}
href={item.href}
className={cn(
'rounded-lg px-4 py-2 text-sm font-medium transition-colors',
isActive
? 'bg-forest-50 text-forest-700'
: 'text-muted-foreground hover:bg-muted hover:text-foreground'
)}
>
{item.name}
</Link>
);
})}
</div>
{/* Mobile menu button */}
<button
type="button"
className="md:hidden rounded-lg p-2 text-muted-foreground hover:bg-muted"
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
aria-label="Toggle menu"
>
{mobileMenuOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />}
</button>
</nav>
{/* Mobile menu */}
{mobileMenuOpen && (
<div className="md:hidden border-t border-border bg-white animate-fade-in">
<div className="space-y-1 px-4 py-3">
{navigation.map((item) => {
const isActive = pathname === item.href ||
(item.href !== '/' && pathname.startsWith(item.href));
return (
<Link
key={item.name}
href={item.href}
onClick={() => setMobileMenuOpen(false)}
className={cn(
'block rounded-lg px-4 py-2.5 text-sm font-medium transition-colors',
isActive
? 'bg-forest-50 text-forest-700'
: 'text-muted-foreground hover:bg-muted hover:text-foreground'
)}
>
{item.name}
</Link>
);
})}
</div>
</div>
)}
</header>
);
}