davanstrien HF staff commited on
Commit
1e45463
·
1 Parent(s): 4bdf3bc

Add filter options for search and similar resources

Browse files
Files changed (1) hide show
  1. index.html +176 -8
index.html CHANGED
@@ -111,7 +111,7 @@
111
  Enter keywords to search through descriptions. The search will
112
  automatically update as you type.
113
  </p>
114
- <div class="flex gap-2">
115
  <select
116
  id="searchTypeSelect"
117
  class="text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none"
@@ -129,6 +129,54 @@
129
  <option value="likes">Sort by likes</option>
130
  <option value="downloads">Sort by downloads</option>
131
  </select>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  </div>
133
  </div>
134
  <div class="relative">
@@ -156,7 +204,7 @@
156
  Enter an ID to find similar resources. Popular items will appear
157
  as you type.
158
  </p>
159
- <div class="flex gap-2">
160
  <select
161
  id="similarTypeSelect"
162
  class="text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none"
@@ -174,6 +222,54 @@
174
  <option value="likes">Sort by likes</option>
175
  <option value="downloads">Sort by downloads</option>
176
  </select>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  </div>
178
  </div>
179
  <div class="flex gap-3">
@@ -300,6 +396,8 @@
300
  // Add these variables with other configurations
301
  let currentSort = "similarity";
302
  let currentType = INITIAL_TYPE;
 
 
303
 
304
  // Initialize Lucide icons
305
  lucide.createIcons();
@@ -629,7 +727,7 @@
629
  const response = await fetch(
630
  `${endpoint}?${paramName}=${encodeURIComponent(resourceId)}&k=${
631
  RESULTS_PER_PAGE * page
632
- }&sort_by=${currentSort}`
633
  );
634
  if (!response.ok) throw new Error("Similarity search failed");
635
 
@@ -928,11 +1026,15 @@
928
 
929
  try {
930
  const endpoint = `${API_URL}/search/${currentType}`;
931
- const response = await fetch(
932
- `${endpoint}?query=${encodeURIComponent(query)}&k=${
933
- RESULTS_PER_PAGE * page
934
- }&sort_by=${currentSort}`
935
- );
 
 
 
 
936
  if (!response.ok) throw new Error("Search failed");
937
 
938
  const data = await response.json();
@@ -1031,6 +1133,72 @@
1031
  }
1032
  }
1033
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1034
  </script>
1035
  </body>
1036
  </html>
 
111
  Enter keywords to search through descriptions. The search will
112
  automatically update as you type.
113
  </p>
114
+ <div class="flex flex-wrap gap-2">
115
  <select
116
  id="searchTypeSelect"
117
  class="text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none"
 
129
  <option value="likes">Sort by likes</option>
130
  <option value="downloads">Sort by downloads</option>
131
  </select>
132
+ <div class="relative">
133
+ <button
134
+ onclick="toggleFilters('search')"
135
+ class="text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 hover:bg-gray-50 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none flex items-center gap-2"
136
+ >
137
+ <i data-lucide="filter"></i>
138
+ Filters
139
+ <span
140
+ id="searchActiveFilters"
141
+ class="hidden px-1.5 py-0.5 bg-blue-100 text-blue-700 text-xs rounded-full"
142
+ ></span>
143
+ </button>
144
+ <div
145
+ id="searchFiltersPopover"
146
+ class="hidden absolute right-0 mt-2 w-64 bg-white border border-gray-200 rounded-lg shadow-lg p-4 z-10"
147
+ >
148
+ <div class="space-y-4">
149
+ <div>
150
+ <label
151
+ class="block text-sm font-medium text-gray-700 mb-1"
152
+ >Minimum Likes</label
153
+ >
154
+ <input
155
+ type="number"
156
+ id="searchMinLikes"
157
+ placeholder="0"
158
+ min="0"
159
+ class="w-full text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none"
160
+ onchange="handleFilterChange('search')"
161
+ />
162
+ </div>
163
+ <div>
164
+ <label
165
+ class="block text-sm font-medium text-gray-700 mb-1"
166
+ >Minimum Downloads</label
167
+ >
168
+ <input
169
+ type="number"
170
+ id="searchMinDownloads"
171
+ placeholder="0"
172
+ min="0"
173
+ class="w-full text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none"
174
+ onchange="handleFilterChange('search')"
175
+ />
176
+ </div>
177
+ </div>
178
+ </div>
179
+ </div>
180
  </div>
181
  </div>
182
  <div class="relative">
 
204
  Enter an ID to find similar resources. Popular items will appear
205
  as you type.
206
  </p>
207
+ <div class="flex flex-wrap gap-2">
208
  <select
209
  id="similarTypeSelect"
210
  class="text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none"
 
222
  <option value="likes">Sort by likes</option>
223
  <option value="downloads">Sort by downloads</option>
224
  </select>
