feat: Add search and filter UI components

- Created SearchBar component with debounced input
- Built FilterPanel component with controls for priority, completion, tags, and due date
- Added sort controls (field and direction)
- Implemented filter clear functionality
- Display search results with highlighted text
- Added GlobalSearch component for home page
- Integrated search and filter into list detail view
- Added CSS styles for search highlighting

Requirements: 6.1, 6.2, 6.3, 6.4, 8.1, 8.2, 8.3
This commit is contained in:
2025-12-01 19:25:09 +00:00
parent 477e378d08
commit 0143097e69
9 changed files with 781 additions and 43 deletions

61
components/SearchBar.tsx Normal file
View File

@@ -0,0 +1,61 @@
'use client'
import { useState, useEffect, useCallback } from 'react'
import { Search, X } from 'lucide-react'
interface SearchBarProps {
onSearch: (query: string) => void
placeholder?: string
debounceMs?: number
initialValue?: string
}
export default function SearchBar({
onSearch,
placeholder = 'Search tasks...',
debounceMs = 300,
initialValue = ''
}: SearchBarProps) {
const [query, setQuery] = useState(initialValue)
// Debounced search effect
useEffect(() => {
const timer = setTimeout(() => {
onSearch(query)
}, debounceMs)
return () => clearTimeout(timer)
}, [query, debounceMs, onSearch])
const handleClear = useCallback(() => {
setQuery('')
onSearch('')
}, [onSearch])
return (
<div className="relative">
<div className="relative">
<Search
className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"
size={20}
/>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder={placeholder}
className="w-full pl-10 pr-10 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
{query && (
<button
onClick={handleClear}
className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 transition-colors"
aria-label="Clear search"
>
<X size={20} />
</button>
)}
</div>
</div>
)
}