mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
wip
This commit is contained in:
@@ -24,7 +24,7 @@ export const AgentImages: React.FC<AgentImagesProps> = ({ images }) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="h-full w-screen overflow-y-auto px-2 md:w-full lg:h-[91.25rem] lg:w-[56.25rem]">
|
||||
<div className="w-screen overflow-y-auto px-2 md:w-full lg:w-[56.25rem]">
|
||||
<div className="space-y-4 sm:space-y-6 md:space-y-[1.875rem]">
|
||||
{images.map((image, index) => (
|
||||
<AgentImageItem
|
||||
|
||||
@@ -58,15 +58,15 @@ export const StoreCard: React.FC<StoreCardProps> = ({
|
||||
<Image
|
||||
src={agentImage}
|
||||
alt={`${agentName} preview`}
|
||||
layout="fill"
|
||||
objectFit="cover"
|
||||
className="rounded-xl"
|
||||
fill
|
||||
sizes="192px"
|
||||
className="rounded-xl object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="-mt-8 flex flex-col px-4">
|
||||
<Avatar className="mb-2 h-16 w-16">
|
||||
<AvatarImage src={avatarSrc} alt={agentName} />
|
||||
<AvatarFallback>{agentName.charAt(0)}</AvatarFallback>
|
||||
<AvatarFallback className='h-16 w-16'>{agentName.charAt(0)}</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="mb-1 font-neue text-xl font-bold tracking-tight text-[#272727]">
|
||||
{agentName}
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { Page } from "./Page";
|
||||
import { userEvent, within } from "@storybook/test";
|
||||
import { IconType } from "../../../ui/icons";
|
||||
|
||||
const meta = {
|
||||
title: "AGPTUI/Marketplace/Agent/Page",
|
||||
component: Page,
|
||||
parameters: {
|
||||
layout: {
|
||||
center: true,
|
||||
fullscreen: true,
|
||||
padding: 0,
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
argTypes: {
|
||||
userName: { control: "text" },
|
||||
userEmail: { control: "text" },
|
||||
navLinks: { control: "object" },
|
||||
activeLink: { control: "text" },
|
||||
menuItemGroups: { control: "object" },
|
||||
agentInfo: { control: "object" },
|
||||
agentImages: { control: "object" },
|
||||
otherAgentsByCreator: { control: "object" },
|
||||
similarAgents: { control: "object" },
|
||||
},
|
||||
} satisfies Meta<typeof Page>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
const mockNavLinks = [
|
||||
{ name: "Marketplace", href: "/" },
|
||||
{ name: "Library", href: "/library" },
|
||||
{ name: "Build", href: "/build" },
|
||||
];
|
||||
|
||||
const mockMenuItemGroups = [
|
||||
{
|
||||
items: [
|
||||
{ icon: IconType.Edit, text: "Edit profile", href: "/profile/edit" },
|
||||
],
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{
|
||||
icon: IconType.LayoutDashboard,
|
||||
text: "Creator Dashboard",
|
||||
href: "/dashboard",
|
||||
},
|
||||
{
|
||||
icon: IconType.UploadCloud,
|
||||
text: "Publish an agent",
|
||||
href: "/publish",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
items: [{ icon: IconType.Settings, text: "Settings", href: "/settings" }],
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{
|
||||
icon: IconType.LogOut,
|
||||
text: "Log out",
|
||||
onClick: () => console.log("Logged out"),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const mockAgentInfo = {
|
||||
name: "Super SEO Optimizer",
|
||||
creator: "AI Labs",
|
||||
description: "Boost your website's search engine rankings with our advanced AI-powered SEO optimization tool.",
|
||||
rating: 4.9,
|
||||
runs: 100000,
|
||||
categories: ["SEO", "Marketing", "Content"],
|
||||
lastUpdated: "2023-05-15",
|
||||
version: "2.1.0",
|
||||
};
|
||||
|
||||
const mockAgentImages = [
|
||||
"https://ddz4ak4pa3d19.cloudfront.net/cache/cc/11/cc1172271dcf723a34f488a3344e82b2.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/c/c5/Big_buck_bunny_poster_big.jpg",
|
||||
];
|
||||
|
||||
const mockOtherAgentsByCreator = [
|
||||
{
|
||||
agentName: "Content Wizard",
|
||||
agentImage: "https://upload.wikimedia.org/wikipedia/commons/c/c5/Big_buck_bunny_poster_big.jpg",
|
||||
description: "Generate high-quality, engaging content for your blog, social media, or marketing campaigns.",
|
||||
runs: 75000,
|
||||
rating: 4.7,
|
||||
avatarSrc: "https://example.com/avatar1.jpg",
|
||||
},
|
||||
{
|
||||
agentName: "Data Analyzer Pro",
|
||||
agentImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/07/78/0778415062f8dff56a046a7eca44567c.jpg",
|
||||
description: "Powerful tool for analyzing large datasets and generating insights.",
|
||||
runs: 50000,
|
||||
rating: 5,
|
||||
avatarSrc: "https://github.com/shadcn.png",
|
||||
},
|
||||
{
|
||||
agentName: "AI Copywriter",
|
||||
agentImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/33/bb/33bb7b3c8252b35a0086d893f7a5790c.jpg",
|
||||
description: "AI-powered copywriting assistant for creating compelling marketing copy.",
|
||||
runs: 62000,
|
||||
rating: 4.8,
|
||||
avatarSrc: "https://example.com/avatar4.jpg",
|
||||
},
|
||||
];
|
||||
|
||||
const mockSimilarAgents = [
|
||||
{
|
||||
agentName: "SEO Master",
|
||||
agentImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/59/b9/59b9415d4044f48f9b9e318c4c5a7984.jpg",
|
||||
description: "Comprehensive SEO tool for website optimization and ranking improvement.",
|
||||
runs: 80000,
|
||||
rating: 4.8,
|
||||
avatarSrc: "https://example.com/avatar2.jpg",
|
||||
},
|
||||
{
|
||||
agentName: "Keyword Genius",
|
||||
agentImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/11/47/114784105a9b180e08e117cbf2612e5b.jpg",
|
||||
description: "Advanced keyword research and analysis tool for SEO professionals.",
|
||||
runs: 60000,
|
||||
rating: 4.6,
|
||||
avatarSrc: "https://example.com/avatar3.jpg",
|
||||
},
|
||||
{
|
||||
agentName: "Backlink Builder",
|
||||
agentImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/22/cc/22cc7136d7eac435657b316bb16b7e89.jpg",
|
||||
description: "Automated tool for building high-quality backlinks to improve SEO performance.",
|
||||
runs: 55000,
|
||||
rating: 4.7,
|
||||
avatarSrc: "https://example.com/avatar5.jpg",
|
||||
},
|
||||
];
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
userName: "John Doe",
|
||||
userEmail: "john.doe@example.com",
|
||||
navLinks: mockNavLinks,
|
||||
activeLink: "/marketplace",
|
||||
menuItemGroups: mockMenuItemGroups,
|
||||
agentInfo: mockAgentInfo,
|
||||
agentImages: mockAgentImages,
|
||||
otherAgentsByCreator: mockOtherAgentsByCreator,
|
||||
similarAgents: mockSimilarAgents,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithInteraction: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
// Click on the "Run Agent" button
|
||||
const runAgentButton = canvas.getByText("Run Agent");
|
||||
await userEvent.click(runAgentButton);
|
||||
|
||||
// Click on an "Other agents by creator" card
|
||||
const otherAgentCard = canvas.getByText("Content Wizard");
|
||||
await userEvent.click(otherAgentCard);
|
||||
|
||||
// Click on the "Become a Creator" button
|
||||
const becomeCreatorButton = canvas.getByText("Become a Creator");
|
||||
await userEvent.click(becomeCreatorButton);
|
||||
},
|
||||
};
|
||||
|
||||
export const LongLists: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
otherAgentsByCreator: Array(10).fill(mockOtherAgentsByCreator[0]),
|
||||
similarAgents: Array(10).fill(mockSimilarAgents[0]),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,134 @@
|
||||
import * as React from "react";
|
||||
import { Navbar } from "../../Navbar";
|
||||
import { AgentInfo } from "../../AgentInfo";
|
||||
import { AgentImages } from "../../AgentImages";
|
||||
import { BecomeACreator } from "../../BecomeACreator";
|
||||
import { TopAgentsSection } from "../home/TopAgentsSection";
|
||||
import { Separator } from "../../../ui/separator";
|
||||
import { IconType } from "../../../ui/icons";
|
||||
import Link from "next/link";
|
||||
|
||||
interface PageProps {
|
||||
userName: string;
|
||||
userEmail: string;
|
||||
navLinks: { name: string; href: string }[];
|
||||
activeLink: string;
|
||||
menuItemGroups: {
|
||||
groupName?: string;
|
||||
items: {
|
||||
icon: IconType;
|
||||
text: string;
|
||||
href?: string;
|
||||
onClick?: () => void;
|
||||
}[];
|
||||
}[];
|
||||
agentInfo: {
|
||||
name: string;
|
||||
creator: string;
|
||||
description: string;
|
||||
rating: number;
|
||||
runs: number;
|
||||
categories: string[];
|
||||
lastUpdated: string;
|
||||
version: string;
|
||||
};
|
||||
agentImages: string[];
|
||||
otherAgentsByCreator: {
|
||||
agentName: string;
|
||||
agentImage: string;
|
||||
description: string;
|
||||
runs: number;
|
||||
rating: number;
|
||||
avatarSrc: string;
|
||||
}[];
|
||||
similarAgents: {
|
||||
agentName: string;
|
||||
agentImage: string;
|
||||
description: string;
|
||||
runs: number;
|
||||
rating: number;
|
||||
avatarSrc: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export const Page: React.FC<PageProps> = ({
|
||||
userName,
|
||||
userEmail,
|
||||
navLinks,
|
||||
activeLink,
|
||||
menuItemGroups,
|
||||
agentInfo,
|
||||
agentImages,
|
||||
otherAgentsByCreator,
|
||||
similarAgents,
|
||||
}) => {
|
||||
const handleRunAgent = () => {
|
||||
console.log("Run agent clicked");
|
||||
// Implement run agent functionality
|
||||
};
|
||||
|
||||
const handleCardClick = (agentName: string) => {
|
||||
console.log("Clicked on agent:", agentName);
|
||||
// Implement card click functionality
|
||||
};
|
||||
|
||||
const handleBecomeCreator = () => {
|
||||
console.log("Become a Creator clicked");
|
||||
// Implement become a creator functionality
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-screen max-w-[1440px]">
|
||||
<Navbar
|
||||
userName={userName}
|
||||
userEmail={userEmail}
|
||||
links={navLinks}
|
||||
activeLink={activeLink}
|
||||
menuItemGroups={menuItemGroups}
|
||||
/>
|
||||
<main className="px-10">
|
||||
<div className="mt-10 mb-6">
|
||||
<Link href="/marketplace" className="text-2xl font-medium text-[#272727]">
|
||||
Marketplace
|
||||
</Link>
|
||||
<span className="mx-2 text-2xl font-medium text-[#272727]">/</span>
|
||||
<span className="text-2xl font-medium text-[#272727]">{agentInfo.name}</span>
|
||||
</div>
|
||||
<div className="flex flex-col lg:flex-row gap-5">
|
||||
<AgentInfo
|
||||
onRunAgent={handleRunAgent}
|
||||
name={agentInfo.name}
|
||||
creator={agentInfo.creator}
|
||||
description={agentInfo.description}
|
||||
rating={agentInfo.rating}
|
||||
runs={agentInfo.runs}
|
||||
categories={agentInfo.categories}
|
||||
lastUpdated={agentInfo.lastUpdated}
|
||||
version={agentInfo.version}
|
||||
/>
|
||||
<AgentImages images={agentImages} />
|
||||
</div>
|
||||
<Separator className="my-12" />
|
||||
<TopAgentsSection
|
||||
topAgents={otherAgentsByCreator}
|
||||
onCardClick={handleCardClick}
|
||||
sectionTitle={`Other agents by ${agentInfo.creator}`}
|
||||
/>
|
||||
<Separator className="my-12" />
|
||||
<TopAgentsSection
|
||||
topAgents={similarAgents}
|
||||
onCardClick={handleCardClick}
|
||||
sectionTitle="Similar agents"
|
||||
/>
|
||||
<Separator className="my-12" />
|
||||
<BecomeACreator
|
||||
title="Want to contribute?"
|
||||
heading="We're always looking for more Creators!"
|
||||
description="Join our ever-growing community of hackers and tinkerers"
|
||||
buttonText="Become a Creator"
|
||||
onButtonClick={handleBecomeCreator}
|
||||
/>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -100,7 +100,11 @@ export const Page: React.FC<PageProps> = ({
|
||||
onCardClick={handleCardClick}
|
||||
/>
|
||||
<Separator />
|
||||
<TopAgentsSection topAgents={topAgents} onCardClick={handleCardClick} />
|
||||
<TopAgentsSection
|
||||
sectionTitle="Top Agents"
|
||||
topAgents={topAgents}
|
||||
onCardClick={handleCardClick}
|
||||
/>
|
||||
<Separator />
|
||||
<FeaturedCreators
|
||||
featuredCreators={featuredCreators}
|
||||
|
||||
@@ -16,11 +16,13 @@ interface TopAgent {
|
||||
}
|
||||
|
||||
interface TopAgentsSectionProps {
|
||||
sectionTitle: string;
|
||||
topAgents: TopAgent[];
|
||||
onCardClick: (agentName: string) => void;
|
||||
}
|
||||
|
||||
export const TopAgentsSection: React.FC<TopAgentsSectionProps> = ({
|
||||
sectionTitle,
|
||||
topAgents,
|
||||
onCardClick,
|
||||
}) => {
|
||||
@@ -28,7 +30,7 @@ export const TopAgentsSection: React.FC<TopAgentsSectionProps> = ({
|
||||
<div className="flex flex-col items-center justify-center py-8">
|
||||
<div className="w-full">
|
||||
<div className="mb-6 font-neue text-[23px] font-bold leading-9 tracking-tight text-[#282828]">
|
||||
Top agents
|
||||
{sectionTitle}
|
||||
</div>
|
||||
<Carousel
|
||||
className="md:hidden"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import * as React from "react";
|
||||
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
||||
import BoringAvatar from "./BoringAvatarWrapper";
|
||||
import tailwindConfig from "../../../tailwind.config";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -33,6 +34,25 @@ const AvatarImage = React.forwardRef<
|
||||
));
|
||||
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
||||
|
||||
/**
|
||||
* Hack to match the avatar size based on Tailwind classes.
|
||||
* This function attempts to extract the size from a 'h-' class in the className string,
|
||||
* and maps it to the corresponding size in the Tailwind config.
|
||||
* If no matching class is found, it defaults to 40.
|
||||
* @param className - The className string to parse
|
||||
* @returns The size of the avatar in pixels
|
||||
*/
|
||||
const getAvatarSize = (className: string | undefined): number => {
|
||||
if (className?.includes('h-')) {
|
||||
const match = parseInt(className.match(/h-(\d+)/)?.[1] || '16');
|
||||
if (match) {
|
||||
const size = tailwindConfig.theme.extend.spacing[match as keyof typeof tailwindConfig.theme.extend.spacing];
|
||||
return size ? parseInt(size.replace('rem', '')) * 16 : 40;
|
||||
}
|
||||
}
|
||||
return 40;
|
||||
};
|
||||
|
||||
const AvatarFallback = React.forwardRef<
|
||||
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
||||
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
||||
@@ -46,7 +66,7 @@ const AvatarFallback = React.forwardRef<
|
||||
{...props}
|
||||
>
|
||||
<BoringAvatar
|
||||
size={40}
|
||||
size={getAvatarSize(className)}
|
||||
name={props.children?.toString() || "User"}
|
||||
variant="marble"
|
||||
colors={["#92A1C6", "#146A7C", "#F0AB3D", "#C271B4", "#C20D90"]}
|
||||
|
||||
@@ -66,7 +66,7 @@ const config = {
|
||||
},
|
||||
spacing: {
|
||||
// Tailwind spacing + custom sizes
|
||||
0: "0px",
|
||||
0: "0rem",
|
||||
0.5: "0.125rem",
|
||||
1: "0.25rem",
|
||||
1.5: "0.375rem",
|
||||
|
||||
Reference in New Issue
Block a user