225
+ <div class="relative">
226
+ <button
227
+ onclick="toggleFilters('similar')"
228
+ class="text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 hover:bg-gray-50 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none flex items-center gap-2"
229
+ >
230
+ <i data-lucide="filter"></i>
231
+ Filters
232
+ <span
233
+ id="similarActiveFilters"
234
+ class="hidden px-1.5 py-0.5 bg-blue-100 text-blue-700 text-xs rounded-full"
235
+ ></span>
236
+ </button>
237
+ <div
238
+ id="similarFiltersPopover"
239
+ class="hidden absolute right-0 mt-2 w-64 bg-white border border-gray-200 rounded-lg shadow-lg p-4 z-10"
240
+ >
241
+ <div class="space-y-4">
242
+ <div>
243
+ <label
244
+ class="block text-sm font-medium text-gray-700 mb-1"
245
+ >Minimum Likes</label
246
+ >
247
+ <input
248
+ type="number"
249
+ id="similarMinLikes"
250
+ placeholder="0"
251
+ min="0"
252
+ class="w-full text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none"
253
+ onchange="handleFilterChange('similar')"
254
+ />
255
+ </div>
256
+ <div>
257
+ <label
258
+ class="block text-sm font-medium text-gray-700 mb-1"
259
+ >Minimum Downloads</label
260
+ >
261
+ <input
262
+ type="number"
263
+ id="similarMinDownloads"
264
+ placeholder="0"
265
+ min="0"
266
+ class="w-full text-sm border rounded-lg px-3 py-2 bg-white text-gray-700 focus:ring-2 focus:ring-blue-100 focus:border-blue-300 transition-all outline-none"
267
+ onchange="handleFilterChange('similar')"
268
+ />
269
+ </div>
270
+ </div>
271
+ </div>
272
+ </div>
273
  </div>
274
  </div>
275
  <div class="flex gap-3">
 
396
  // Add these variables with other configurations
397
  let currentSort = "similarity";
398
  let currentType = INITIAL_TYPE;
399
+ let currentMinLikes = 0;
400
+ let currentMinDownloads = 0;
401
 
402
  // Initialize Lucide icons
403
  lucide.createIcons();
 
727
  const response = await fetch(
728
  `${endpoint}?${paramName}=${encodeURIComponent(resourceId)}&k=${
729
  RESULTS_PER_PAGE * page
730
+ }&sort_by=${currentSort}&min_likes=${currentMinLikes}&min_downloads=${currentMinDownloads}`
731
  );
732
  if (!response.ok) throw new Error("Similarity search failed");
733
 
 
1026
 
1027
  try {
1028
  const endpoint = `${API_URL}/search/${currentType}`;
1029
+ const params = new URLSearchParams({
1030
+ query: query,
1031
+ k: RESULTS_PER_PAGE * page,
1032
+ sort_by: currentSort,
1033
+ min_likes: currentMinLikes,
1034
+ min_downloads: currentMinDownloads,
1035
+ });
1036
+
1037
+ const response = await fetch(`${endpoint}?${params}`);
1038
  if (!response.ok) throw new Error("Search failed");
1039
 
1040
  const data = await response.json();
 
1133
  }
1134
  }
1135
  }
1136
+
1137
+ // Add these new functions to handle the filters UI
1138
+ function toggleFilters(tab) {
1139
+ const popover = document.getElementById(`${tab}FiltersPopover`);
1140
+ popover.classList.toggle("hidden");
1141
+
1142
+ // Close other popovers
1143
+ const otherTab = tab === "search" ? "similar" : "search";
1144
+ document
1145
+ .getElementById(`${otherTab}FiltersPopover`)
1146
+ .classList.add("hidden");
1147
+ }
1148
+
1149
+ // Close filters when clicking outside
1150
+ document.addEventListener("click", (event) => {
1151
+ const searchPopover = document.getElementById("searchFiltersPopover");
1152
+ const similarPopover = document.getElementById("similarFiltersPopover");
1153
+ const searchButton = event.target.closest(
1154
+ "button[onclick=\"toggleFilters('search')\"]"
1155
+ );
1156
+ const similarButton = event.target.closest(
1157
+ "button[onclick=\"toggleFilters('similar')\"]"
1158
+ );
1159
+
1160
+ if (!searchButton && !event.target.closest("#searchFiltersPopover")) {
1161
+ searchPopover.classList.add("hidden");
1162
+ }
1163
+ if (!similarButton && !event.target.closest("#similarFiltersPopover")) {
1164
+ similarPopover.classList.add("hidden");
1165
+ }
1166
+ });
1167
+
1168
+ // Modify handleFilterChange to update the active filters indicator
1169
+ function handleFilterChange(tab) {
1170
+ const minLikesInput = document.getElementById(`${tab}MinLikes`);
1171
+ const minDownloadsInput = document.getElementById(`${tab}MinDownloads`);
1172
+ const activeFiltersSpan = document.getElementById(
1173
+ `${tab}ActiveFilters`
1174
+ );
1175
+
1176
+ currentMinLikes = parseInt(minLikesInput.value) || 0;
1177
+ currentMinDownloads = parseInt(minDownloadsInput.value) || 0;
1178
+
1179
+ // Update active filters indicator
1180
+ const activeCount =
1181
+ (currentMinLikes > 0 ? 1 : 0) + (currentMinDownloads > 0 ? 1 : 0);
1182
+ if (activeCount > 0) {
1183
+ activeFiltersSpan.textContent = activeCount;
1184
+ activeFiltersSpan.classList.remove("hidden");
1185
+ } else {
1186
+ activeFiltersSpan.classList.add("hidden");
1187
+ }
1188
+
1189
+ // Re-run the current search with new filters
1190
+ if (tab === "search") {
1191
+ const searchQuery = document.getElementById("searchInput").value;
1192
+ if (searchQuery.length >= MIN_SEARCH_LENGTH) {
1193
+ searchResources(searchQuery, 1);
1194
+ }
1195
+ } else {
1196
+ const resourceId = document.getElementById("resourceInput").value;
1197
+ if (resourceId) {
1198
+ findSimilarResources(1);
1199
+ }
1200
+ }
1201
+ }
1202
  </script>
1203
  </body>
1204
  </html>