2024-12-09 16:06:47 +03:00

189 lines
7.2 KiB
TypeScript

import React, { useState } from 'react';
import { Menu, Search, X, ChevronDown } from 'lucide-react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import { Category, City } from '../types';
const categories: Category[] = ['Film', 'Theater', 'Music', 'Sports', 'Art', 'Legends', 'Anniversaries', 'Memory'];
const cities: City[] = ['New York', 'London'];
export function Header() {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [searchQuery, setSearchQuery] = useState('');
const location = useLocation();
const navigate = useNavigate();
const searchParams = new URLSearchParams(location.search);
const currentCategory = searchParams.get('category');
const currentCity = searchParams.get('city');
const handleCityChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const city = event.target.value;
const params = new URLSearchParams(location.search);
if (city) {
params.set('city', city);
} else {
params.delete('city');
}
navigate(`/?${params.toString()}`);
};
const handleSearch = (e: React.FormEvent) => {
e.preventDefault();
if (searchQuery.trim()) {
navigate(`/search?q=${encodeURIComponent(searchQuery.trim())}`);
}
};
const handleSearchKeyPress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
handleSearch(e);
}
};
return (
<header className="sticky top-0 z-50 bg-white shadow-sm">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16">
<div className="flex items-center">
<button
className="p-2 rounded-md text-gray-500 lg:hidden hover:bg-gray-100"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
>
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
</button>
<Link to="/" className="ml-2 flex items-center space-x-2">
<h1 className="text-2xl font-bold text-gray-900">CultureScope</h1>
</Link>
</div>
<nav className="hidden lg:flex items-center space-x-8">
<div className="flex items-center space-x-4">
<span className="text-sm font-medium text-gray-500"></span>
<div className="relative">
<select
value={currentCity || ''}
onChange={handleCityChange}
className="appearance-none bg-white pl-3 pr-8 py-2 text-sm font-medium rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent cursor-pointer"
>
<option value="">All Cities</option>
{cities.map((city) => (
<option key={city} value={city}>
{city}
</option>
))}
</select>
<ChevronDown
size={16}
className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-400 pointer-events-none"
/>
</div>
</div>
<div className="h-6 w-px bg-gray-200" />
<div className="flex items-center space-x-4 overflow-x-auto">
<span className="text-sm font-medium text-gray-500"></span>
<Link
to={currentCity ? `/?city=${currentCity}` : '/'}
className={`px-3 py-2 text-sm font-medium transition-colors whitespace-nowrap ${
!currentCategory
? 'text-blue-600 hover:text-blue-800'
: 'text-gray-600 hover:text-gray-900'
}`}
>
All Categories
</Link>
{categories.map((category) => (
<Link
key={category}
to={`/?category=${category}${currentCity ? `&city=${currentCity}` : ''}`}
className={`px-3 py-2 text-sm font-medium transition-colors whitespace-nowrap ${
currentCategory === category
? 'text-blue-600 hover:text-blue-800'
: 'text-gray-600 hover:text-gray-900'
}`}
>
{category}
</Link>
))}
</div>
</nav>
<div className="flex items-center space-x-4">
<form onSubmit={handleSearch} className="relative">
<input
type="text"
placeholder="Search..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
onKeyPress={handleSearchKeyPress}
className="w-40 lg:w-60 pl-10 pr-4 py-2 text-sm border border-gray-300 rounded-full focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
<button
type="submit"
className="absolute left-3 top-2.5 text-gray-400 hover:text-gray-600"
>
<Search size={18} />
</button>
</form>
</div>
</div>
</div>
{/* Mobile menu */}
<div
className={`lg:hidden ${
isMobileMenuOpen ? 'block' : 'hidden'
} border-b border-gray-200`}
>
<div className="px-2 pt-2 pb-3 space-y-1">
<div className="px-3 py-2">
<h3 className="text-sm font-medium text-gray-500 mb-2">City</h3>
<select
value={currentCity || ''}
onChange={handleCityChange}
className="w-full bg-white px-3 py-2 text-base font-medium rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="">All Cities</option>
{cities.map((city) => (
<option key={city} value={city}>
{city}
</option>
))}
</select>
</div>
<div className="px-3 py-2">
<h3 className="text-sm font-medium text-gray-500 mb-2">Categories</h3>
<div className="space-y-1">
<Link
to={currentCity ? `/?city=${currentCity}` : '/'}
className={`block px-3 py-2 rounded-md text-base font-medium ${
!currentCategory
? 'bg-blue-50 text-blue-600'
: 'text-gray-600 hover:bg-gray-50'
}`}
>
All Categories
</Link>
{categories.map((category) => (
<Link
key={category}
to={`/?category=${category}${currentCity ? `&city=${currentCity}` : ''}`}
className={`block px-3 py-2 rounded-md text-base font-medium ${
currentCategory === category
? 'bg-blue-50 text-blue-600'
: 'text-gray-600 hover:bg-gray-50'
}`}
>
{category}
</Link>
))}
</div>
</div>
</div>
</div>
</header>
);
}