120 lines
3.7 KiB
TypeScript
120 lines
3.7 KiB
TypeScript
import { Search, User, X } from 'lucide-react';
|
|
import { cn } from '@/lib/utils';
|
|
import React, { useState } from 'react';
|
|
import { MediaCategory } from '@/types';
|
|
import LibrarySettings from './LibrarySettings';
|
|
|
|
interface HeaderProps {
|
|
onBrowse: () => void;
|
|
onCast: () => void;
|
|
onSearch: (query: string) => void;
|
|
activeCategory: MediaCategory;
|
|
onCategoryChange: (category: MediaCategory) => void;
|
|
enabledCategories: MediaCategory[];
|
|
onToggleCategory: (category: MediaCategory) => void;
|
|
transparent?: boolean;
|
|
}
|
|
|
|
export default function Header({
|
|
onBrowse,
|
|
onCast,
|
|
onSearch,
|
|
activeCategory,
|
|
onCategoryChange,
|
|
enabledCategories,
|
|
onToggleCategory,
|
|
transparent
|
|
}: HeaderProps) {
|
|
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
|
|
const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
const query = e.target.value;
|
|
setSearchQuery(query);
|
|
onSearch(query);
|
|
};
|
|
|
|
const toggleSearch = () => {
|
|
setIsSearchOpen(!isSearchOpen);
|
|
if (isSearchOpen) {
|
|
setSearchQuery('');
|
|
onSearch('');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<header
|
|
className={cn(
|
|
"fixed top-0 left-0 right-0 z-50 flex items-center justify-between px-6 py-4 transition-all duration-300",
|
|
transparent ? "bg-transparent" : "bg-[#6d28d9]"
|
|
)}
|
|
>
|
|
<div className="flex items-center gap-8">
|
|
<div
|
|
className="text-2xl font-black text-white cursor-pointer flex items-center gap-1"
|
|
onClick={onBrowse}
|
|
>
|
|
<div className="w-6 h-6 bg-white rounded-full flex items-center justify-center">
|
|
<div className="w-3 h-3 bg-[#6d28d9] rounded-full" />
|
|
</div>
|
|
kyoo
|
|
</div>
|
|
<nav className="hidden md:flex items-center gap-6">
|
|
{enabledCategories.map(cat => (
|
|
<button
|
|
key={cat}
|
|
onClick={() => onCategoryChange(cat)}
|
|
className={cn(
|
|
"text-sm font-bold transition-colors uppercase tracking-wider",
|
|
activeCategory === cat ? "text-white" : "text-white/60 hover:text-white"
|
|
)}
|
|
>
|
|
{cat}
|
|
</button>
|
|
))}
|
|
<div className="w-px h-4 bg-white/20 mx-2" />
|
|
<button
|
|
onClick={onCast}
|
|
className="text-sm font-bold text-white/60 hover:text-white transition-colors uppercase tracking-wider"
|
|
>
|
|
CAST
|
|
</button>
|
|
</nav>
|
|
</div>
|
|
<div className="flex items-center gap-4">
|
|
<div className={cn(
|
|
"flex items-center transition-all duration-300 overflow-hidden",
|
|
isSearchOpen ? "w-48 md:w-64 bg-white/10 rounded-full px-3 py-1" : "w-0"
|
|
)}>
|
|
<input
|
|
type="text"
|
|
placeholder="Search..."
|
|
value={searchQuery}
|
|
onChange={handleSearchChange}
|
|
className="bg-transparent border-none outline-none text-white text-sm w-full placeholder:text-white/50"
|
|
autoFocus={isSearchOpen}
|
|
/>
|
|
</div>
|
|
<button
|
|
onClick={toggleSearch}
|
|
className="p-2 text-white/90 hover:text-white transition-colors"
|
|
>
|
|
{isSearchOpen ? <X size={20} /> : <Search size={20} />}
|
|
</button>
|
|
<LibrarySettings
|
|
enabledCategories={enabledCategories}
|
|
onToggleCategory={onToggleCategory}
|
|
/>
|
|
<button className="w-8 h-8 rounded-full overflow-hidden border-2 border-white/20">
|
|
<img
|
|
src="https://picsum.photos/seed/user/100/100"
|
|
alt="User"
|
|
className="w-full h-full object-cover"
|
|
referrerPolicy="no-referrer"
|
|
/>
|
|
</button>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|