Files
neomovies/src/components/HeaderBar.tsx

119 lines
5.2 KiB
TypeScript
Raw Normal View History

2025-07-08 00:15:55 +03:00
"use client";
import Link from "next/link";
import { useState, useEffect } from "react";
import { useTheme } from 'next-themes';
import { Search, Sun, Moon, User, Menu, Settings } from "lucide-react";
import { usePathname, useRouter } from 'next/navigation';
const NavLink = ({ href, children }: { href: string; children: React.ReactNode }) => {
const pathname = usePathname();
const isActive = pathname === href;
return (
<Link href={href} className={`text-sm font-medium transition-colors ${isActive ? 'text-accent-orange font-semibold' : 'text-gray-500 dark:text-gray-400 hover:text-accent-orange dark:hover:text-accent-orange'}`}>
{children}
</Link>
);
};
const ThemeToggleButton = () => {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return <div className="w-9 h-9" />; // placeholder
return (
<button
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
className="p-2 rounded-full bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-300 hover:text-black dark:hover:text-white transition-colors"
aria-label="Toggle theme"
>
{theme === 'dark' ? <Sun size={20} /> : <Moon size={20} />}
</button>
);
};
export default function HeaderBar({ onBurgerClick }: { onBurgerClick?: () => void }) {
const [userName, setUserName] = useState<string | null>(
typeof window !== 'undefined' ? localStorage.getItem('userName') : null
);
const [query, setQuery] = useState("");
const router = useRouter();
useEffect(() => {
const handler = () => setUserName(localStorage.getItem('userName'));
window.addEventListener('auth-changed', handler);
return () => window.removeEventListener('auth-changed', handler);
}, []);
const handleSearch = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (query.trim()) {
router.push(`/search?q=${encodeURIComponent(query.trim())}`);
setQuery('');
}
};
return (
<header className="sticky top-0 z-50 bg-white dark:bg-[#1a1a1a] text-gray-800 dark:text-white shadow-md">
<div className="w-full px-4 sm:px-6 lg:px-8">
{/* Top bar */}
<div className="flex items-center justify-between h-14">
2025-07-08 01:01:58 +03:00
{/* Hide logo on small screens to give more space to search bar */}
<div className="hidden sm:flex items-center space-x-6">
2025-07-08 00:15:55 +03:00
<Link href="/" className="text-xl font-bold text-gray-900 dark:text-white">
Neo<span className="text-red-500">Movies</span>
</Link>
</div>
2025-07-08 01:01:58 +03:00
{/* Search form - now more responsive */}
<form onSubmit={handleSearch} className="flex-1 min-w-0 max-w-xl sm:mx-8">
2025-07-08 00:15:55 +03:00
<div className="relative">
<input
type="text"
placeholder="Поиск фильмов и сериалов..."
value={query}
onChange={(e) => setQuery(e.target.value)}
className="w-full bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-full py-2 pl-10 pr-4 text-sm text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-transparent"
/>
<Search className="absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-gray-400 dark:text-gray-500" />
</div>
</form>
<div className="flex items-center space-x-4">
<ThemeToggleButton />
2025-07-08 13:41:04 +03:00
<Link href="/settings" className="p-2 rounded-full bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors">
<Settings size={20} className="text-gray-800 dark:text-gray-300 hover:text-accent-orange" />
</Link>
2025-07-08 00:15:55 +03:00
{userName ? (
2025-07-08 13:41:04 +03:00
<Link href="/profile" className="flex items-center space-x-2 p-2 rounded-full bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors">
<User size={20} className="text-gray-800 dark:text-gray-300" />
<span className="text-sm font-medium hidden sm:block text-gray-800 dark:text-white">{userName}</span>
</Link>
2025-07-08 00:15:55 +03:00
) : (
<Link href="/login" className="text-sm font-medium p-2 rounded-md bg-red-600 hover:bg-red-700 text-white transition-colors">
Вход
</Link>
)}
<button onClick={onBurgerClick} className="md:hidden p-2 rounded-full bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600">
<Menu size={20} className="text-gray-800 dark:text-gray-300" />
</button>
</div>
</div>
{/* Bottom bar */}
<div className="hidden md:flex items-center justify-center h-12 border-t border-gray-200 dark:border-gray-800">
<nav className="flex items-center space-x-8">
<NavLink href="/">Фильмы</NavLink>
<NavLink href="/categories">Категории</NavLink>
<NavLink href="/favorites">Избранное</NavLink>
</nav>
</div>
</div>
</header>
);
}