From 77f3e0d65b1e59f964227dbe8e95f69ee66414ab Mon Sep 17 00:00:00 2001 From: Dominik Stumpf Date: Thu, 21 Nov 2024 06:36:30 +0100 Subject: [PATCH] feat: add search --- .../components/InfiniteScrollGuilds.tsx | 23 ++++++++----- src/app/explorer/components/Search.tsx | 34 ++++++++++++++++++- src/app/explorer/page.tsx | 6 ++-- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/app/explorer/components/InfiniteScrollGuilds.tsx b/src/app/explorer/components/InfiniteScrollGuilds.tsx index cbc92d1d52..18652a6a1e 100644 --- a/src/app/explorer/components/InfiniteScrollGuilds.tsx +++ b/src/app/explorer/components/InfiniteScrollGuilds.tsx @@ -4,22 +4,27 @@ import { Button } from "@/components/ui/Button"; import { env } from "@/lib/env"; import { useInfiniteQuery } from "@tanstack/react-query"; import { useIntersection } from "foxact/use-intersection"; -import { useEffect } from "react"; +import { useSearchParams } from "next/navigation"; +import { useCallback, useEffect } from "react"; import { GuildCard } from "./GuildCard"; const pageSize = 24; -export const InfiniteScrollGuilds = ({ search = "" }: { search?: string }) => { - const fetchGuilds = async ({ pageParam }: { pageParam: number }) => - ( - await fetch( - `${env.NEXT_PUBLIC_API}/guild/search?page=${pageParam}&pageSize=${pageSize}&sortBy=name&reverse=false&search=${search}`, - ) - ).json() as Promise>; +export const InfiniteScrollGuilds = () => { + const searchParams = useSearchParams(); + const fetchGuilds = useCallback( + async ({ pageParam }: { pageParam: number }) => + ( + await fetch( + `${env.NEXT_PUBLIC_API}/guild/search?page=${pageParam}&pageSize=${pageSize}&search=${searchParams?.get("search") || ""}`, + ) + ).json() as Promise>, + [searchParams], + ); const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({ - queryKey: ["guilds"], + queryKey: ["guilds", searchParams.toString()], queryFn: fetchGuilds, initialPageParam: 1, getNextPageParam: (lastPage) => diff --git a/src/app/explorer/components/Search.tsx b/src/app/explorer/components/Search.tsx index 0ef94a52b4..d8e39fa73b 100644 --- a/src/app/explorer/components/Search.tsx +++ b/src/app/explorer/components/Search.tsx @@ -1,3 +1,35 @@ "use client"; -export const Search = () => {}; +import { Input } from "@/components/ui/Input"; +import { useDebouncedValue } from "foxact/use-debounced-value"; +import { usePathname, useRouter, useSearchParams } from "next/navigation"; +import { useEffect, useState } from "react"; + +export const Search = () => { + const router = useRouter(); + const searchParams = useSearchParams(); + const pathname = usePathname(); + const [value, setValue] = useState( + searchParams?.get("search")?.toString() || "", + ); + const _debouncedValue = useDebouncedValue(value, 200); + + useEffect(() => { + const newSearchParams = new URLSearchParams( + Object.entries({ search: value }).filter(([_, value]) => value), + ); + + router.replace(`${pathname}?${newSearchParams.toString()}`, { + scroll: false, + }); + }, [value]); + + return ( + setValue(e.currentTarget.value)} + /> + ); +}; diff --git a/src/app/explorer/page.tsx b/src/app/explorer/page.tsx index 991f73753f..e67ca39797 100644 --- a/src/app/explorer/page.tsx +++ b/src/app/explorer/page.tsx @@ -1,13 +1,13 @@ import { AuthBoundary } from "@/components/AuthBoundary"; import { Button } from "@/components/ui/Button"; import { Card } from "@/components/ui/Card"; -import { Input } from "@/components/ui/Input"; import { Skeleton } from "@/components/ui/Skeleton"; import { env } from "@/lib/env"; import { Plus, SignIn } from "@phosphor-icons/react/dist/ssr"; import { Suspense } from "react"; import { GuildCard } from "./components/GuildCard"; import { InfiniteScrollGuilds } from "./components/InfiniteScrollGuilds"; +import { Search } from "./components/Search"; const getAssociatedGuilds = async () => { const request = `${env.NEXT_PUBLIC_API}/guild/search?page=1&pageSize=24&sortBy=name&reverse=false&search=`; @@ -35,8 +35,8 @@ export default function Explorer() { -
- +
+