Next.js Discord

Discord Forum

SearchBar For products!

Answered
Nile Crocodile posted this in #help-forum
Open in Discord
Nile CrocodileOP
Hi! I'm building a ecommerce store and am trying to make a Search Bar that works functional with my product/ProductReel. My productReel is made with Payload CMS so there are categories for each project (For example Software, Courses, Design). I would like customers to Search For one of there payload values/categories and it takes them to the /store page and only shows them the value/category they search for.

Here is My Code:

Search-Bar on my homepage/page.tsx:
<div className="mt-6 w-full max-w-md relative">
<input
type="text"
className="mt-2 w-full px-4 py-2 border rounded-full shadow-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 pr-10"
placeholder="Search 'Courses'"
value={searchTerm}
onChange={handleInputChange}
onKeyPress={handleKeyPress} // Added to handle Enter key press
/>
<button
className="absolute right-4 top-7 transform -translate-y-1/2"
onClick={handleSearch}
>
<Search className="text-indigo-500" />
</button>
</div>

Here is an example of my ProductReel in action:
<ProductReel
query={{ sort: "desc", limit: 4 }}
href="/store"
title="Brand New"
/>


If anyone needs any other files lmk ill dm them to u!!! Also thanks for the help!!!!!!
Answered by Nile Crocodile
//Imports Here

export const appRouter = router({
auth: authRouter,
payment: paymentRouter,

getInfiniteProducts: publicProcedure
.input(
z.object({
limit: z.number().min(1).max(100),
cursor: z.number().nullish(),
query: QueryValidator.extend({ search: z.string().optional() }),
})
)
.query(async ({ input }) => {
const { query, cursor } = input;
const { sort, limit, search, ...queryOpts } = query;

const payload = await getPayloadClient();

const parsedQueryOpts: Record<
string,
{ equals: string } | { contains: string; mode?: "insensitive" }
= {};

Object.entries(queryOpts).forEach(([key, value]) => {
parsedQueryOpts[key] = {
equals: value,
};
});

const searchCriteria = [];

if (search) {
searchCriteria.push(
{ name: { contains: search, mode: "insensitive" } },
{ category: { contains: search, mode: "insensitive" } },
{ description: { contains: search, mode: "insensitive" } }
);
}

console.log("Final Query Options:", parsedQueryOpts);

const page = cursor || 1;

const {
docs: items,
hasNextPage,
nextPage,
} = await payload.find({
collection: "products",
where: {
approvedForSale: {
equals: "approved",
},
...(searchCriteria.length > 0 ? { or: searchCriteria } : {}),
...parsedQueryOpts,
},
sort,
depth: 1,
limit,
page,
});

console.log("Payload Query Results:", items);
console.log("Search term was:", search);

return {
items,
nextPage: hasNextPage ? nextPage : null,
};
}),
});

export type AppRouter = typeof appRouter;
View full answer

17 Replies

The reason you didn't got responses to it because there is too much unnecessary info. You could've make multiple paragraphs with 1 paragraph containing the exact issue. if you can do that, I'll be happy to help you!
@"use php" The reason you didn't got responses to it because there is too much unnecessary info. You could've make multiple paragraphs with 1 paragraph containing the exact issue. if you can do that, I'll be happy to help you!
Nile CrocodileOP
I'm a little confused on what you mean! are you taking about the code? or that paragraph explaining what I'm trying to achieve?! Thanks for your help!!!!!!!
See this rules and guidelines
@"use php" See this rules and guidelines
Nile CrocodileOP
Yes sir. Give me one second and Ill have that all to you!
Nile CrocodileOP
1. I'm trying to solve how to make a searchbar that is on my Homepage.tsx. I want this search-bar to work with payloa-cms because that is where all the functionality for my products are. I have some payload values/labels/categories which describe what each product on my store is (I will list those below). I want customers to search for one of these Values/Labels/Categories (Like "Software", "Design", "Courses") and it takes them to the /store and filters them via My code called <ProductReel /> (this is how my products show up on my site). If you have anymore questions about what i'm trying to achieve Just ask! Now ill list all the code!
2. Here is my chucks of code!

Homepage(searchBar):
<div className="mt-6 w-full max-w-md relative">
<input
type="text"
className="mt-2 w-full px-4 py-2 border rounded-full shadow-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 pr-10"
placeholder="Search 'Courses'"
value={searchTerm}
onChange={handleInputChange}
onKeyPress={handleKeyPress} // Added to handle Enter key press
/>
<button
className="absolute right-4 top-7 transform -translate-y-1/2"
onClick={handleSearch}
>
<Search className="text-indigo-500" />
</button>
</div>
Someone might help you soon. I don't use payload cms so I can't help
Nile CrocodileOP
export default function Store() {
const searchParams = useSearchParams();
const searchTerm = searchParams.get("search") || "";

return (
#Unknown Channel
<MaxWidthWrapper>
<ProductReel
query={{ sort: "desc", limit: 20 }}
title="Welcome To The Store"
/>
Values/Labels/Categories:

export const PRODUCT_CATEGORIES = [
{
label: "Software",
value: "sofware" as const,
Featured: [
{
name: "SaaS",
href: "/sell",
productlist: "Marketing, E-commerce, Education, Healthcare, Finance",
},
{
name: "Apps",
href: "/sell",
productlist:
"Social Media & Entertainment, Health & Fitness, Educational, Music, Shopping",
},
{
name: "Dream Favorites",
href: "#",
productlist:
"Shopping, Health & Fitness, Marketing, E-commerce, Educational",
},
],
},
Nile CrocodileOP
/solved
/solve
@Nile Crocodile /solved
which message would you like to mark as solution? (or can you make one explaining!)
It was my App router/Index.js I'll list my code below
Nile CrocodileOP
//Imports Here

export const appRouter = router({
auth: authRouter,
payment: paymentRouter,

getInfiniteProducts: publicProcedure
.input(
z.object({
limit: z.number().min(1).max(100),
cursor: z.number().nullish(),
query: QueryValidator.extend({ search: z.string().optional() }),
})
)
.query(async ({ input }) => {
const { query, cursor } = input;
const { sort, limit, search, ...queryOpts } = query;

const payload = await getPayloadClient();

const parsedQueryOpts: Record<
string,
{ equals: string } | { contains: string; mode?: "insensitive" }
= {};

Object.entries(queryOpts).forEach(([key, value]) => {
parsedQueryOpts[key] = {
equals: value,
};
});

const searchCriteria = [];

if (search) {
searchCriteria.push(
{ name: { contains: search, mode: "insensitive" } },
{ category: { contains: search, mode: "insensitive" } },
{ description: { contains: search, mode: "insensitive" } }
);
}

console.log("Final Query Options:", parsedQueryOpts);

const page = cursor || 1;

const {
docs: items,
hasNextPage,
nextPage,
} = await payload.find({
collection: "products",
where: {
approvedForSale: {
equals: "approved",
},
...(searchCriteria.length > 0 ? { or: searchCriteria } : {}),
...parsedQueryOpts,
},
sort,
depth: 1,
limit,
page,
});

console.log("Payload Query Results:", items);
console.log("Search term was:", search);

return {
items,
nextPage: hasNextPage ? nextPage : null,
};
}),
});

export type AppRouter = typeof appRouter;
Answer
Nile CrocodileOP
What REALLY did it was adding this because Im using components from Payload CMS so just add your product components or whatever you need a searchbar for here

if (search) {
searchCriteria.push(
{ name: { contains: search, mode: "insensitive" } },
{ category: { contains: search, mode: "insensitive" } },
{ description: { contains: search, mode: "insensitive" } }
);
}
@riský done!