first commit
This commit is contained in:
119
src/components/Header.tsx
Normal file
119
src/components/Header.tsx
Normal file
@@ -0,0 +1,119 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user