| null>(null);
const fetchResults = useCallback(
- async (q: string, diff: string, maxM: string, off: number, append = false) => {
+ async (q: string, diff: string, maxM: string, off: number, tags: string[], append = false) => {
if (!q.trim()) {
setResults([]);
setTotal(0);
@@ -124,6 +126,7 @@ export function ExplorePageContent({ trending, recent, initialQuery }: Props) {
const params = new URLSearchParams({ q, limit: "20", offset: String(off) });
if (diff && diff !== "any") params.set("difficulty", diff);
if (maxM) params.set("maxMins", maxM);
+ if (tags.length > 0) params.set("tags", tags.join(","));
const res = await fetch(`/api/v1/search?${params}`);
if (!res.ok) return;
const json = await res.json() as SearchResponse;
@@ -157,7 +160,7 @@ export function ExplorePageContent({ trending, recent, initialQuery }: Props) {
useEffect(() => {
if (initialQuery) {
- fetchResults(initialQuery, "any", "", 0);
+ fetchResults(initialQuery, "any", "", 0, []);
fetchPeople(initialQuery);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -213,7 +216,7 @@ export function ExplorePageContent({ trending, recent, initialQuery }: Props) {
debounceRef.current = setTimeout(() => {
setQuery(value);
updateUrl(value);
- fetchResults(value, difficulty, maxMins, 0);
+ fetchResults(value, difficulty, maxMins, 0, [...selectedTags]);
fetchPeople(value);
}, 300);
};
@@ -223,24 +226,34 @@ export function ExplorePageContent({ trending, recent, initialQuery }: Props) {
if (debounceRef.current) clearTimeout(debounceRef.current);
setQuery(inputValue);
updateUrl(inputValue);
- fetchResults(inputValue, difficulty, maxMins, 0);
+ fetchResults(inputValue, difficulty, maxMins, 0, [...selectedTags]);
fetchPeople(inputValue);
};
const handleDifficultyChange = (value: string | null) => {
const v = value ?? "any";
setDifficulty(v);
- fetchResults(query, v, maxMins, 0);
+ fetchResults(query, v, maxMins, 0, [...selectedTags]);
};
const handleMaxMinsChange = (value: string) => {
setMaxMins(value);
if (debounceRef.current) clearTimeout(debounceRef.current);
debounceRef.current = setTimeout(() => {
- fetchResults(query, difficulty, value, 0);
+ fetchResults(query, difficulty, value, 0, [...selectedTags]);
}, 300);
};
+ const toggleTag = (tag: string) => {
+ setSelectedTags((prev) => {
+ const next = new Set(prev);
+ if (next.has(tag)) next.delete(tag);
+ else next.add(tag);
+ fetchResults(query, difficulty, maxMins, 0, [...next]);
+ return next;
+ });
+ };
+
const hasQuery = query.trim().length > 0;
const hasMore = results.length < total;
const hasNoResults = hasQuery && !loading && !peopleLoading && results.length === 0 && peopleResults.length === 0;
@@ -294,6 +307,18 @@ export function ExplorePageContent({ trending, recent, initialQuery }: Props) {
)}
)}
+
+ {hasQuery && popularTags.length > 0 && (
+
+ {popularTags.map((tag) => (
+
+ ))}
+
+ )}
{/* People results */}
@@ -365,7 +390,7 @@ export function ExplorePageContent({ trending, recent, initialQuery }: Props) {