134 lines
5.5 KiB
TypeScript
134 lines
5.5 KiB
TypeScript
import { useState } from 'react';
|
|
import { Button } from './ui/button';
|
|
import { Input } from './ui/input';
|
|
import { Sheet, SheetContent, SheetTrigger } from './ui/sheet';
|
|
import { Search, Menu, MapPin } from 'lucide-react';
|
|
|
|
interface HeaderProps {
|
|
activeCity?: string;
|
|
onCityChange?: (city: string) => void;
|
|
}
|
|
|
|
export function Header({ activeCity, onCityChange }: HeaderProps) {
|
|
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
|
|
const cities = [
|
|
'Paris', 'London', 'New York', 'Tokyo', 'Barcelona', 'Rome'
|
|
];
|
|
|
|
const filteredCities = cities.filter(city =>
|
|
city.toLowerCase().includes(searchQuery.toLowerCase())
|
|
);
|
|
|
|
const handleCitySelect = (city: string) => {
|
|
onCityChange?.(city);
|
|
setSearchQuery('');
|
|
setIsSearchOpen(false);
|
|
};
|
|
|
|
return (
|
|
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
<div className="container flex h-16 items-center justify-between px-4">
|
|
{/* Logo */}
|
|
<div className="flex items-center space-x-2">
|
|
<div className="flex items-center space-x-2">
|
|
<div className="w-8 h-8 bg-gradient-to-r from-primary to-secondary rounded-lg flex items-center justify-center">
|
|
<MapPin className="w-5 h-5 text-white" />
|
|
</div>
|
|
<span className="font-merchant text-lg font-semibold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
|
CityCards
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Desktop Navigation */}
|
|
<nav className="hidden md:flex items-center space-x-6">
|
|
<a href="#" className="hover:text-primary transition-colors">Cities</a>
|
|
<a href="#" className="hover:text-primary transition-colors">Passes</a>
|
|
<a href="#" className="hover:text-primary transition-colors">How it Works</a>
|
|
<a href="#" className="hover:text-primary transition-colors">Support</a>
|
|
</nav>
|
|
|
|
{/* Search and Actions */}
|
|
<div className="flex items-center space-x-3">
|
|
{/* City Search */}
|
|
<div className="relative hidden md:block">
|
|
<div className="relative">
|
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground w-4 h-4" />
|
|
<Input
|
|
placeholder="Search cities..."
|
|
value={searchQuery}
|
|
onChange={(e) => {
|
|
setSearchQuery(e.target.value);
|
|
setIsSearchOpen(e.target.value.length > 0);
|
|
}}
|
|
onFocus={() => setIsSearchOpen(true)}
|
|
className="pl-10 w-64"
|
|
/>
|
|
</div>
|
|
|
|
{isSearchOpen && (
|
|
<div className="absolute top-full mt-1 w-full bg-popover border rounded-md shadow-lg z-50">
|
|
{filteredCities.length > 0 ? (
|
|
filteredCities.map((city) => (
|
|
<button
|
|
key={city}
|
|
onClick={() => handleCitySelect(city)}
|
|
className="w-full text-left px-4 py-2 hover:bg-accent transition-colors first:rounded-t-md last:rounded-b-md"
|
|
>
|
|
{city}
|
|
</button>
|
|
))
|
|
) : (
|
|
<div className="px-4 py-2 text-muted-foreground">No cities found</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<Button variant="outline" className="hidden md:inline-flex">
|
|
Sign In
|
|
</Button>
|
|
<Button className="hidden md:inline-flex bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90">
|
|
Get Started
|
|
</Button>
|
|
|
|
{/* Mobile Menu */}
|
|
<Sheet>
|
|
<SheetTrigger asChild>
|
|
<Button variant="outline" size="icon" className="md:hidden">
|
|
<Menu className="h-4 w-4" />
|
|
<span className="sr-only">Toggle menu</span>
|
|
</Button>
|
|
</SheetTrigger>
|
|
<SheetContent side="right" className="w-80">
|
|
<div className="flex flex-col space-y-4 mt-6">
|
|
{/* Mobile Search */}
|
|
<div className="relative">
|
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground w-4 h-4" />
|
|
<Input placeholder="Search cities..." className="pl-10" />
|
|
</div>
|
|
|
|
{/* Mobile Navigation */}
|
|
<nav className="flex flex-col space-y-3">
|
|
<a href="#" className="py-2 hover:text-primary transition-colors">Cities</a>
|
|
<a href="#" className="py-2 hover:text-primary transition-colors">Passes</a>
|
|
<a href="#" className="py-2 hover:text-primary transition-colors">How it Works</a>
|
|
<a href="#" className="py-2 hover:text-primary transition-colors">Support</a>
|
|
</nav>
|
|
|
|
<div className="flex flex-col space-y-2 pt-4 border-t">
|
|
<Button variant="outline">Sign In</Button>
|
|
<Button className="bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90">
|
|
Get Started
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</SheetContent>
|
|
</Sheet>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
} |