You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.1 KiB
75 lines
2.1 KiB
import { SEARCH_QUERY_DEBOUNCE_MS } from '@/constants' |
|
import { Input } from '@/components/ui/input' |
|
import { Search, X } from 'lucide-react' |
|
import { cn } from '@/lib/utils' |
|
import { useState, useEffect } from 'react' |
|
|
|
interface ProfileSearchBarProps { |
|
onSearch: (query: string) => void |
|
placeholder?: string |
|
className?: string |
|
disabled?: boolean |
|
} |
|
|
|
export default function ProfileSearchBar({ |
|
onSearch, |
|
placeholder = "Search...", |
|
className, |
|
disabled = false |
|
}: ProfileSearchBarProps) { |
|
const [query, setQuery] = useState('') |
|
const [isFocused, setIsFocused] = useState(false) |
|
|
|
// Debounce search to avoid too many calls |
|
useEffect(() => { |
|
const timer = setTimeout(() => { |
|
onSearch(query) |
|
}, SEARCH_QUERY_DEBOUNCE_MS) |
|
|
|
return () => clearTimeout(timer) |
|
}, [query, onSearch]) |
|
|
|
const handleClear = () => { |
|
setQuery('') |
|
onSearch('') |
|
} |
|
|
|
return ( |
|
<div className={cn('relative flex items-center', className)}> |
|
<div className="relative flex-1"> |
|
<Search |
|
className={cn( |
|
'absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground transition-colors', |
|
isFocused && 'text-green-500' |
|
)} |
|
/> |
|
<Input |
|
type="text" |
|
placeholder={placeholder} |
|
value={query} |
|
onChange={(e) => setQuery(e.target.value)} |
|
onFocus={() => setIsFocused(true)} |
|
onBlur={() => setIsFocused(false)} |
|
disabled={disabled} |
|
className={cn( |
|
'pl-10 pr-10 h-10', |
|
'border-2 border-muted-foreground/20 focus:border-green-500', |
|
'bg-background text-foreground', |
|
'transition-all duration-200', |
|
'rounded-lg', |
|
disabled && 'opacity-50 cursor-not-allowed' |
|
)} |
|
/> |
|
{query && ( |
|
<button |
|
onClick={handleClear} |
|
className="absolute right-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground hover:text-foreground transition-colors" |
|
disabled={disabled} |
|
> |
|
<X className="h-4 w-4" /> |
|
</button> |
|
)} |
|
</div> |
|
</div> |
|
) |
|
}
|
|
|