How to handle search queries?
Answered
evandabest posted this in #help-forum
Okay so I am trying to make a page where you can search for usernames and render the search results after. I don't know how to approach this. Do I redirect the user to a new page? Do conditionally render a component?
this is the main page:
this is the main page:
"use server"
import { Input } from "@/components/ui/input";
import { handleSearch } from "./actions";
import { Button } from "@/components/ui/button";
import { redirect } from "next/navigation";
import Searches from "./searches";
const search : ({}: any) => Promise<JSX.Element> = async ({}) => {
const handleSearches = async (event: any) => {
event.preventDefault();
const form = new FormData(event.target);
const userName = form.get('userName') as string; // Extract the value of the input field
if (!userName) {
return;
}
const response = await handleSearch(userName); // Pass the value to the handleSearch function
return response;
}
const getSearch = async (prop: any) => {
const Searches: any[][] = await prop;
return Searches;
}
return (
<div>
<h1>Search Page</h1>
<form >
<Input placeholder="Search" id="userName" name="userName" type="userName" required/>
<Button formAction = {handleSearch} type="submit">Search</Button>
</form>
</div>
)
}
export default search;Answered by Turkish Van
In case You want user to type first and then press
You could handle
Then You would have a separate page, page that user gets redirected to, that could look just like
enter or Search button after which he would be redirected to new page with all the users listed that match the searched term, You could have a form with an appropriate input that takes users input.You could handle
form element submit by assigning a server action as its action property. That server action can look just as a fetchUsersSearch function from above, just make sure to make it a server action. Take a look at docs if needed.Then You would have a separate page, page that user gets redirected to, that could look just like
UsersList component from above.9 Replies
this is the actions.ts where the handleSearch function is
(in a previous attempt, I tried to redirect to a new page)
This is the search component (theres nothing right now but there would be a map function over the array of users returned)
Help me plz 🙏🏼
import { createClient } from "@/utils/supabase/server"
import { redirect } from "next/navigation";
export async function handleSearch(form:string ) {
const supabase = createClient();
const response = await supabase.from('profiles').select('*').ilike('username', `%${form}%`);
const results = [];
console.log(response);
if (response.error) {
console.log(response.error);
return { error: response.error };
} else {
results.push(response.data);
}
return { data: results };
}(in a previous attempt, I tried to redirect to a new page)
This is the search component (theres nothing right now but there would be a map function over the array of users returned)
const Searches: React.FC<any> = (prop : any) => {
return (
<div>
<h1>Searches</h1>
</div>
)
}
export default Searches;Help me plz 🙏🏼
Turkish Van
You can store Your users typed search inside of URL as a
Let's say You have a search input and bunch of usernames listed below it as a list.
If You want to achieve to have them filtered just as You type in Your search input, it might look like this:
Your page/component:
searchParam.Let's say You have a search input and bunch of usernames listed below it as a list.
If You want to achieve to have them filtered just as You type in Your search input, it might look like this:
Your page/component:
import Search from "@/components/Search";
import {Suspense} from "react";
import UsersList from "@/components/UsersList";
const Page = ({searchParams}: {searchParams?: {query?: string}}) => {
const query = searchParams?.query || "";
return (
<div>
<Search />
<Suspense key={query} fallback={<p>Loading</p>}>
<UsersList query={query} />
</Suspense>
</div>
);
};
export default Page;Search component:"use client";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useDebouncedCallback } from "use-debounce";
const Search = () => {
const searchParams = useSearchParams();
const pathname = usePathname();
const { replace } = useRouter();
const handleSearch = useDebouncedCallback((term: string) => {
const params = new URLSearchParams(searchParams);
params.delete("page");
if (term) {
params.set("query", term);
} else {
params.delete("query");
}
replace(`${pathname}?${params.toString()}`);
}, 300);
return (
<div className='relative flex flex-1 flex-shrink-0'>
<label htmlFor='search' className='sr-only'>
Search
</label>
<input
placeholder={'Search usernames'}
onChange={(e) => handleSearch(e.target.value)}
defaultValue={searchParams.get("query")?.toString()}
/>
</div>
);
}
export default Search;UsersList component:const UsersList = async ({query}: {query: string}) => {
const {data: users} = await fetchUsersSearch(query);
return (
<div>
{users.map(user => (
<h1 key={user.id}>{user.username}</h1>
))}
</div>
);
};
export default UsersList;fetchUsersSearch function:const fetchUsersSearch = async (query: string) => {
const supabase = createClient();
const {data, error} = await supabase.from('profiles').select('*').ilike('username', `%${query}%`);
return {data, error};
}Turkish Van
In case You want user to type first and then press
You could handle
Then You would have a separate page, page that user gets redirected to, that could look just like
enter or Search button after which he would be redirected to new page with all the users listed that match the searched term, You could have a form with an appropriate input that takes users input.You could handle
form element submit by assigning a server action as its action property. That server action can look just as a fetchUsersSearch function from above, just make sure to make it a server action. Take a look at docs if needed.Then You would have a separate page, page that user gets redirected to, that could look just like
UsersList component from above.Answer
Bro you are actually so goated
Thank you so much
@evandabest Thank you so much
Turkish Van
Make sure to mark it as answered, so thread gets closed.
Glad to help!
Glad to help!