-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserach.js
More file actions
161 lines (145 loc) · 5.46 KB
/
serach.js
File metadata and controls
161 lines (145 loc) · 5.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import React, { useState, useEffect } from 'react';
import { Search } from 'lucide-react';
import { debounce } from 'lodash';
import {
Card,
CardContent,
CardHeader,
CardTitle
} from '@/components/ui/card';
const SearchInterface = () => {
const [searchTerm, setSearchTerm] = useState('');
const [filters, setFilters] = useState({
category: 'all',
sortBy: 'relevance',
itemsPerPage: 10
});
const [results, setResults] = useState([]);
const [suggestions, setSuggestions] = useState([]);
const [loading, setLoading] = useState(false);
// Simulated data for demo purposes
const sampleData = [
{ id: 1, title: 'JavaScript Basics', category: 'programming', content: 'Learn the basics of JavaScript programming' },
{ id: 2, title: 'React Fundamentals', category: 'programming', content: 'Understanding React core concepts' },
{ id: 3, title: 'Database Design', category: 'database', content: 'Introduction to database design principles' }
];
// Simulate API call with delay
const fetchSearchResults = async (term, filters) => {
setLoading(true);
// Simulate network delay
await new Promise(resolve => setTimeout(resolve, 500));
// Filter and sort results based on search term and filters
const filtered = sampleData.filter(item => {
if (filters.category !== 'all' && item.category !== filters.category) return false;
return item.title.toLowerCase().includes(term.toLowerCase()) ||
item.content.toLowerCase().includes(term.toLowerCase());
});
setResults(filtered);
setLoading(false);
};
// Debounced search to prevent too many API calls
const debouncedSearch = debounce((term, filters) => {
fetchSearchResults(term, filters);
}, 300);
// Update search results when search term or filters change
useEffect(() => {
if (searchTerm) {
debouncedSearch(searchTerm, filters);
} else {
setResults([]);
}
}, [searchTerm, filters]);
// Generate search suggestions
useEffect(() => {
if (searchTerm.length > 2) {
const matchingSuggestions = sampleData
.filter(item => item.title.toLowerCase().includes(searchTerm.toLowerCase()))
.map(item => item.title)
.slice(0, 5);
setSuggestions(matchingSuggestions);
} else {
setSuggestions([]);
}
}, [searchTerm]);
return (
<Card className="w-full max-w-4xl mx-auto">
<CardHeader>
<CardTitle>Database Search</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-4">
{/* Search input */}
<div className="relative">
<div className="relative">
<input
type="text"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder="Search database..."
className="w-full p-2 pr-10 border rounded-lg"
/>
<Search className="absolute right-3 top-2.5 h-5 w-5 text-gray-400" />
</div>
{/* Search suggestions */}
{suggestions.length > 0 && (
<div className="absolute z-10 w-full bg-white border rounded-lg mt-1 shadow-lg">
{suggestions.map((suggestion, index) => (
<div
key={index}
className="p-2 hover:bg-gray-100 cursor-pointer"
onClick={() => setSearchTerm(suggestion)}
>
{suggestion}
</div>
))}
</div>
)}
</div>
{/* Filters */}
<div className="flex gap-4">
<select
value={filters.category}
onChange={(e) => setFilters({...filters, category: e.target.value})}
className="p-2 border rounded-lg"
>
<option value="all">All Categories</option>
<option value="programming">Programming</option>
<option value="database">Database</option>
</select>
<select
value={filters.sortBy}
onChange={(e) => setFilters({...filters, sortBy: e.target.value})}
className="p-2 border rounded-lg"
>
<option value="relevance">Sort by Relevance</option>
<option value="date">Sort by Date</option>
<option value="title">Sort by Title</option>
</select>
</div>
{/* Loading state */}
{loading && (
<div className="text-center py-4">
Loading...
</div>
)}
{/* Search results */}
<div className="space-y-4">
{results.map((result) => (
<div key={result.id} className="p-4 border rounded-lg">
<h3 className="text-lg font-semibold">{result.title}</h3>
<p className="text-sm text-gray-600">{result.category}</p>
<p className="mt-2">{result.content}</p>
</div>
))}
{!loading && results.length === 0 && searchTerm && (
<div className="text-center py-4 text-gray-500">
No results found for "{searchTerm}"
</div>
)}
</div>
</div>
</CardContent>
</Card>
);
};
export default SearchInterface;