mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
Add skeleton components and loading states
This commit is contained in:
@@ -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 React, { ButtonHTMLAttributes } from "react";
|
||||
@@ -8,7 +9,11 @@ interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
description?: string;
|
||||
}
|
||||
|
||||
const Block: React.FC<Props> = ({ title, description, className, ...rest }) => {
|
||||
interface BlockComponent extends React.FC<Props> {
|
||||
Skeleton: React.FC<{ className?: string }>;
|
||||
}
|
||||
|
||||
const Block: BlockComponent = ({ title, description, className, ...rest }) => {
|
||||
return (
|
||||
<Button
|
||||
className={cn(
|
||||
@@ -43,4 +48,18 @@ const Block: React.FC<Props> = ({ title, description, className, ...rest }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const BlockSkeleton = () => {
|
||||
return (
|
||||
<Skeleton className="flex h-16 w-full min-w-[7.5rem] animate-pulse items-center justify-start space-x-3 rounded-[0.75rem] bg-zinc-100 px-[0.875rem] py-[0.625rem]">
|
||||
<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>
|
||||
);
|
||||
};
|
||||
|
||||
Block.Skeleton = BlockSkeleton;
|
||||
|
||||
export default Block;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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";
|
||||
import React, { ButtonHTMLAttributes } from "react";
|
||||
|
||||
@@ -11,7 +11,11 @@ interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
number_of_blocks?: number;
|
||||
}
|
||||
|
||||
const Integration: React.FC<Props> = ({
|
||||
interface IntegrationComponent extends React.FC<Props> {
|
||||
Skeleton: React.FC<{ className?: string }>;
|
||||
}
|
||||
|
||||
const Integration: IntegrationComponent = ({
|
||||
title,
|
||||
icon_url,
|
||||
description,
|
||||
@@ -23,6 +27,7 @@ const Integration: React.FC<Props> = ({
|
||||
<Button
|
||||
className={cn(
|
||||
"group flex h-16 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-50 disabled:pointer-events-none",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
@@ -54,4 +59,28 @@ const Integration: React.FC<Props> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const IntegrationSkeleton: React.FC<{ className?: string }> = ({
|
||||
className,
|
||||
}) => {
|
||||
return (
|
||||
<Skeleton
|
||||
className={cn(
|
||||
"flex h-16 w-full min-w-[7.5rem] animate-pulse items-center justify-start space-x-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">
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<Skeleton className="h-[1.375rem] w-24 rounded bg-zinc-200" />
|
||||
<Skeleton className="h-[1.375rem] w-[1.6875rem] rounded-[1.25rem] bg-zinc-200" />
|
||||
</div>
|
||||
<Skeleton className="h-5 w-[80%] rounded bg-zinc-200" />
|
||||
</div>
|
||||
</Skeleton>
|
||||
);
|
||||
};
|
||||
|
||||
Integration.Skeleton = IntegrationSkeleton;
|
||||
|
||||
export default Integration;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
import Image from "next/image";
|
||||
import React, { ButtonHTMLAttributes } from "react";
|
||||
@@ -8,7 +9,12 @@ interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
icon_url?: string;
|
||||
}
|
||||
|
||||
const IntegrationChip: React.FC<Props> = ({
|
||||
// Define the component type with Skeleton property
|
||||
interface IntegrationChipComponent extends React.FC<Props> {
|
||||
Skeleton: React.FC;
|
||||
}
|
||||
|
||||
const IntegrationChip: IntegrationChipComponent = ({
|
||||
icon_url,
|
||||
name,
|
||||
className,
|
||||
@@ -39,4 +45,16 @@ const IntegrationChip: React.FC<Props> = ({
|
||||
);
|
||||
};
|
||||
|
||||
// Skeleton subcomponent
|
||||
const IntegrationChipSkeleton: React.FC = () => {
|
||||
return (
|
||||
<Skeleton className="flex h-[3.25rem] w-full min-w-[7.5rem] gap-2 rounded-[0.5rem] bg-zinc-100 p-2 pr-3">
|
||||
<Skeleton className="h-9 w-12 rounded-[0.5rem] bg-zinc-200" />
|
||||
<Skeleton className="h-5 w-24 self-center rounded-sm bg-zinc-200" />
|
||||
</Skeleton>
|
||||
);
|
||||
};
|
||||
|
||||
IntegrationChip.Skeleton = IntegrationChipSkeleton;
|
||||
|
||||
export default IntegrationChip;
|
||||
|
||||
@@ -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";
|
||||
@@ -11,7 +12,11 @@ interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
image_url?: string;
|
||||
}
|
||||
|
||||
const MarketplaceAgentBlock: React.FC<Props> = ({
|
||||
interface MarketplaceAgentBlockComponent extends React.FC<Props> {
|
||||
Skeleton: React.FC<{ className?: string }>;
|
||||
}
|
||||
|
||||
const MarketplaceAgentBlock: MarketplaceAgentBlockComponent = ({
|
||||
title,
|
||||
image_url,
|
||||
creator_name,
|
||||
@@ -23,6 +28,7 @@ const MarketplaceAgentBlock: React.FC<Props> = ({
|
||||
<Button
|
||||
className={cn(
|
||||
"group flex h-[4.375rem] w-full min-w-[7.5rem] items-center justify-start gap-3 whitespace-normal rounded-[0.75rem] bg-zinc-50 p-[0.625rem] pr-[0.875rem] 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",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
@@ -75,4 +81,30 @@ const MarketplaceAgentBlock: React.FC<Props> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const MarketplaceAgentBlockSkeleton: React.FC<{ className?: string }> = ({
|
||||
className,
|
||||
}) => {
|
||||
return (
|
||||
<Skeleton
|
||||
className={cn(
|
||||
"flex h-[4.375rem] w-full min-w-[7.5rem] animate-pulse items-center justify-start gap-3 rounded-[0.75rem] bg-zinc-100 p-[0.625rem] pr-[0.875rem]",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<Skeleton className="h-[3.125rem] w-[5.625rem] rounded-[0.375rem] 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" />
|
||||
<div className="flex items-center gap-1">
|
||||
<Skeleton className="h-5 w-16 rounded bg-zinc-200" />
|
||||
|
||||
<Skeleton className="h-5 w-16 rounded bg-zinc-200" />
|
||||
</div>
|
||||
</div>
|
||||
<Skeleton className="h-7 w-7 rounded-[0.5rem] bg-zinc-200" />
|
||||
</Skeleton>
|
||||
);
|
||||
};
|
||||
|
||||
MarketplaceAgentBlock.Skeleton = MarketplaceAgentBlockSkeleton;
|
||||
|
||||
export default MarketplaceAgentBlock;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ArrowUpRight } from "lucide-react";
|
||||
import React, { ButtonHTMLAttributes } from "react";
|
||||
@@ -7,7 +8,11 @@ interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
content?: string;
|
||||
}
|
||||
|
||||
const SearchHistoryChip: React.FC<Props> = ({
|
||||
interface SearchHistoryChipComponent extends React.FC<Props> {
|
||||
Skeleton: React.FC<{ className?: string }>;
|
||||
}
|
||||
|
||||
const SearchHistoryChip: SearchHistoryChipComponent = ({
|
||||
content,
|
||||
className,
|
||||
...rest
|
||||
@@ -28,4 +33,16 @@ const SearchHistoryChip: React.FC<Props> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const SearchHistoryChipSkeleton: React.FC<{ className?: string }> = ({
|
||||
className,
|
||||
}) => {
|
||||
return (
|
||||
<Skeleton
|
||||
className={cn("h-[2.25rem] w-32 rounded-[1.5rem] bg-zinc-100", className)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
SearchHistoryChip.Skeleton = SearchHistoryChipSkeleton;
|
||||
|
||||
export default SearchHistoryChip;
|
||||
|
||||
@@ -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";
|
||||
@@ -11,7 +12,11 @@ interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
image_url?: string;
|
||||
}
|
||||
|
||||
const UGCAgentBlock: React.FC<Props> = ({
|
||||
interface UGCAgentBlockComponent extends React.FC<Props> {
|
||||
Skeleton: React.FC<{ className?: string }>;
|
||||
}
|
||||
|
||||
const UGCAgentBlock: UGCAgentBlockComponent = ({
|
||||
title,
|
||||
image_url,
|
||||
edited_time,
|
||||
@@ -23,6 +28,7 @@ const UGCAgentBlock: React.FC<Props> = ({
|
||||
<Button
|
||||
className={cn(
|
||||
"group flex h-[4.375rem] w-full min-w-[7.5rem] items-center justify-start gap-3 whitespace-normal rounded-[0.75rem] bg-zinc-50 p-[0.625rem] pr-[0.875rem] 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",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
@@ -76,4 +82,29 @@ const UGCAgentBlock: React.FC<Props> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const UGCAgentBlockSkeleton: React.FC<{ className?: string }> = ({
|
||||
className,
|
||||
}) => {
|
||||
return (
|
||||
<Skeleton
|
||||
className={cn(
|
||||
"flex h-[4.375rem] w-full min-w-[7.5rem] animate-pulse items-center justify-start gap-3 rounded-[0.75rem] bg-zinc-100 p-[0.625rem] pr-[0.875rem]",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<Skeleton className="h-[3.125rem] w-[5.625rem] rounded-[0.375rem] 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" />
|
||||
<div className="flex items-center gap-1">
|
||||
<Skeleton className="h-5 w-16 rounded bg-zinc-200" />
|
||||
<Skeleton className="h-5 w-16 rounded bg-zinc-200" />
|
||||
</div>
|
||||
</div>
|
||||
<Skeleton className="h-7 w-7 rounded-[0.5rem] bg-zinc-200" />
|
||||
</Skeleton>
|
||||
);
|
||||
};
|
||||
|
||||
UGCAgentBlock.Skeleton = UGCAgentBlockSkeleton;
|
||||
|
||||
export default UGCAgentBlock;
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
import React from "react";
|
||||
import Block from "../Block";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { actionBlocksListData } from "../../testing_data";
|
||||
import { BlockListType } from "./BlockMenuDefaultContent";
|
||||
import BlocksList from "./BlocksList";
|
||||
|
||||
const ActionBlocksContent: React.FC = () => {
|
||||
return (
|
||||
<div className="scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-zinc-200 scrollbar-track-transparent h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
<Block title="Date Input" description="Input a date into your agent." />
|
||||
<Block
|
||||
title="Dropdown input"
|
||||
description="Give your users the ability to select from a dropdown menu"
|
||||
/>
|
||||
<Block title="File upload" description="Upload a file to your agent" />
|
||||
<Block
|
||||
title="Text input"
|
||||
description="Allow users to select multiple options using checkboxes"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const [blocks, setBlocks] = useState<BlockListType[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchBlocks = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// Simulate API call
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
setBlocks(actionBlocksListData);
|
||||
} catch (error) {
|
||||
console.error("Error fetching blocks:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchBlocks();
|
||||
}, []);
|
||||
return <BlocksList blocks={blocks} loading={loading} />;
|
||||
};
|
||||
|
||||
export default ActionBlocksContent;
|
||||
|
||||
@@ -1,119 +1,98 @@
|
||||
// BLOCK MENU TODO: Currently I have hide the scrollbar, but need to add better designed custom scroller
|
||||
|
||||
import React from "react";
|
||||
import React, { useState, useEffect, Fragment } from "react";
|
||||
import Block from "../Block";
|
||||
import { Button } from "@/components/ui/button";
|
||||
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;
|
||||
};
|
||||
|
||||
export type BlockCategory = {
|
||||
name: string;
|
||||
count: number;
|
||||
items: BlockItem[];
|
||||
};
|
||||
|
||||
const AllBlocksContent: React.FC = () => {
|
||||
const [categories, setCategories] = useState<BlockCategory[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchBlocks = async () => {
|
||||
setLoading(true);
|
||||
setTimeout(() => {
|
||||
setCategories(allBlocksDataWithCategories);
|
||||
setLoading(false);
|
||||
}, 800);
|
||||
};
|
||||
|
||||
fetchBlocks();
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="w-full space-y-3 p-4">
|
||||
{[0, 1, 3].map((categoryIndex) => (
|
||||
<Fragment key={categoryIndex}>
|
||||
{categoryIndex > 0 && (
|
||||
<Skeleton className="h-[1px] w-full text-zinc-100" />
|
||||
)}
|
||||
{[0, 1, 2].map((blockIndex) => (
|
||||
<Block.Skeleton key={`${categoryIndex}-${blockIndex}`} />
|
||||
))}
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-zinc-200 scrollbar-track-transparent h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
{/* AI Category */}
|
||||
<div className="space-y-2.5">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="font-sans text-sm font-medium leading-[1.375rem] text-zinc-800">
|
||||
AI
|
||||
</p>
|
||||
<span className="rounded-full bg-zinc-100 px-[0.375rem] font-sans text-sm leading-[1.375rem] text-zinc-600">
|
||||
10
|
||||
</span>
|
||||
</div>
|
||||
{categories.map((category, index) => (
|
||||
<Fragment key={category.name}>
|
||||
{index > 0 && (
|
||||
<Separator className="h-[1px] w-full text-zinc-300" />
|
||||
)}
|
||||
|
||||
<div className="space-y-2">
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
{/* Category Section */}
|
||||
<div className="space-y-2.5">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="font-sans text-sm font-medium leading-[1.375rem] text-zinc-800">
|
||||
{category.name}
|
||||
</p>
|
||||
<span className="rounded-full bg-zinc-100 px-[0.375rem] font-sans text-sm leading-[1.375rem] text-zinc-600">
|
||||
{category.count}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant={"link"}
|
||||
className="px-0 font-sans text-sm leading-[1.375rem] text-zinc-600 underline hover:text-zinc-800"
|
||||
>
|
||||
see all
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{category.items.slice(0, 3).map((item, idx) => (
|
||||
<Block
|
||||
key={`${category.name}-${idx}`}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
/>
|
||||
))}
|
||||
|
||||
<Separator className="h-[1px] w-full text-zinc-300" />
|
||||
|
||||
{/* Basic Category */}
|
||||
<div className="space-y-2.5">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="font-sans text-sm font-medium leading-[1.375rem] text-zinc-800">
|
||||
Basic
|
||||
</p>
|
||||
<span className="rounded-full bg-zinc-100 px-[0.375rem] font-sans text-sm leading-[1.375rem] text-zinc-600">
|
||||
6
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant={"link"}
|
||||
className="px-0 font-sans text-sm leading-[1.375rem] text-zinc-600 underline hover:text-zinc-800"
|
||||
>
|
||||
see all
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Separator className="h-[1px] w-full text-zinc-300" />
|
||||
|
||||
{/* Communincation Category */}
|
||||
<div className="space-y-2.5">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="font-sans text-sm font-medium leading-[1.375rem] text-zinc-800">
|
||||
Communincation
|
||||
</p>
|
||||
<span className="rounded-full bg-zinc-100 px-[0.375rem] font-sans text-sm leading-[1.375rem] text-zinc-600">
|
||||
6
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant={"link"}
|
||||
className="px-0 font-sans text-sm leading-[1.375rem] text-zinc-600 underline hover:text-zinc-800"
|
||||
>
|
||||
see all
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{category.items.length > 3 && (
|
||||
<Button
|
||||
variant={"link"}
|
||||
className="px-0 font-sans text-sm leading-[1.375rem] text-zinc-600 underline hover:text-zinc-800"
|
||||
>
|
||||
see all
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import Block from "../Block";
|
||||
|
||||
interface BlockListSkeletonProps {
|
||||
count?: number;
|
||||
}
|
||||
|
||||
const BlockListSkeleton: React.FC<BlockListSkeletonProps> = ({ count = 3 }) => {
|
||||
return (
|
||||
<>
|
||||
{Array.from({ length: count }).map((_, index) => (
|
||||
<Block.Skeleton key={index} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default BlockListSkeleton;
|
||||
@@ -27,7 +27,6 @@ const BlockMenuDefault: React.FC = () => {
|
||||
defaultState={defaultState}
|
||||
setDefaultState={setDefaultState}
|
||||
setIntegration={setIntegration}
|
||||
integration={integration}
|
||||
/>
|
||||
|
||||
<Separator className="h-full w-[1px] text-zinc-300" />
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import { DefaultStateType } from "./BlockMenuDefault";
|
||||
import SuggestionContent from "./SuggestionContent";
|
||||
import AllBlocksContent from "./AllBlocksContent";
|
||||
import InputBlocksContent from "./InputBlocksContent";
|
||||
import ActionBlocksContent from "./ActionBlocksContent";
|
||||
import OutputBlocksContent from "./OutputBlocksContent";
|
||||
import IntegrationsContent from "./IntegrationsContent";
|
||||
import MarketplaceAgentsContent from "./MarketplaceAgentsContent";
|
||||
import MyAgentsContent from "./MyAgentsContent";
|
||||
import ActionBlocksContent from "./ActionBlocksContent";
|
||||
import InputBlocksContent from "./InputBlocksContent";
|
||||
import OutputBlocksContent from "./OutputBlocksContent";
|
||||
|
||||
interface BlockMenuDefaultContentProps {
|
||||
defaultState: DefaultStateType;
|
||||
@@ -16,6 +16,18 @@ interface BlockMenuDefaultContentProps {
|
||||
setIntegration: React.Dispatch<React.SetStateAction<string>>;
|
||||
}
|
||||
|
||||
export interface ActionBlock {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface BlockListType {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
const BlockMenuDefaultContent: React.FC<BlockMenuDefaultContentProps> = ({
|
||||
defaultState,
|
||||
setDefaultState,
|
||||
@@ -26,7 +38,6 @@ const BlockMenuDefaultContent: React.FC<BlockMenuDefaultContentProps> = ({
|
||||
<div className="h-full flex-1 overflow-hidden">
|
||||
{defaultState == "suggestion" && (
|
||||
<SuggestionContent
|
||||
integration={integration}
|
||||
setIntegration={setIntegration}
|
||||
setDefaultState={setDefaultState}
|
||||
/>
|
||||
|
||||
@@ -5,14 +5,12 @@ import { DefaultStateType } from "./BlockMenuDefault";
|
||||
interface BlockMenuSidebarProps {
|
||||
defaultState: DefaultStateType;
|
||||
setDefaultState: React.Dispatch<React.SetStateAction<DefaultStateType>>;
|
||||
integration: string;
|
||||
setIntegration: React.Dispatch<React.SetStateAction<string>>;
|
||||
}
|
||||
|
||||
const BlockMenuSidebar: React.FC<BlockMenuSidebarProps> = ({
|
||||
defaultState,
|
||||
setDefaultState,
|
||||
integration,
|
||||
setIntegration,
|
||||
}) => {
|
||||
// BLOCK MENU TODO: We need to fetch the number of Blocks/Integrations/Agents when opening the menu.
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import React from "react";
|
||||
import Block from "../Block";
|
||||
import { BlockListType } from "./BlockMenuDefaultContent";
|
||||
|
||||
interface BlocksListProps {
|
||||
blocks: BlockListType[];
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
const BlocksList: React.FC<BlocksListProps> = ({ blocks, loading = false }) => {
|
||||
return (
|
||||
<div className="scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-zinc-200 scrollbar-track-transparent h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
{loading
|
||||
? Array.from({ length: 7 }).map((_, index) => (
|
||||
<Block.Skeleton key={index} />
|
||||
))
|
||||
: blocks.map((block) => (
|
||||
<Block
|
||||
key={block.id}
|
||||
title={block.title}
|
||||
description={block.description}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BlocksList;
|
||||
@@ -1,43 +1,29 @@
|
||||
import React from "react";
|
||||
import Block from "../Block";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import BlocksList from "./BlocksList";
|
||||
import { BlockListType } from "./BlockMenuDefaultContent";
|
||||
import { inputBlocksListData } from "../../testing_data";
|
||||
|
||||
const InputBlocksContent: React.FC = () => {
|
||||
return (
|
||||
<div className="scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-zinc-200 scrollbar-track-transparent h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
<Block title="Date Input" description="Input a date into your agent." />
|
||||
<Block
|
||||
title="Dropdown input"
|
||||
description="Give your users the ability to select from a dropdown menu"
|
||||
/>
|
||||
<Block title="File upload" description="Upload a file to your agent" />
|
||||
<Block
|
||||
title="Text input"
|
||||
description="Allow users to select multiple options using checkboxes"
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Add to list"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const [blocks, setBlocks] = useState<BlockListType[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchBlocks = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// Simulate API call
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
setBlocks(inputBlocksListData);
|
||||
} catch (error) {
|
||||
console.error("Error fetching blocks:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchBlocks();
|
||||
}, []);
|
||||
return <BlocksList blocks={blocks} loading={loading} />;
|
||||
};
|
||||
|
||||
export default InputBlocksContent;
|
||||
|
||||
@@ -1,43 +1,67 @@
|
||||
import React from "react";
|
||||
import IntegrationBlock from "../IntegrationBlock";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Integration from "../Integration";
|
||||
import { integrationsListData } from "../../testing_data";
|
||||
|
||||
interface IntegrationListProps {
|
||||
setIntegration: React.Dispatch<React.SetStateAction<string>>;
|
||||
}
|
||||
|
||||
export interface IntegrationData {
|
||||
title: string;
|
||||
icon_url: string;
|
||||
description: string;
|
||||
number_of_blocks: number;
|
||||
}
|
||||
|
||||
const IntegrationList: React.FC<IntegrationListProps> = ({
|
||||
setIntegration,
|
||||
}) => {
|
||||
const [integrations, setIntegrations] = useState<IntegrationData[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
|
||||
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);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch integrations:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchIntegrations();
|
||||
}, []);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
{Array(5)
|
||||
.fill(null)
|
||||
.map((_, index) => (
|
||||
<Integration.Skeleton key={index} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<Integration
|
||||
title="Twitter Blocks"
|
||||
icon_url="/integrations/x.png"
|
||||
description="All twitter blocks, It has everthing to interact with twitter"
|
||||
number_of_blocks={10}
|
||||
onClick={() => setIntegration("Twitter Blocks")}
|
||||
/>
|
||||
<Integration
|
||||
title="Discord Blocks"
|
||||
icon_url="/integrations/discord.png"
|
||||
description="All Discord blocks, It has everthing to interact with discord"
|
||||
number_of_blocks={14}
|
||||
onClick={() => setIntegration("Discord Blocks")}
|
||||
/>
|
||||
<Integration
|
||||
title="Github Blocks"
|
||||
icon_url="/integrations/github.png"
|
||||
description="All Github blocks, It has everthing to interact with github"
|
||||
number_of_blocks={4}
|
||||
onClick={() => setIntegration("Github Blocks")}
|
||||
/>
|
||||
<Integration
|
||||
title="Hubspot Blocks"
|
||||
icon_url="/integrations/hubspot.png"
|
||||
description="All Hubspot blocks, It has everthing to interact with Hubspot"
|
||||
number_of_blocks={2}
|
||||
onClick={() => setIntegration("Hubspot Blocks")}
|
||||
/>
|
||||
{integrations.map((integration, index) => (
|
||||
<Integration
|
||||
key={index}
|
||||
title={integration.title}
|
||||
icon_url={integration.icon_url}
|
||||
description={integration.description}
|
||||
number_of_blocks={integration.number_of_blocks}
|
||||
onClick={() => setIntegration(integration.title)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,64 +1,57 @@
|
||||
import React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import MarketplaceAgentBlock from "../MarketplaceAgentBlock";
|
||||
import { marketplaceAgentData } from "../../testing_data";
|
||||
|
||||
export interface MarketplaceAgent {
|
||||
id: number;
|
||||
title: string;
|
||||
image_url: string;
|
||||
creator_name: string;
|
||||
number_of_runs: number;
|
||||
}
|
||||
|
||||
const MarketplaceAgentsContent: React.FC = () => {
|
||||
const [agents, setAgents] = useState<MarketplaceAgent[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchAgents = async () => {
|
||||
try {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1500));
|
||||
setAgents(marketplaceAgentData);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchAgents();
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="w-full space-y-3 p-4">
|
||||
{Array(5)
|
||||
.fill(null)
|
||||
.map((_, index) => (
|
||||
<MarketplaceAgentBlock.Skeleton key={index} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-zinc-200 scrollbar-track-transparent h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
<MarketplaceAgentBlock
|
||||
title="turtle test"
|
||||
image_url="/placeholder.png"
|
||||
creator_name="Autogpt"
|
||||
number_of_runs={1000}
|
||||
/>
|
||||
<MarketplaceAgentBlock
|
||||
title="turtle test 1"
|
||||
image_url="/placeholder.png"
|
||||
creator_name="Autogpt"
|
||||
number_of_runs={1324}
|
||||
/>
|
||||
<MarketplaceAgentBlock
|
||||
title="turtle test 2"
|
||||
image_url="/placeholder.png"
|
||||
creator_name="Autogpt"
|
||||
number_of_runs={10030}
|
||||
/>
|
||||
<MarketplaceAgentBlock
|
||||
title="turtle test 3"
|
||||
image_url="/placeholder.png"
|
||||
creator_name="Autogpt"
|
||||
number_of_runs={324}
|
||||
/>
|
||||
<MarketplaceAgentBlock
|
||||
title="turtle test"
|
||||
image_url="/placeholder.png"
|
||||
creator_name="Autogpt"
|
||||
number_of_runs={4345}
|
||||
/>
|
||||
<MarketplaceAgentBlock
|
||||
title="turtle test"
|
||||
image_url="/placeholder.png"
|
||||
creator_name="Autogpt"
|
||||
number_of_runs={324}
|
||||
/>
|
||||
<MarketplaceAgentBlock
|
||||
title="turtle test 3"
|
||||
image_url="/placeholder.png"
|
||||
creator_name="Autogpt"
|
||||
number_of_runs={324}
|
||||
/>
|
||||
<MarketplaceAgentBlock
|
||||
title="turtle test"
|
||||
image_url="/placeholder.png"
|
||||
creator_name="Autogpt"
|
||||
number_of_runs={4345}
|
||||
/>
|
||||
<MarketplaceAgentBlock
|
||||
title="turtle test"
|
||||
image_url="/placeholder.png"
|
||||
creator_name="Autogpt"
|
||||
number_of_runs={324}
|
||||
/>
|
||||
{agents.map((agent) => (
|
||||
<MarketplaceAgentBlock
|
||||
key={agent.id}
|
||||
title={agent.title}
|
||||
image_url={agent.image_url}
|
||||
creator_name={agent.creator_name}
|
||||
number_of_runs={agent.number_of_runs}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,46 +1,57 @@
|
||||
import React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import UGCAgentBlock from "../UGCAgentBlock";
|
||||
import { myAgentData } from "../../testing_data";
|
||||
|
||||
export interface UserAgent {
|
||||
id: number;
|
||||
title: string;
|
||||
edited_time: string;
|
||||
version: number;
|
||||
image_url: string;
|
||||
}
|
||||
|
||||
const MyAgentsContent: React.FC = () => {
|
||||
const [agents, setAgents] = useState<UserAgent[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchAgents = async () => {
|
||||
try {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1500));
|
||||
setAgents(myAgentData);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchAgents();
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="w-full space-y-3 p-4">
|
||||
{Array(5)
|
||||
.fill(null)
|
||||
.map((_, index) => (
|
||||
<UGCAgentBlock.Skeleton key={index} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-zinc-200 scrollbar-track-transparent h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
<UGCAgentBlock
|
||||
title="My Agent 1"
|
||||
edited_time="23rd April"
|
||||
version={3}
|
||||
image_url="/placeholder.png"
|
||||
/>
|
||||
<UGCAgentBlock
|
||||
title="My Agent 2"
|
||||
edited_time="21st April"
|
||||
version={4}
|
||||
image_url="/placeholder.png"
|
||||
/>
|
||||
<UGCAgentBlock
|
||||
title="My Agent 3"
|
||||
edited_time="23rd May"
|
||||
version={7}
|
||||
image_url="/placeholder.png"
|
||||
/>
|
||||
<UGCAgentBlock
|
||||
title="My Agent 4"
|
||||
edited_time="23rd April"
|
||||
version={3}
|
||||
image_url="/placeholder.png"
|
||||
/>
|
||||
<UGCAgentBlock
|
||||
title="My Agent 5"
|
||||
edited_time="23rd April"
|
||||
version={3}
|
||||
image_url="/placeholder.png"
|
||||
/>
|
||||
<UGCAgentBlock
|
||||
title="My Agent 6"
|
||||
edited_time="23rd April"
|
||||
version={3}
|
||||
image_url="/placeholder.png"
|
||||
/>
|
||||
{agents.map((agent) => (
|
||||
<UGCAgentBlock
|
||||
key={agent.id}
|
||||
title={agent.title}
|
||||
edited_time={agent.edited_time}
|
||||
version={agent.version}
|
||||
image_url={agent.image_url}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
import React from "react";
|
||||
import Block from "../Block";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import BlocksList from "./BlocksList";
|
||||
import { BlockListType } from "./BlockMenuDefaultContent";
|
||||
import { outputBlocksListData } from "../../testing_data";
|
||||
|
||||
const OutputBlocksContent: React.FC = () => {
|
||||
return (
|
||||
<div className="scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-zinc-200 scrollbar-track-transparent h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
<Block title="Date Input" description="Input a date into your agent." />
|
||||
<Block
|
||||
title="Dropdown input"
|
||||
description="Give your users the ability to select from a dropdown menu"
|
||||
/>
|
||||
<Block title="File upload" description="Upload a file to your agent" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const [blocks, setBlocks] = useState<BlockListType[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchBlocks = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// Simulate API call
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
setBlocks(outputBlocksListData);
|
||||
} catch (error) {
|
||||
console.error("Error fetching blocks:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchBlocks();
|
||||
}, []);
|
||||
return <BlocksList blocks={blocks} loading={loading} />;
|
||||
};
|
||||
|
||||
export default OutputBlocksContent;
|
||||
|
||||
@@ -1,20 +1,76 @@
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import SearchHistoryChip from "../SearchHistoryChip";
|
||||
import IntegrationChip from "../IntegrationChip";
|
||||
import Block from "../Block";
|
||||
import { DefaultStateType } from "./BlockMenuDefault";
|
||||
import {
|
||||
integrationsData,
|
||||
topBlocksData,
|
||||
recentSearchesData,
|
||||
} from "../../testing_data";
|
||||
|
||||
interface SuggestionContentProps {
|
||||
integration: string;
|
||||
setIntegration: React.Dispatch<React.SetStateAction<string>>;
|
||||
setDefaultState: React.Dispatch<React.SetStateAction<DefaultStateType>>;
|
||||
}
|
||||
|
||||
const SuggestionContent: React.FC<SuggestionContentProps> = ({
|
||||
integration,
|
||||
setIntegration,
|
||||
setDefaultState,
|
||||
}) => {
|
||||
const [recentSearches, setRecentSearches] = useState<string[] | null>(null);
|
||||
const [integrations, setIntegrations] = useState<
|
||||
{ icon_url: string; name: string }[] | null
|
||||
>(null);
|
||||
const [topBlocks, setTopBlocks] = useState<
|
||||
{ title: string; description: string }[] | null
|
||||
>(null);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
const fetchIntegrations = async (): Promise<
|
||||
{ icon_url: string; name: string }[]
|
||||
> => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 400));
|
||||
return integrationsData;
|
||||
};
|
||||
|
||||
const fetchTopBlocks = async (): Promise<
|
||||
{ title: string; description: string }[]
|
||||
> => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 600));
|
||||
return topBlocksData;
|
||||
};
|
||||
|
||||
// Fetch all data simultaneously using Promise.all
|
||||
const [
|
||||
recentSearchesDataFetched,
|
||||
integrationsDataFetched,
|
||||
topBlocksDataFetched,
|
||||
] = await Promise.all([
|
||||
fetchRecentSearches(),
|
||||
fetchIntegrations(),
|
||||
fetchTopBlocks(),
|
||||
]);
|
||||
|
||||
setRecentSearches(recentSearchesDataFetched);
|
||||
setIntegrations(integrationsDataFetched);
|
||||
setTopBlocks(topBlocksDataFetched);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-zinc-200 scrollbar-track-transparent h-full overflow-y-scroll pt-4">
|
||||
<div className="w-full space-y-6 pb-4">
|
||||
@@ -24,15 +80,22 @@ const SuggestionContent: React.FC<SuggestionContentProps> = ({
|
||||
Recent searches
|
||||
</p>
|
||||
<div className="scrollbar-hide flex flex-nowrap gap-2 overflow-x-auto">
|
||||
<SearchHistoryChip content="image generator" className="ml-4" />
|
||||
<SearchHistoryChip content="deepfake" />
|
||||
<SearchHistoryChip content="competitor analysis" />
|
||||
<SearchHistoryChip content="image generator" />
|
||||
<SearchHistoryChip content="deepfake" />
|
||||
<SearchHistoryChip content="competitor analysis" />
|
||||
<SearchHistoryChip content="image generator" />
|
||||
<SearchHistoryChip content="deepfake" />
|
||||
<SearchHistoryChip content="competitor analysis" />
|
||||
{recentSearches
|
||||
? recentSearches.map((search, index) => (
|
||||
<SearchHistoryChip
|
||||
key={`search-${index}`}
|
||||
content={search}
|
||||
className={index === 0 ? "ml-4" : ""}
|
||||
/>
|
||||
))
|
||||
: Array(3)
|
||||
.fill(0)
|
||||
.map((_, index) => (
|
||||
<SearchHistoryChip.Skeleton
|
||||
key={`search-${index}`}
|
||||
className={index === 0 ? "ml-4" : ""}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -42,34 +105,25 @@ const SuggestionContent: React.FC<SuggestionContentProps> = ({
|
||||
Integrations
|
||||
</p>
|
||||
<div className="grid grid-cols-3 grid-rows-2 gap-2">
|
||||
<IntegrationChip
|
||||
icon_url="/integrations/x.png"
|
||||
name="Twitter"
|
||||
onClick={() => {
|
||||
setDefaultState("integrations");
|
||||
setIntegration("Twitter Blocks");
|
||||
}}
|
||||
/>
|
||||
<IntegrationChip
|
||||
icon_url="/integrations/github.png"
|
||||
name="Github"
|
||||
/>
|
||||
<IntegrationChip
|
||||
icon_url="/integrations/hubspot.png"
|
||||
name="Hubspot"
|
||||
/>
|
||||
<IntegrationChip
|
||||
icon_url="/integrations/discord.png"
|
||||
name="Discord"
|
||||
/>
|
||||
<IntegrationChip
|
||||
icon_url="/integrations/medium.png"
|
||||
name="Medium"
|
||||
/>
|
||||
<IntegrationChip
|
||||
icon_url="/integrations/todoist.png"
|
||||
name="Todoist"
|
||||
/>
|
||||
{integrations
|
||||
? integrations.map((integration, index) => (
|
||||
<IntegrationChip
|
||||
key={`integration-${index}`}
|
||||
icon_url={integration.icon_url}
|
||||
name={integration.name}
|
||||
onClick={() => {
|
||||
setDefaultState("integrations");
|
||||
setIntegration(integration.name);
|
||||
}}
|
||||
/>
|
||||
))
|
||||
: Array(6)
|
||||
.fill(0)
|
||||
.map((_, index) => (
|
||||
<IntegrationChip.Skeleton
|
||||
key={`integration-skeleton-${index}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -79,26 +133,19 @@ const SuggestionContent: React.FC<SuggestionContentProps> = ({
|
||||
Top blocks
|
||||
</p>
|
||||
<div className="space-y-2">
|
||||
<Block
|
||||
title="Find in Dictionary"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Find in Dictionary"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Find in Dictionary"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Find in Dictionary"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
<Block
|
||||
title="Find in Dictionary"
|
||||
description="Enables your agent to chat with users in natural language."
|
||||
/>
|
||||
{topBlocks
|
||||
? topBlocks.map((block, index) => (
|
||||
<Block
|
||||
key={`block-${index}`}
|
||||
title={block.title}
|
||||
description={block.description}
|
||||
/>
|
||||
))
|
||||
: Array(3)
|
||||
.fill(0)
|
||||
.map((_, index) => (
|
||||
<Block.Skeleton key={`block-skeleton-${index}`} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,360 @@
|
||||
// Default state data
|
||||
|
||||
// All blocks
|
||||
import { BlockCategory } from "./block-menu/default/AllBlocksContent";
|
||||
import { BlockListType } from "./block-menu/default/BlockMenuDefaultContent";
|
||||
import { IntegrationData } from "./block-menu/default/IntegrationList";
|
||||
import { MarketplaceAgent } from "./block-menu/default/MarketplaceAgentsContent";
|
||||
import { UserAgent } from "./block-menu/default/MyAgentsContent";
|
||||
|
||||
// Suggestion
|
||||
|
||||
export const recentSearchesData = [
|
||||
"image generator",
|
||||
"deepfake",
|
||||
"competitor analysis",
|
||||
"market research",
|
||||
"AI tools",
|
||||
"content creation",
|
||||
"data visualization",
|
||||
"automation workflow",
|
||||
"analytics dashboard",
|
||||
];
|
||||
|
||||
// Define data for integrations
|
||||
export const integrationsData = [
|
||||
{
|
||||
icon_url: "/integrations/x.png",
|
||||
name: "Twitter",
|
||||
},
|
||||
{ icon_url: "/integrations/github.png", name: "Github" },
|
||||
{ icon_url: "/integrations/hubspot.png", name: "Hubspot" },
|
||||
{ icon_url: "/integrations/discord.png", name: "Discord" },
|
||||
{ icon_url: "/integrations/medium.png", name: "Medium" },
|
||||
{ icon_url: "/integrations/todoist.png", name: "Todoist" },
|
||||
];
|
||||
|
||||
// Define data for top blocks
|
||||
export const topBlocksData = [
|
||||
{
|
||||
title: "Find in Dictionary",
|
||||
description: "Enables your agent to chat with users in natural language.",
|
||||
},
|
||||
{
|
||||
title: "Web Search",
|
||||
description: "Allows your agent to search the web for information.",
|
||||
},
|
||||
{
|
||||
title: "Code Interpreter",
|
||||
description: "Helps your agent understand and execute code snippets.",
|
||||
},
|
||||
{
|
||||
title: "Data Analysis",
|
||||
description:
|
||||
"Enables your agent to analyze data and create visualizations.",
|
||||
},
|
||||
{
|
||||
title: "File Manager",
|
||||
description: "Gives your agent the ability to manage files and documents.",
|
||||
},
|
||||
];
|
||||
|
||||
// All Blocks
|
||||
export const allBlocksDataWithCategories: BlockCategory[] = [
|
||||
{
|
||||
name: "AI",
|
||||
count: 10,
|
||||
items: [
|
||||
{
|
||||
title: "Natural Language Processing",
|
||||
description:
|
||||
"Enables your agent to chat with users in natural language.",
|
||||
},
|
||||
{
|
||||
title: "Sentiment Analysis",
|
||||
description:
|
||||
"Analyzes the sentiment of user messages to respond appropriately.",
|
||||
},
|
||||
{
|
||||
title: "Text Generation",
|
||||
description:
|
||||
"Creates human-like text based on the context and inputs provided.",
|
||||
},
|
||||
{
|
||||
title: "Entity Recognition",
|
||||
description: "Identifies and extracts entities from user messages.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Basic",
|
||||
count: 6,
|
||||
items: [
|
||||
{
|
||||
title: "Condition",
|
||||
description: "Creates branching logic based on specific conditions.",
|
||||
},
|
||||
{
|
||||
title: "Loop",
|
||||
description: "Repeats actions until a specific condition is met.",
|
||||
},
|
||||
{
|
||||
title: "Variable",
|
||||
description:
|
||||
"Stores and manages data for use throughout your workflow.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Communication",
|
||||
count: 6,
|
||||
items: [
|
||||
{
|
||||
title: "Email Sender",
|
||||
description: "Sends emails to users based on triggers or conditions.",
|
||||
},
|
||||
{
|
||||
title: "SMS Notification",
|
||||
description:
|
||||
"Sends text message notifications to users' mobile devices.",
|
||||
},
|
||||
{
|
||||
title: "Webhook",
|
||||
description:
|
||||
"Integrates with external services through HTTP callbacks.",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const actionBlocksListData: BlockListType[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: "Date Input Block",
|
||||
description: "Input a date into your agent.",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Dropdown input",
|
||||
description: "Give your users the ability to select from a dropdown menu",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "File upload",
|
||||
description: "Upload a file to your agent",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "Text input",
|
||||
description: "Allow users to select multiple options using checkboxes",
|
||||
},
|
||||
];
|
||||
|
||||
export const inputBlocksListData: BlockListType[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: "Text Field",
|
||||
description: "Collect single line text input from users.",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Checkbox",
|
||||
description: "Allow users to select multiple options using checkboxes.",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Radio Button",
|
||||
description: "Let users choose one option from a list of alternatives.",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "Textarea",
|
||||
description: "Collect multi-line text input from users.",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "Number Input",
|
||||
description: "Collect numerical values with optional min/max constraints.",
|
||||
},
|
||||
];
|
||||
|
||||
export const outputBlocksListData: BlockListType[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: "Display Text",
|
||||
description: "Show formatted text content to users.",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Image Output",
|
||||
description: "Display images, charts, or visual content.",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Table Display",
|
||||
description: "Present data in an organized tabular format.",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "PDF Generation",
|
||||
description: "Create and export data as PDF documents.",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "Status Alert",
|
||||
description: "Show success, error, or informational alerts to users.",
|
||||
},
|
||||
];
|
||||
|
||||
export const integrationsListData: IntegrationData[] = [
|
||||
{
|
||||
title: "Twitter Blocks",
|
||||
icon_url: "/integrations/x.png",
|
||||
description:
|
||||
"All twitter blocks, It has everthing to interact with twitter",
|
||||
number_of_blocks: 10,
|
||||
},
|
||||
{
|
||||
title: "Discord Blocks",
|
||||
icon_url: "/integrations/discord.png",
|
||||
description:
|
||||
"All Discord blocks, It has everthing to interact with discord",
|
||||
number_of_blocks: 14,
|
||||
},
|
||||
{
|
||||
title: "Github Blocks",
|
||||
icon_url: "/integrations/github.png",
|
||||
description: "All Github blocks, It has everthing to interact with github",
|
||||
number_of_blocks: 4,
|
||||
},
|
||||
{
|
||||
title: "Hubspot Blocks",
|
||||
icon_url: "/integrations/hubspot.png",
|
||||
description:
|
||||
"All Hubspot blocks, It has everthing to interact with Hubspot",
|
||||
number_of_blocks: 2,
|
||||
},
|
||||
{
|
||||
title: "Medium Blocks",
|
||||
icon_url: "/integrations/medium.png",
|
||||
description: "All Medium blocks, It has everything to interact with Medium",
|
||||
number_of_blocks: 6,
|
||||
},
|
||||
{
|
||||
title: "Todoist Blocks",
|
||||
icon_url: "/integrations/todoist.png",
|
||||
description:
|
||||
"All Todoist blocks, It has everything to interact with Todoist",
|
||||
number_of_blocks: 8,
|
||||
},
|
||||
];
|
||||
|
||||
export const marketplaceAgentData: MarketplaceAgent[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: "turtle test",
|
||||
image_url: "/placeholder.png",
|
||||
creator_name: "Autogpt",
|
||||
number_of_runs: 1000,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "turtle test 1",
|
||||
image_url: "/placeholder.png",
|
||||
creator_name: "Autogpt",
|
||||
number_of_runs: 1324,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "turtle test 2",
|
||||
image_url: "/placeholder.png",
|
||||
creator_name: "Autogpt",
|
||||
number_of_runs: 10030,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "turtle test 3",
|
||||
image_url: "/placeholder.png",
|
||||
creator_name: "Autogpt",
|
||||
number_of_runs: 324,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "turtle test",
|
||||
image_url: "/placeholder.png",
|
||||
creator_name: "Autogpt",
|
||||
number_of_runs: 4345,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: "turtle test",
|
||||
image_url: "/placeholder.png",
|
||||
creator_name: "Autogpt",
|
||||
number_of_runs: 324,
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
title: "turtle test 3",
|
||||
image_url: "/placeholder.png",
|
||||
creator_name: "Autogpt",
|
||||
number_of_runs: 324,
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
title: "turtle test",
|
||||
image_url: "/placeholder.png",
|
||||
creator_name: "Autogpt",
|
||||
number_of_runs: 4345,
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
title: "turtle test",
|
||||
image_url: "/placeholder.png",
|
||||
creator_name: "Autogpt",
|
||||
number_of_runs: 324,
|
||||
},
|
||||
];
|
||||
|
||||
export const myAgentData: UserAgent[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: "My Agent 1",
|
||||
edited_time: "23rd April",
|
||||
version: 3,
|
||||
image_url: "/placeholder.png",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "My Agent 2",
|
||||
edited_time: "21st April",
|
||||
version: 4,
|
||||
image_url: "/placeholder.png",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "My Agent 3",
|
||||
edited_time: "23rd May",
|
||||
version: 7,
|
||||
image_url: "/placeholder.png",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "My Agent 4",
|
||||
edited_time: "23rd April",
|
||||
version: 3,
|
||||
image_url: "/placeholder.png",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "My Agent 5",
|
||||
edited_time: "23rd April",
|
||||
version: 3,
|
||||
image_url: "/placeholder.png",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: "My Agent 6",
|
||||
edited_time: "23rd April",
|
||||
version: 3,
|
||||
image_url: "/placeholder.png",
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user