mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
add search list in block menu
This commit is contained in:
@@ -18,8 +18,11 @@ const BlockMenuContent: React.FC = () => {
|
||||
<Separator className="h-[1px] w-full text-zinc-300" />
|
||||
|
||||
{/* Content */}
|
||||
{/* BLOCK MENU TODO : search after 3 characters */}
|
||||
{searchQuery ? <BlockMenuSearch /> : <BlockMenuDefault />}
|
||||
{searchQuery ? (
|
||||
<BlockMenuSearch searchQuery={searchQuery} />
|
||||
) : (
|
||||
<BlockMenuDefault />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -16,7 +16,12 @@ const BlockMenuSearchBar: React.FC<BlockMenuSearchBarProps> = ({
|
||||
}) => {
|
||||
const inputRef = useRef(null);
|
||||
return (
|
||||
<div className="flex min-h-[3.5625rem] items-center gap-2.5 px-4">
|
||||
<div
|
||||
className={cn(
|
||||
"flex min-h-[3.5625rem] items-center gap-2.5 px-4",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<Search className="h-6 w-6 text-zinc-700" strokeWidth={2} />
|
||||
<Input
|
||||
ref={inputRef}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Plus } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
@@ -10,7 +11,11 @@ interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
icon_url?: string;
|
||||
}
|
||||
|
||||
const IntegrationBlock: React.FC<Props> = ({
|
||||
interface IntegrationBlockComponent extends React.FC<Props> {
|
||||
Skeleton: React.FC<{ className?: string }>;
|
||||
}
|
||||
|
||||
const IntegrationBlock: IntegrationBlockComponent = ({
|
||||
title,
|
||||
icon_url,
|
||||
description,
|
||||
@@ -61,4 +66,24 @@ const IntegrationBlock: React.FC<Props> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const IntegrationBlockSkeleton = ({ className }: { className?: string }) => {
|
||||
return (
|
||||
<Skeleton
|
||||
className={cn(
|
||||
"flex h-16 w-full min-w-[7.5rem] animate-pulse items-center justify-start gap-3 rounded-[0.75rem] bg-zinc-100 px-[0.875rem] py-[0.625rem]",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<Skeleton className="h-[2.625rem] w-[2.625rem] rounded-[0.5rem] bg-zinc-200" />
|
||||
<div className="flex flex-1 flex-col items-start gap-0.5">
|
||||
<Skeleton className="h-[1.375rem] w-24 rounded bg-zinc-200" />
|
||||
<Skeleton className="h-5 w-32 rounded bg-zinc-200" />
|
||||
</div>
|
||||
<Skeleton className="h-7 w-7 rounded-[0.5rem] bg-zinc-200" />
|
||||
</Skeleton>
|
||||
);
|
||||
};
|
||||
|
||||
IntegrationBlock.Skeleton = IntegrationBlockSkeleton;
|
||||
|
||||
export default IntegrationBlock;
|
||||
|
||||
@@ -7,11 +7,11 @@ const ActionBlocksContent: React.FC = () => {
|
||||
const [blocks, setBlocks] = useState<BlockListType[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
// Update Block Menu fetching
|
||||
useEffect(() => {
|
||||
const fetchBlocks = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// Simulate API call
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
setBlocks(actionBlocksListData);
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// BLOCK MENU TODO: Currently I have hide the scrollbar, but need to add better designed custom scroller
|
||||
|
||||
import React, { useState, useEffect, Fragment } from "react";
|
||||
import Block from "../Block";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -7,7 +5,6 @@ import { Separator } from "@/components/ui/separator";
|
||||
import { allBlocksDataWithCategories } from "../../testing_data";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
// These are Temporary type, need to change it in future
|
||||
type BlockItem = {
|
||||
title: string;
|
||||
description: string;
|
||||
@@ -23,6 +20,7 @@ const AllBlocksContent: React.FC = () => {
|
||||
const [categories, setCategories] = useState<BlockCategory[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
// Update Block Menu fetching
|
||||
useEffect(() => {
|
||||
const fetchBlocks = async () => {
|
||||
setLoading(true);
|
||||
@@ -41,7 +39,7 @@ const AllBlocksContent: React.FC = () => {
|
||||
{[0, 1, 3].map((categoryIndex) => (
|
||||
<Fragment key={categoryIndex}>
|
||||
{categoryIndex > 0 && (
|
||||
<Skeleton className="h-[1px] w-full text-zinc-100" />
|
||||
<Skeleton className="my-4 h-[1px] w-full text-zinc-100" />
|
||||
)}
|
||||
{[0, 1, 2].map((blockIndex) => (
|
||||
<Block.Skeleton key={`${categoryIndex}-${blockIndex}`} />
|
||||
@@ -53,7 +51,7 @@ const AllBlocksContent: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="scrollbar-thumb-rounded h-full overflow-y-scroll pt-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200">
|
||||
<div className="scrollbar-thumb-rounded scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200 h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
{categories.map((category, index) => (
|
||||
<Fragment key={category.name}>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// BLOCK MENU TODO: Fix scrollbar in all states
|
||||
|
||||
import React, { useState } from "react";
|
||||
import BlockMenuSidebar from "./BlockMenuSidebar";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
@@ -13,10 +13,7 @@ const BlockMenuSidebar: React.FC<BlockMenuSidebarProps> = ({
|
||||
setDefaultState,
|
||||
setIntegration,
|
||||
}) => {
|
||||
// BLOCK MENU TODO: We need to fetch the number of Blocks/Integrations/Agents when opening the menu.
|
||||
// Alternatively, this might depend on the strategy we plan in the future.
|
||||
// We'll add a loading state based on the future plan.
|
||||
|
||||
// Update Block Menu fetching
|
||||
return (
|
||||
<div className="space-y-2 p-4">
|
||||
<MenuItem
|
||||
|
||||
@@ -8,10 +8,10 @@ const InputBlocksContent: React.FC = () => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
// Update Block Menu fetching
|
||||
const fetchBlocks = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// Simulate API call
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
setBlocks(inputBlocksListData);
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import IntegrationBlock from "../IntegrationBlock";
|
||||
import {
|
||||
integrationBlocksData,
|
||||
integrationsListData,
|
||||
} from "../../testing_data";
|
||||
|
||||
export interface IntegrationBlockData {
|
||||
title: string;
|
||||
description: string;
|
||||
icon_url: string;
|
||||
}
|
||||
|
||||
interface IntegrationBlocksProps {
|
||||
integration: string;
|
||||
@@ -11,6 +21,28 @@ const IntegrationBlocks: React.FC<IntegrationBlocksProps> = ({
|
||||
integration,
|
||||
setIntegration,
|
||||
}) => {
|
||||
const [blocks, setBlocks] = useState<IntegrationBlockData[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
|
||||
// Update Block Menu fetching
|
||||
useEffect(() => {
|
||||
if (integration) {
|
||||
setIsLoading(true);
|
||||
setTimeout(() => {
|
||||
const foundBlocks = integrationBlocksData[integration] || [];
|
||||
setBlocks(foundBlocks);
|
||||
setIsLoading(false);
|
||||
}, 800);
|
||||
}
|
||||
}, [integration]);
|
||||
|
||||
const getBlockCount = (): number => {
|
||||
const integrationData = integrationsListData.find(
|
||||
(item) => item.title === integration,
|
||||
);
|
||||
return integrationData?.number_of_blocks || 0;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-2.5">
|
||||
<div className="flex items-center justify-between">
|
||||
@@ -32,56 +64,28 @@ const IntegrationBlocks: React.FC<IntegrationBlocksProps> = ({
|
||||
</p>
|
||||
</div>
|
||||
<span className="flex h-[1.375rem] w-[1.6875rem] items-center justify-center rounded-[1.25rem] bg-[#f0f0f0] p-1.5 font-sans text-sm leading-[1.375rem] text-zinc-500 group-disabled:text-zinc-400">
|
||||
{13}
|
||||
{getBlockCount()}
|
||||
</span>
|
||||
</div>
|
||||
{integration == "Twitter Blocks" && (
|
||||
<div className="space-y-3">
|
||||
<IntegrationBlock
|
||||
title={`${integration}: Post tweet`}
|
||||
description="Post tweet on twitter"
|
||||
icon_url="/integrations/x.png"
|
||||
/>
|
||||
<IntegrationBlock
|
||||
title={`${integration}: Delete tweet`}
|
||||
description="Delete tweet on twitter"
|
||||
icon_url="/integrations/x.png"
|
||||
/>
|
||||
<IntegrationBlock
|
||||
title={`${integration}: Update tweet`}
|
||||
description="Update tweet on twitter"
|
||||
icon_url="/integrations/x.png"
|
||||
/>
|
||||
<IntegrationBlock
|
||||
title={`${integration}: Retweet tweet`}
|
||||
description="Retweet tweet on twitter"
|
||||
icon_url="/integrations/x.png"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{integration == "Discord Blocks" && (
|
||||
{isLoading ? (
|
||||
<div className="space-y-3">
|
||||
<IntegrationBlock
|
||||
title={`${integration}: Create`}
|
||||
description="Create message on discord"
|
||||
icon_url="/integrations/discord.png"
|
||||
/>
|
||||
<IntegrationBlock
|
||||
title={`${integration}: Delete`}
|
||||
description="Delete message on discord"
|
||||
icon_url="/integrations/discord.png"
|
||||
/>
|
||||
<IntegrationBlock
|
||||
title={`${integration}: Update`}
|
||||
description="Update message on discord"
|
||||
icon_url="/integrations/discord.png"
|
||||
/>
|
||||
<IntegrationBlock
|
||||
title={`${integration}: Read`}
|
||||
description="Read message on discord"
|
||||
icon_url="/integrations/discord.png"
|
||||
/>
|
||||
{Array(5)
|
||||
.fill(0)
|
||||
.map((_, index) => (
|
||||
<IntegrationBlock.Skeleton key={index} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{blocks.map((block, index) => (
|
||||
<IntegrationBlock
|
||||
key={index}
|
||||
title={block.title}
|
||||
description={block.description}
|
||||
icon_url={block.icon_url}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -19,12 +19,11 @@ const IntegrationList: React.FC<IntegrationListProps> = ({
|
||||
const [integrations, setIntegrations] = useState<IntegrationData[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
|
||||
// Update Block Menu fetching
|
||||
useEffect(() => {
|
||||
// Mock API call to fetch integrations
|
||||
const fetchIntegrations = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
// Simulate network delay
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
|
||||
setIntegrations(integrationsListData);
|
||||
|
||||
@@ -11,9 +11,8 @@ const IntegrationsContent: React.FC<IntegrationsContentProps> = ({
|
||||
integration,
|
||||
setIntegration,
|
||||
}) => {
|
||||
// I am currently comparing the integration with names, in future maybe using ids
|
||||
return (
|
||||
<div className="scrollbar-thumb-rounded h-full overflow-y-scroll pt-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200">
|
||||
<div className="scrollbar-thumb-rounded scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200 h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full px-4 pb-4">
|
||||
{integration == "" ? (
|
||||
<IntegrationList setIntegration={setIntegration} />
|
||||
|
||||
@@ -14,6 +14,7 @@ const MarketplaceAgentsContent: React.FC = () => {
|
||||
const [agents, setAgents] = useState<MarketplaceAgent[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
// Update Block Menu fetching
|
||||
useEffect(() => {
|
||||
const fetchAgents = async () => {
|
||||
try {
|
||||
@@ -41,7 +42,7 @@ const MarketplaceAgentsContent: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="scrollbar-thumb-rounded h-full overflow-y-scroll pt-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200">
|
||||
<div className="scrollbar-thumb-rounded scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200 h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
{agents.map((agent) => (
|
||||
<MarketplaceAgentBlock
|
||||
|
||||
@@ -14,6 +14,7 @@ const MyAgentsContent: React.FC = () => {
|
||||
const [agents, setAgents] = useState<UserAgent[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
// Update Block Menu fetching
|
||||
useEffect(() => {
|
||||
const fetchAgents = async () => {
|
||||
try {
|
||||
@@ -41,7 +42,7 @@ const MyAgentsContent: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="scrollbar-thumb-rounded h-full overflow-y-scroll pt-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200">
|
||||
<div className="scrollbar-thumb-rounded scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200 h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
{agents.map((agent) => (
|
||||
<UGCAgentBlock
|
||||
|
||||
@@ -7,11 +7,11 @@ const OutputBlocksContent: React.FC = () => {
|
||||
const [blocks, setBlocks] = useState<BlockListType[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
// Update Block Menu fetching
|
||||
useEffect(() => {
|
||||
const fetchBlocks = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// Simulate API call
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
setBlocks(outputBlocksListData);
|
||||
} catch (error) {
|
||||
|
||||
@@ -26,10 +26,10 @@ const SuggestionContent: React.FC<SuggestionContentProps> = ({
|
||||
{ title: string; description: string }[] | null
|
||||
>(null);
|
||||
|
||||
// Update Block Menu fetching
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// Create fetch functions that return their respective data
|
||||
const fetchRecentSearches = async (): Promise<string[]> => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
return recentSearchesData;
|
||||
@@ -49,7 +49,6 @@ const SuggestionContent: React.FC<SuggestionContentProps> = ({
|
||||
return topBlocksData;
|
||||
};
|
||||
|
||||
// Fetch all data simultaneously using Promise.all
|
||||
const [
|
||||
recentSearchesDataFetched,
|
||||
integrationsDataFetched,
|
||||
@@ -72,14 +71,14 @@ const SuggestionContent: React.FC<SuggestionContentProps> = ({
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="scrollbar-thumb-rounded h-full overflow-y-scroll pt-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200">
|
||||
<div className="scrollbar-thumb-rounded scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200 h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-6 pb-4">
|
||||
{/* Recent Searches */}
|
||||
<div className="space-y-2.5">
|
||||
<p className="px-4 font-sans text-sm font-medium leading-[1.375rem] text-zinc-800">
|
||||
Recent searches
|
||||
</p>
|
||||
<div className="flex flex-nowrap gap-2 overflow-x-auto scrollbar-hide">
|
||||
<div className="scrollbar-hide flex flex-nowrap gap-2 overflow-x-auto">
|
||||
{recentSearches
|
||||
? recentSearches.map((search, index) => (
|
||||
<SearchHistoryChip
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Plus } from "lucide-react";
|
||||
import { ButtonHTMLAttributes } from "react";
|
||||
|
||||
interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
title?: string;
|
||||
description?: string;
|
||||
ai_name?: string;
|
||||
}
|
||||
|
||||
const AiBlock: React.FC<Props> = ({
|
||||
title,
|
||||
description,
|
||||
className,
|
||||
ai_name,
|
||||
...rest
|
||||
}) => {
|
||||
return (
|
||||
<Button
|
||||
className={cn(
|
||||
"group flex h-[5.625rem] w-full min-w-[7.5rem] items-center justify-start space-x-3 whitespace-normal rounded-[0.75rem] bg-zinc-50 px-[0.875rem] py-[0.625rem] text-start shadow-none hover:bg-zinc-100 focus:ring-0 active:border active:border-zinc-300 active:bg-zinc-100 disabled:pointer-events-none",
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<div className="flex flex-1 flex-col items-start gap-1.5">
|
||||
<span
|
||||
className={cn(
|
||||
"line-clamp-1 font-sans text-sm font-medium leading-[1.375rem] text-zinc-700 group-disabled:text-zinc-400",
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
<span
|
||||
className={cn(
|
||||
"line-clamp-1 font-sans text-xs font-normal leading-5 text-zinc-500 group-disabled:text-zinc-400",
|
||||
)}
|
||||
>
|
||||
{description}
|
||||
</span>
|
||||
<span
|
||||
className={cn(
|
||||
"rounded-[0.75rem] bg-zinc-200 px-[0.5rem] font-sans text-xs leading-[1.25rem] text-zinc-500",
|
||||
)}
|
||||
>
|
||||
Supports {ai_name}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
"flex h-7 w-7 items-center justify-center rounded-[0.5rem] bg-zinc-700 group-disabled:bg-zinc-400",
|
||||
)}
|
||||
>
|
||||
<Plus className="h-5 w-5 text-zinc-50" strokeWidth={2} />
|
||||
</div>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export default AiBlock;
|
||||
@@ -1,9 +1,14 @@
|
||||
import React from "react";
|
||||
import FiltersList from "./FiltersList";
|
||||
import SearchList from "./SearchList.";
|
||||
|
||||
const BlockMenuSearch: React.FC = () => {
|
||||
const BlockMenuSearch: React.FC<{ searchQuery: string }> = ({
|
||||
searchQuery,
|
||||
}) => {
|
||||
return (
|
||||
<div className="p-4">
|
||||
<h2>Filter Block Menu</h2>
|
||||
<div className="scrollbar-thumb-rounded scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200 h-full space-y-4 overflow-y-scroll p-4">
|
||||
<FiltersList />
|
||||
<SearchList searchQuery={searchQuery} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import FilterChip from "../FilterChip";
|
||||
|
||||
const FiltersList = () => {
|
||||
return (
|
||||
<div className="space-x-3">
|
||||
<FilterChip name="All filters" />
|
||||
{/* Created by filters */}
|
||||
|
||||
{/* Fixed filters */}
|
||||
<FilterChip name="Blocks" />
|
||||
<FilterChip name="Integrations" />
|
||||
<FilterChip name="Marketplace agents" />
|
||||
<FilterChip name="My agents" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FiltersList;
|
||||
@@ -0,0 +1,153 @@
|
||||
import { marketplaceAgentData, searchingData } from "../../testing_data";
|
||||
import { useEffect, useState } from "react";
|
||||
import MarketplaceAgentBlock from "../MarketplaceAgentBlock";
|
||||
import Block from "../Block";
|
||||
import UGCAgentBlock from "../UGCAgentBlock";
|
||||
import AiBlock from "./AiBlock";
|
||||
import IntegrationBlock from "../IntegrationBlock";
|
||||
|
||||
interface BaseSearchItem {
|
||||
type: "marketing_agent" | "integration_block" | "block" | "my_agent" | "ai";
|
||||
}
|
||||
|
||||
interface MarketingAgentItem extends BaseSearchItem {
|
||||
type: "marketing_agent";
|
||||
title: string;
|
||||
image_url: string;
|
||||
creator_name: string;
|
||||
number_of_runs: number;
|
||||
}
|
||||
|
||||
interface AIItem extends BaseSearchItem {
|
||||
type: "ai";
|
||||
title: string;
|
||||
description: string;
|
||||
ai_name: string;
|
||||
}
|
||||
|
||||
interface BlockItem extends BaseSearchItem {
|
||||
type: "block";
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
interface IntegrationItem extends BaseSearchItem {
|
||||
type: "integration_block";
|
||||
title: string;
|
||||
description: string;
|
||||
icon_url: string;
|
||||
number_of_blocks: number;
|
||||
}
|
||||
|
||||
interface MyAgentItem extends BaseSearchItem {
|
||||
type: "my_agent";
|
||||
title: string;
|
||||
image_url: string;
|
||||
edited_time: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export type SearchItem =
|
||||
| MarketingAgentItem
|
||||
| AIItem
|
||||
| BlockItem
|
||||
| IntegrationItem
|
||||
| MyAgentItem;
|
||||
|
||||
const SearchList = ({ searchQuery }: { searchQuery: string }) => {
|
||||
const [searchData, setSearchData] = useState<SearchItem[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1500));
|
||||
setSearchData(searchingData as SearchItem[]);
|
||||
} catch (error) {
|
||||
console.error("Error fetching search data:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, [searchQuery]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="space-y-2.5">
|
||||
<p className="font-sans text-sm font-medium leading-[1.375rem] text-zinc-800">
|
||||
Search results
|
||||
</p>
|
||||
{Array(6)
|
||||
.fill(0)
|
||||
.map(() => (
|
||||
<Block.Skeleton />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-2.5">
|
||||
<p className="font-sans text-sm font-medium leading-[1.375rem] text-zinc-800">
|
||||
Search results
|
||||
</p>
|
||||
{searchData.map((item: SearchItem, index: number) => {
|
||||
switch (item.type) {
|
||||
case "marketing_agent":
|
||||
return (
|
||||
<MarketplaceAgentBlock
|
||||
key={index}
|
||||
title={item.title}
|
||||
image_url={item.image_url}
|
||||
creator_name={item.creator_name}
|
||||
number_of_runs={item.number_of_runs}
|
||||
/>
|
||||
);
|
||||
case "block":
|
||||
return (
|
||||
<Block
|
||||
key={index}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
/>
|
||||
);
|
||||
case "integration_block":
|
||||
return (
|
||||
<IntegrationBlock
|
||||
key={index}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
icon_url={item.icon_url}
|
||||
/>
|
||||
);
|
||||
case "my_agent":
|
||||
return (
|
||||
<UGCAgentBlock
|
||||
key={index}
|
||||
title={item.title}
|
||||
image_url={item.image_url}
|
||||
version={item.version}
|
||||
edited_time={item.edited_time}
|
||||
/>
|
||||
);
|
||||
case "ai":
|
||||
return (
|
||||
<AiBlock
|
||||
key={index}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
ai_name={item.ai_name}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchList;
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
import { BlockCategory } from "./block-menu/default/AllBlocksContent";
|
||||
import { BlockListType } from "./block-menu/default/BlockMenuDefaultContent";
|
||||
import { IntegrationBlockData } from "./block-menu/default/IntegrationBlocks";
|
||||
import { IntegrationData } from "./block-menu/default/IntegrationList";
|
||||
import { MarketplaceAgent } from "./block-menu/default/MarketplaceAgentsContent";
|
||||
import { UserAgent } from "./block-menu/default/MyAgentsContent";
|
||||
import { SearchItem } from "./block-menu/search-and-filter/SearchList.";
|
||||
|
||||
// Suggestion
|
||||
|
||||
@@ -207,44 +209,44 @@ export const outputBlocksListData: BlockListType[] = [
|
||||
|
||||
export const integrationsListData: IntegrationData[] = [
|
||||
{
|
||||
title: "Twitter Blocks",
|
||||
title: "Twitter",
|
||||
icon_url: "/integrations/x.png",
|
||||
description:
|
||||
"All twitter blocks, It has everthing to interact with twitter",
|
||||
number_of_blocks: 10,
|
||||
number_of_blocks: 4,
|
||||
},
|
||||
{
|
||||
title: "Discord Blocks",
|
||||
title: "Discord",
|
||||
icon_url: "/integrations/discord.png",
|
||||
description:
|
||||
"All Discord blocks, It has everthing to interact with discord",
|
||||
number_of_blocks: 14,
|
||||
number_of_blocks: 4,
|
||||
},
|
||||
{
|
||||
title: "Github Blocks",
|
||||
title: "Github",
|
||||
icon_url: "/integrations/github.png",
|
||||
description: "All Github blocks, It has everthing to interact with github",
|
||||
number_of_blocks: 4,
|
||||
},
|
||||
{
|
||||
title: "Hubspot Blocks",
|
||||
title: "Hubspot",
|
||||
icon_url: "/integrations/hubspot.png",
|
||||
description:
|
||||
"All Hubspot blocks, It has everthing to interact with Hubspot",
|
||||
number_of_blocks: 2,
|
||||
},
|
||||
{
|
||||
title: "Medium Blocks",
|
||||
title: "Medium",
|
||||
icon_url: "/integrations/medium.png",
|
||||
description: "All Medium blocks, It has everything to interact with Medium",
|
||||
number_of_blocks: 6,
|
||||
number_of_blocks: 4,
|
||||
},
|
||||
{
|
||||
title: "Todoist Blocks",
|
||||
title: "Todoist",
|
||||
icon_url: "/integrations/todoist.png",
|
||||
description:
|
||||
"All Todoist blocks, It has everything to interact with Todoist",
|
||||
number_of_blocks: 8,
|
||||
number_of_blocks: 4,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -358,3 +360,183 @@ export const myAgentData: UserAgent[] = [
|
||||
image_url: "/placeholder.png",
|
||||
},
|
||||
];
|
||||
|
||||
export const integrationBlocksData: Record<string, IntegrationBlockData[]> = {
|
||||
Twitter: [
|
||||
{
|
||||
title: "Twitter Blocks: Post tweet",
|
||||
description: "Post tweet on twitter",
|
||||
icon_url: "/integrations/x.png",
|
||||
},
|
||||
{
|
||||
title: "Twitter Blocks: Delete tweet",
|
||||
description: "Delete tweet on twitter",
|
||||
icon_url: "/integrations/x.png",
|
||||
},
|
||||
{
|
||||
title: "Twitter Blocks: Update tweet",
|
||||
description: "Update tweet on twitter",
|
||||
icon_url: "/integrations/x.png",
|
||||
},
|
||||
{
|
||||
title: "Twitter Blocks: Retweet tweet",
|
||||
description: "Retweet tweet on twitter",
|
||||
icon_url: "/integrations/x.png",
|
||||
},
|
||||
],
|
||||
Discord: [
|
||||
{
|
||||
title: "Discord Blocks: Create",
|
||||
description: "Create message on discord",
|
||||
icon_url: "/integrations/discord.png",
|
||||
},
|
||||
{
|
||||
title: "Discord Blocks: Delete",
|
||||
description: "Delete message on discord",
|
||||
icon_url: "/integrations/discord.png",
|
||||
},
|
||||
{
|
||||
title: "Discord Blocks: Update",
|
||||
description: "Update message on discord",
|
||||
icon_url: "/integrations/discord.png",
|
||||
},
|
||||
{
|
||||
title: "Discord Blocks: Read",
|
||||
description: "Read message on discord",
|
||||
icon_url: "/integrations/discord.png",
|
||||
},
|
||||
],
|
||||
Github: [
|
||||
{
|
||||
title: "Github Blocks: Create PR",
|
||||
description: "Create pull request on github",
|
||||
icon_url: "/integrations/github.png",
|
||||
},
|
||||
{
|
||||
title: "Github Blocks: Merge PR",
|
||||
description: "Merge pull request on github",
|
||||
icon_url: "/integrations/github.png",
|
||||
},
|
||||
],
|
||||
Hubspot: [
|
||||
{
|
||||
title: "Hubspot Blocks: Create Contact",
|
||||
description: "Create contact on hubspot",
|
||||
icon_url: "/integrations/hubspot.png",
|
||||
},
|
||||
{
|
||||
title: "Hubspot Blocks: Update Contact",
|
||||
description: "Update contact on hubspot",
|
||||
icon_url: "/integrations/hubspot.png",
|
||||
},
|
||||
],
|
||||
Medium: [
|
||||
{
|
||||
title: "Medium Blocks: Post Article",
|
||||
description: "Post article on medium",
|
||||
icon_url: "/integrations/medium.png",
|
||||
},
|
||||
{
|
||||
title: "Medium Blocks: Delete Article",
|
||||
description: "Delete article on medium",
|
||||
icon_url: "/integrations/medium.png",
|
||||
},
|
||||
],
|
||||
Todoist: [
|
||||
{
|
||||
title: "Todoist Blocks: Create Task",
|
||||
description: "Create task on todoist",
|
||||
icon_url: "/integrations/todoist.png",
|
||||
},
|
||||
{
|
||||
title: "Todoist Blocks: Complete Task",
|
||||
description: "Complete task on todoist",
|
||||
icon_url: "/integrations/todoist.png",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const searchingData: SearchItem[] = [
|
||||
{
|
||||
type: "marketing_agent" as const,
|
||||
title: marketplaceAgentData[0].title,
|
||||
image_url: marketplaceAgentData[0].image_url,
|
||||
creator_name: marketplaceAgentData[0].creator_name,
|
||||
number_of_runs: marketplaceAgentData[0].number_of_runs,
|
||||
},
|
||||
|
||||
{
|
||||
type: "ai",
|
||||
title: "Natural Language Processing",
|
||||
description: "Enables your agent to chat with users in natural language.",
|
||||
ai_name: "Claude 3.5 Sonnet",
|
||||
},
|
||||
|
||||
{
|
||||
type: "integration_block" as const,
|
||||
title: integrationsListData[0].title,
|
||||
description: integrationsListData[0].description,
|
||||
icon_url: integrationsListData[0].icon_url,
|
||||
number_of_blocks: integrationsListData[0].number_of_blocks,
|
||||
},
|
||||
|
||||
{
|
||||
type: "marketing_agent" as const,
|
||||
title: marketplaceAgentData[1].title,
|
||||
image_url: marketplaceAgentData[1].image_url,
|
||||
creator_name: marketplaceAgentData[1].creator_name,
|
||||
number_of_runs: marketplaceAgentData[1].number_of_runs,
|
||||
},
|
||||
|
||||
{
|
||||
type: "block" as const,
|
||||
title: topBlocksData[0].title,
|
||||
description: topBlocksData[0].description,
|
||||
},
|
||||
|
||||
{
|
||||
type: "my_agent" as const,
|
||||
title: myAgentData[0].title,
|
||||
image_url: myAgentData[0].image_url,
|
||||
edited_time: myAgentData[0].edited_time,
|
||||
version: myAgentData[0].version,
|
||||
},
|
||||
|
||||
{
|
||||
type: "ai",
|
||||
title: "Sentiment Analysis",
|
||||
description:
|
||||
"Analyzes the sentiment of user messages to respond appropriately.",
|
||||
ai_name: "Claude 3.5 Sonnet",
|
||||
},
|
||||
|
||||
{
|
||||
type: "block" as const,
|
||||
title: topBlocksData[1].title,
|
||||
description: topBlocksData[1].description,
|
||||
},
|
||||
|
||||
{
|
||||
type: "marketing_agent" as const,
|
||||
title: marketplaceAgentData[2].title,
|
||||
image_url: marketplaceAgentData[2].image_url,
|
||||
creator_name: marketplaceAgentData[2].creator_name,
|
||||
number_of_runs: marketplaceAgentData[2].number_of_runs,
|
||||
},
|
||||
|
||||
{
|
||||
type: "integration_block" as const,
|
||||
title: integrationsListData[1].title,
|
||||
description: integrationsListData[1].description,
|
||||
icon_url: integrationsListData[1].icon_url,
|
||||
number_of_blocks: integrationsListData[1].number_of_blocks,
|
||||
},
|
||||
|
||||
{
|
||||
type: "my_agent" as const,
|
||||
title: myAgentData[1].title,
|
||||
image_url: myAgentData[1].image_url,
|
||||
edited_time: myAgentData[1].edited_time,
|
||||
version: myAgentData[1].version,
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user