feat(platform): Updates to Search page (#8769)

Updates to search page
This commit is contained in:
Bently
2024-11-27 10:55:51 +00:00
committed by GitHub
parent d4b69d864f
commit c1c3fd4982
4 changed files with 161 additions and 26 deletions

View File

@@ -3,49 +3,70 @@ import { AgentsSection } from "@/components/agptui/composite/AgentsSection";
import { SearchBar } from "@/components/agptui/SearchBar";
import { FeaturedCreators } from "@/components/agptui/composite/FeaturedCreators";
import { Separator } from "@/components/ui/separator";
import { FilterChips } from "@/components/agptui/FilterChips";
import { SearchFilterChips } from "@/components/agptui/SearchFilterChips";
import { SortDropdown } from "@/components/agptui/SortDropdown";
export default async function Page({
params,
searchParams,
}: {
params: { lang: string };
searchParams: { searchTerm?: string };
searchParams: { searchTerm?: string; sort?: string };
}) {
const search_term = searchParams.searchTerm || "";
const sort = searchParams.sort || "trending";
const api = new AutoGPTServerAPIServerSide();
const { agents } = await api.getStoreAgents({ search_query: search_term });
const { agents } = await api.getStoreAgents({
search_query: search_term,
sort: sort
});
const { creators } = await api.getStoreCreators({
search_query: search_term,
});
const handleFilterChange = (selectedFilters: string[]) => {
console.log(selectedFilters);
};
const agentsCount = agents?.length || 0;
const creatorsCount = creators?.length || 0;
const totalCount = agentsCount + creatorsCount;
return (
<div>
<div className="flex items-center justify-between">
<div className="flex flex-col">
<h2 className="font-['Geist'] text-base font-medium leading-normal">
Results for:
</h2>
<h1 className="font-['Poppins'] text-2xl font-semibold leading-loose">
{search_term}
</h1>
<div className="w-full bg-white">
<div className="px-10 max-w-[1440px] mx-auto">
<div className="flex items-center justify-between mt-8">
<div className="flex flex-col">
<h2 className="font-['Geist'] text-base font-medium text-neutral-800">
Results for:
</h2>
<h1 className="font-['Poppins'] text-2xl font-semibold text-neutral-800">
{search_term}
</h1>
</div>
<div>
<SearchBar width="w-[439px]" />
</div>
</div>
<div className="w-32 px-6 py-3.5">
<SearchBar />
<div className="mt-8 flex justify-between items-center">
<SearchFilterChips
totalCount={totalCount}
agentsCount={agentsCount}
creatorsCount={creatorsCount}
/>
<SortDropdown />
</div>
<div className="mt-6">
<h2 className="text-neutral-800 text-lg font-semibold font-['Poppins'] mb-4">Agents</h2>
<AgentsSection agents={agents} sectionTitle="Search Results" />
</div>
<Separator className="my-6" />
<div className="mb-8">
<h2 className="text-neutral-800 text-lg font-semibold font-['Poppins'] mb-4">Creators</h2>
<FeaturedCreators featuredCreators={creators} />
</div>
</div>
<div className="flex justify-between">
{/* TODO: Add filter chips */}
{/* <FilterChips badges={["All", "Agents", "Creators"]} onFilterChange={handleFilterChange} /> */}
<div className="w-32 px-6 py-3.5">Sort By</div>
</div>
<AgentsSection agents={agents} sectionTitle="Search Results" />
<Separator />
<FeaturedCreators featuredCreators={creators} />
</div>
);
}

View File

@@ -11,6 +11,7 @@ interface SearchBarProps {
iconColor?: string;
textColor?: string;
placeholderColor?: string;
width?: string;
}
/** SearchBar component for user input and search functionality. */
@@ -20,6 +21,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
iconColor = "text-[#646464]",
textColor = "text-[#707070]",
placeholderColor = "text-[#707070]",
width = "w-9/10 lg:w-[56.25rem]",
}) => {
const router = useRouter();
@@ -39,7 +41,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
return (
<form
onSubmit={handleSubmit}
className="w-9/10 lg:w-[56.25rem]"
className={width}
data-testid="store-search-bar"
>
<div

View File

@@ -0,0 +1,57 @@
"use client";
import * as React from "react";
interface FilterOption {
label: string;
count: number;
value: string;
}
interface SearchFilterChipsProps {
totalCount?: number;
agentsCount?: number;
creatorsCount?: number;
}
export const SearchFilterChips: React.FC<SearchFilterChipsProps> = ({
totalCount = 10,
agentsCount = 8,
creatorsCount = 2,
}) => {
const [selected, setSelected] = React.useState("all");
const filters: FilterOption[] = [
{ label: "All", count: totalCount, value: "all" },
{ label: "Agents", count: agentsCount, value: "agents" },
{ label: "Creators", count: creatorsCount, value: "creators" },
];
const handleFilterClick = (value: string) => {
setSelected(value);
console.log(`Filter selected: ${value}`);
};
return (
<div className="flex gap-2.5">
{filters.map((filter) => (
<button
key={filter.value}
onClick={() => handleFilterClick(filter.value)}
className={`px-5 py-2 rounded-[34px] flex items-center gap-2.5 ${
selected === filter.value
? "bg-neutral-800 text-white"
: "border border-neutral-600 text-neutral-800"
}`}
>
<span className={`text-base ${selected === filter.value ? "font-medium" : ""}`}>
{filter.label}
</span>
<span className={`text-base ${selected === filter.value ? "font-medium" : ""}`}>
{filter.count}
</span>
</button>
))}
</div>
);
};

View File

@@ -0,0 +1,55 @@
"use client";
import * as React from "react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { ChevronDownIcon } from "@radix-ui/react-icons";
const sortOptions: SortOption[] = [
{ label: "Trending", value: "trending" },
{ label: "Most Recent", value: "recent" },
{ label: "Most Popular", value: "popular" },
{ label: "Highest Rated", value: "rating" },
{ label: "Most Runs", value: "runs" },
];
interface SortOption {
label: string;
value: string;
}
export const SortDropdown: React.FC = () => {
const [selected, setSelected] = React.useState(sortOptions[0]);
const handleSelect = (option: SortOption) => {
setSelected(option);
console.log(`Sorting by: ${option.label} (${option.value})`);
};
return (
<DropdownMenu>
<DropdownMenuTrigger className="flex items-center gap-1.5 focus:outline-none">
<span className="text-neutral-800 text-base font-medium">Sort by</span>
<span className="text-neutral-800 text-base font-medium">{selected.label}</span>
<ChevronDownIcon className="h-4 w-4 text-neutral-800" />
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-[200px] bg-white rounded-lg shadow-lg">
{sortOptions.map((option) => (
<DropdownMenuItem
key={option.value}
className={`px-4 py-2 text-base cursor-pointer hover:bg-neutral-100 ${
selected.value === option.value ? "text-neutral-800 font-medium" : "text-neutral-600"
}`}
onClick={() => handleSelect(option)}
>
{option.label}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
);
};