update featured agent and formatting

This commit is contained in:
SwiftyOS
2024-10-28 10:49:51 +01:00
parent 8dc22e2a63
commit 03d754cb50
10 changed files with 245 additions and 198 deletions

View File

@@ -12,7 +12,11 @@ const nextConfig = {
process.env.NEXT_PUBLIC_AGPT_MARKETPLACE_URL,
},
images: {
domains: ["images.unsplash.com", "ddz4ak4pa3d19.cloudfront.net", "upload.wikimedia.org"],
domains: [
"images.unsplash.com",
"ddz4ak4pa3d19.cloudfront.net",
"upload.wikimedia.org",
],
},
// async redirects() {
// return [

View File

@@ -1,4 +1,3 @@
import * as React from "react";
import { HeroSection } from "@/components/agptui/composite/HeroSection";
import { FeaturedSection } from "@/components/agptui/composite/FeaturedSection";
@@ -9,124 +8,126 @@ import { Separator } from "@/components/ui/separator";
import { getFeaturedAgents } from "@/app/api/featuredAgents/getFeaturedAgents";
interface PageProps {
featuredAgents: {
agentName: string;
agentImage: string;
creatorName: string;
description: string;
runs: number;
rating: number;
}[];
topAgents: {
agentName: string;
agentImage: string;
avatarSrc: string;
description: string;
runs: number;
rating: number;
}[];
featuredCreators: {
creatorName: string;
creatorImage: string;
bio: string;
agentsUploaded: number;
avatarSrc: string;
}[];
featuredAgents: {
agentName: string;
agentImage: string;
creatorName: string;
description: string;
runs: number;
rating: number;
}[];
topAgents: {
agentName: string;
agentImage: string;
avatarSrc: string;
description: string;
runs: number;
rating: number;
}[];
featuredCreators: {
creatorName: string;
creatorImage: string;
bio: string;
agentsUploaded: number;
avatarSrc: string;
}[];
}
export default async function Page() {
let featuredAgents = await getFeaturedAgents();
let topAgents = [
{
agentName: "Data Analyzer Pro",
agentImage:
"https://ddz4ak4pa3d19.cloudfront.net/cache/07/78/0778415062f8dff56a046a7eca44567c.jpg",
avatarSrc: "https://github.com/shadcn.png",
description:
"Powerful tool for analyzing large datasets and generating insights.",
runs: 50000,
rating: 5,
},
{
agentName: "Image Recognition Master",
agentImage:
"https://ddz4ak4pa3d19.cloudfront.net/cache/59/b9/59b9415d4044f48f9b9e318c4c5a7984.jpg",
avatarSrc: "https://example.com/avatar2.jpg",
description:
"Accurately identify and classify objects in images using state-of-the-art machine learning algorithms.",
runs: 60000,
rating: 4.6,
},
];
let featuredCreators = [
{
creatorName: "AI Labs",
creatorImage:
"https://ddz4ak4pa3d19.cloudfront.net/cache/53/b2/53b2bc7d7900f0e1e60bf64ebf38032d.jpg",
bio: "Pioneering AI solutions for everyday problems",
agentsUploaded: 25,
avatarSrc: "https://github.com/shadcn.png",
},
{
creatorName: "WriteRight Inc.",
creatorImage:
"https://ddz4ak4pa3d19.cloudfront.net/cache/40/f7/40f7bc97c952f8df0f9c88d29defe8d4.jpg",
bio: "Empowering content creators with AI-driven tools",
agentsUploaded: 18,
avatarSrc: "https://example.com/writeright-avatar.jpg",
},
];
let featuredAgents = await getFeaturedAgents();
let topAgents = [
{
agentName: "Data Analyzer Pro",
agentImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/07/78/0778415062f8dff56a046a7eca44567c.jpg",
avatarSrc: "https://github.com/shadcn.png",
description: "Powerful tool for analyzing large datasets and generating insights.",
runs: 50000,
rating: 5,
},
{
agentName: "Image Recognition Master",
agentImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/59/b9/59b9415d4044f48f9b9e318c4c5a7984.jpg",
avatarSrc: "https://example.com/avatar2.jpg",
description: "Accurately identify and classify objects in images using state-of-the-art machine learning algorithms.",
runs: 60000,
rating: 4.6,
},
];
let featuredCreators = [
{
creatorName: "AI Labs",
creatorImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/53/b2/53b2bc7d7900f0e1e60bf64ebf38032d.jpg",
bio: "Pioneering AI solutions for everyday problems",
agentsUploaded: 25,
avatarSrc: "https://github.com/shadcn.png",
},
{
creatorName: "WriteRight Inc.",
creatorImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/40/f7/40f7bc97c952f8df0f9c88d29defe8d4.jpg",
bio: "Empowering content creators with AI-driven tools",
agentsUploaded: 18,
avatarSrc: "https://example.com/writeright-avatar.jpg",
},
];
const handleSearch = (query: string) => {
console.log("Search query:", query);
// Implement search functionality
};
const handleFilterChange = (selectedFilters: string[]) => {
console.log("Selected filters:", selectedFilters);
// Implement filter functionality
};
const handleCardClick = (agentName: string) => {
console.log("Clicked on agent:", agentName);
// Implement card click functionality
};
const handleSearch = (query: string) => {
console.log("Search query:", query);
// Implement search functionality
};
const handleBecomeCreator = () => {
console.log("Become a Creator clicked");
// Implement become a creator functionality
};
const handleFilterChange = (selectedFilters: string[]) => {
console.log("Selected filters:", selectedFilters);
// Implement filter 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-[1360px]">
<main className="px-4">
<HeroSection
onSearch={handleSearch}
onFilterChange={handleFilterChange}
/>
<FeaturedSection
featuredAgents={featuredAgents}
onCardClick={handleCardClick}
/>
<Separator />
<AgentsSection
sectionTitle="Top Agents"
agents={topAgents}
onCardClick={handleCardClick}
/>
<Separator />
<FeaturedCreators
featuredCreators={featuredCreators}
onCardClick={handleCardClick}
/>
<Separator />
<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>
);
};
return (
<div className="mx-auto w-screen max-w-[1360px]">
<main className="px-4">
<HeroSection
onSearch={handleSearch}
onFilterChange={handleFilterChange}
/>
<FeaturedSection
featuredAgents={featuredAgents}
onCardClick={handleCardClick}
/>
<Separator />
<AgentsSection
sectionTitle="Top Agents"
agents={topAgents}
onCardClick={handleCardClick}
/>
<Separator />
<FeaturedCreators
featuredCreators={featuredCreators}
onCardClick={handleCardClick}
/>
<Separator />
<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>
);
}

View File

@@ -1,10 +1,10 @@
export interface FeaturedAgent {
agentName: string;
agentImage: string;
creatorName: string;
description: string;
runs: number;
rating: number;
agentName: string;
agentImage: string;
creatorName: string;
description: string;
runs: number;
rating: number;
}
export type FeaturedAgents = FeaturedAgent[];

View File

@@ -1,40 +1,44 @@
import type { FeaturedAgents } from './featuredAgents';
import type { FeaturedAgents } from "./featuredAgents";
export async function getFeaturedAgents(): Promise<FeaturedAgents> {
if (!process.env.NEXT_PUBLIC_AGPT_SERVER_URL) {
throw new Error('NEXT_PUBLIC_AGPT_SERVER_URL is not set!');
}
try {
const res = await fetch(`${process.env.NEXT_PUBLIC_AGPT_SERVER_URL}/featured-agents`);
if (!process.env.NEXT_PUBLIC_AGPT_SERVER_URL) {
throw new Error("NEXT_PUBLIC_AGPT_SERVER_URL is not set!");
}
try {
const res = await fetch(
`${process.env.NEXT_PUBLIC_AGPT_SERVER_URL}/featured-agents`,
);
if (!res.ok) {
// Render the closest `error.js` Error Boundary
throw new Error('Something went wrong while fetching featured agents!');
}
const featuredAgents = (await res.json()) as FeaturedAgents;
return featuredAgents;
} catch (error) {
console.error('Error fetching featured agents:', error);
return [
{
agentName: "Super SEO Optimizer",
agentImage: "https://ddz4ak4pa3d19.cloudfront.net/cache/cc/11/cc1172271dcf723a34f488a3344e82b2.jpg",
creatorName: "AI Labs",
description: "Boost your website's search engine rankings with our advanced AI-powered SEO optimization tool.",
runs: 100000,
rating: 4.9,
},
{
agentName: "Content Wizard",
agentImage: "https://upload.wikimedia.org/wikipedia/commons/c/c5/Big_buck_bunny_poster_big.jpg",
creatorName: "WriteRight Inc.",
description: "Generate high-quality, engaging content for your blog, social media, or marketing campaigns.",
runs: 75000,
rating: 4.7,
},
];
if (!res.ok) {
// Render the closest `error.js` Error Boundary
throw new Error("Something went wrong while fetching featured agents!");
}
const featuredAgents = (await res.json()) as FeaturedAgents;
return featuredAgents;
} catch (error) {
console.error("Error fetching featured agents:", error);
return [
{
agentName: "Super SEO Optimizer",
agentImage:
"https://ddz4ak4pa3d19.cloudfront.net/cache/cc/11/cc1172271dcf723a34f488a3344e82b2.jpg",
creatorName: "AI Labs",
description:
"Boost your website's search engine rankings with our advanced AI-powered SEO optimization tool.",
runs: 100000,
rating: 4.9,
},
{
agentName: "Content Wizard",
agentImage:
"https://upload.wikimedia.org/wikipedia/commons/c/c5/Big_buck_bunny_poster_big.jpg",
creatorName: "WriteRight Inc.",
description:
"Generate high-quality, engaging content for your blog, social media, or marketing campaigns.",
runs: 75000,
rating: 4.7,
},
];
}
}

View File

@@ -14,6 +14,7 @@ const meta = {
tags: ["autodocs"],
argTypes: {
agentName: { control: "text" },
subHeading: { control: "text" },
agentImage: { control: "text" },
creatorName: { control: "text" },
description: { control: "text" },
@@ -29,6 +30,7 @@ type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
agentName: "SEO Optimizer Pro",
subHeading: "Optimize your website's SEO",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "AI Solutions Inc.",
@@ -43,6 +45,7 @@ export const Default: Story = {
export const LowRating: Story = {
args: {
agentName: "Data Analyzer Lite",
subHeading: "Basic data analysis tool",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "DataTech",
@@ -56,6 +59,7 @@ export const LowRating: Story = {
export const HighRuns: Story = {
args: {
agentName: "CodeAssist AI",
subHeading: "Your AI coding companion",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "DevTools Co.",
@@ -70,6 +74,7 @@ export const HighRuns: Story = {
export const LongDescription: Story = {
args: {
agentName: "MultiTasker",
subHeading: "All-in-one productivity suite",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "Productivity Plus",
@@ -84,6 +89,7 @@ export const LongDescription: Story = {
export const ShortDescription: Story = {
args: {
agentName: "QuickTask",
subHeading: "Fast task automation",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "EfficientWorks",
@@ -97,6 +103,7 @@ export const ShortDescription: Story = {
export const TwoLineName: Story = {
args: {
agentName: "Agent name goes here example of agent with two lines of text",
subHeading: "Multi-line agent example",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "InnovativeTech Solutions",
@@ -111,6 +118,7 @@ export const TwoLineName: Story = {
export const TwoLineNameLongDescription: Story = {
args: {
agentName: "Advanced Natural Language Processing and Machine Learning",
subHeading: "State-of-the-art NLP & ML",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "AI Research Labs",
@@ -125,6 +133,7 @@ export const TwoLineNameLongDescription: Story = {
export const WithInteraction: Story = {
args: {
agentName: "AI Writing Assistant",
subHeading: "Enhance your writing",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "WordCraft AI",

View File

@@ -3,6 +3,7 @@ import Image from "next/image";
import { StarRatingIcons } from "@/components/ui/icons";
interface FeaturedStoreCardProps {
agentName: string;
subHeading: string;
agentImage: string;
creatorName: string;
description: string;
@@ -13,6 +14,7 @@ interface FeaturedStoreCardProps {
export const FeaturedStoreCard: React.FC<FeaturedStoreCardProps> = ({
agentName,
subHeading,
agentImage,
creatorName,
description,
@@ -22,43 +24,61 @@ export const FeaturedStoreCard: React.FC<FeaturedStoreCardProps> = ({
}) => {
return (
<div
className={`inline-flex w-[calc(100vw-4rem)] cursor-pointer flex-col items-start justify-between gap-3 rounded-xl border border-black/10 bg-[#f9f9f9] px-2 pb-2 pt-4 font-neue text-sm tracking-tight text-[#272727] transition-shadow duration-300 hover:shadow-lg md:h-[37.188rem] md:w-[41.875rem] md:gap-5 md:px-[1.5625rem] md:pb-[0.9375rem] md:pt-[2.1875rem] md:text-xl lg:basis-full`}
className="group inline-flex h-[775px] w-[440px] cursor-pointer flex-col items-start justify-start gap-7 rounded-[26px] bg-neutral-100 px-[22px] pb-5 pt-[30px] font-neue text-sm tracking-tight transition-shadow duration-300 hover:shadow-lg"
onClick={onClick}
data-testid="featured-store-card"
>
<div className="flex flex-col items-start justify-start self-stretch">
<div className="self-stretch text-2xl font-medium md:text-4xl">
<div className="flex h-[188px] w-full flex-col items-start justify-start gap-3 group-hover:h-fit">
<h2 className="font-['Poppins'] text-[35px] font-medium leading-10 text-neutral-900">
{agentName}
</div>
<div className="self-stretch font-normal text-[#737373]">
by {creatorName}
</div>
</h2>
<p className="font-['Geist'] text-xl font-normal leading-7 text-neutral-800">
{subHeading}
</p>
</div>
<div className="max-h-18 w-full flex-grow text-clip font-normal text-[#282828] md:w-[33.75rem]">
{description.length > 170
? `${description.slice(0, 170)}...`
: description}
</div>
<div className="flex flex-col items-start justify-end gap-3 self-stretch">
<div className="relative aspect-[540/245] w-full">
<Image
src={agentImage}
alt={`${agentName} preview`}
layout="fill"
objectFit="cover"
className="rounded-xl"
/>
</div>
<div className="flex items-center justify-between self-stretch">
<div>
<span className="font-medium">{runs.toLocaleString()}+</span>
<span className="font-normal"> runs</span>
<div className="relative w-full flex-1">
{/* Default view */}
<div className="absolute inset-0 flex flex-col gap-[18px] group-hover:opacity-0">
<p className="font-['Geist'] text-xl font-normal leading-7 text-neutral-800">
by {creatorName}
</p>
<div className="relative aspect-square w-full flex-1">
<Image
src={agentImage}
alt={`${agentName} preview`}
width={396}
height={396}
className="aspect-square rounded-xl object-cover"
/>
</div>
<div className="flex items-center gap-2">
<div className="font-normal">{rating.toFixed(1)}</div>
<div className="flex items-center justify-start gap-px">
{StarRatingIcons(rating)}
</div>
</div>
{/* Hovered view */}
<div className="absolute inset-0 flex flex-col gap-[18px] opacity-0 group-hover:opacity-100">
<p className="font-['Geist'] text-xl font-normal leading-7 text-neutral-800">
by {creatorName}
</p>
<div className="flex-1 overflow-y-auto rounded-xl py-4">
<p className="font-['Geist'] text-xl font-normal leading-7 text-neutral-800">
{description}
</p>
</div>
</div>
</div>
<div className="flex w-full items-center justify-between">
<div className="font-['Inter'] text-lg font-semibold leading-7 text-neutral-800">
{runs.toLocaleString()} runs
</div>
<div className="flex items-center gap-[5px]">
<div className="font-['Inter'] text-lg font-semibold leading-7 text-neutral-800">
{rating.toFixed(1)}
</div>
<div className="flex w-[84px] items-center justify-start gap-px">
{StarRatingIcons(rating)}
</div>
</div>
</div>

View File

@@ -27,7 +27,8 @@ interface NavbarProps {
}[];
}
{/* <div className="w-[1408px] h-20 pl-6 pr-3 py-3 bg-white/5 rounded-bl-2xl rounded-br-2xl border border-white/50 backdrop-blur-[26px] justify-between items-center inline-flex">
{
/* <div className="w-[1408px] h-20 pl-6 pr-3 py-3 bg-white/5 rounded-bl-2xl rounded-br-2xl border border-white/50 backdrop-blur-[26px] justify-between items-center inline-flex">
<div className="justify-start items-center gap-11 flex">
<div className="w-[88.87px] h-10 relative" />
<div className="justify-start items-center gap-6 flex">
@@ -55,7 +56,8 @@ interface NavbarProps {
</div>
<img className="w-[60px] h-[60px] rounded-full" src="https://via.placeholder.com/60x60" />
</div>
</div> */}
</div> */
}
export const Navbar: React.FC<NavbarProps> = ({
isLoggedIn,
@@ -68,7 +70,7 @@ export const Navbar: React.FC<NavbarProps> = ({
}) => {
return (
<>
<nav className="hidden w-[1408px] sticky top-0 h-20 pl-6 pr-3 py-3 bg-white/5 rounded-bl-2xl rounded-br-2xl border border-white/50 backdrop-blur-[26px] justify-between items-center md:inline-flex">
<nav className="sticky top-0 hidden h-20 w-[1408px] items-center justify-between rounded-bl-2xl rounded-br-2xl border border-white/50 bg-white/5 py-3 pl-6 pr-3 backdrop-blur-[26px] md:inline-flex">
<div className="flex items-center space-x-10">
{links.map((link) => (
<div key={link.name} className="relative">

View File

@@ -23,7 +23,6 @@ export const StoreCard: React.FC<StoreCardProps> = ({
avatarSrc,
hideAvatar = false,
}) => {
const handleClick = () => {
onClick();
};

View File

@@ -14,13 +14,24 @@ export const HeroSection: React.FC<HeroSectionProps> = ({
return (
<div className="mb-2 mt-8 flex flex-col items-center justify-center px-4 sm:mb-4 sm:mt-12 sm:px-6 md:mb-6 md:mt-16 lg:my-24 lg:px-8 xl:my-16">
<div className="w-full max-w-3xl lg:max-w-4xl xl:max-w-5xl">
<div className="text-center mb-4 8md:mb-8">
<span className="text-neutral-950 text-4xl md:text-5xl font-semibold font-['Poppins'] leading-[54px]">Explore AI agents built for </span>
<span className="text-violet-600 text-4xl md:text-5xl font-semibold font-['Poppins'] leading-[54px]">you<br /></span>
<span className="text-neutral-950 text-4xl md:text-5xl font-semibold font-['Poppins'] leading-[54px]">by the </span>
<span className="text-blue-500 text-4xl md:text-5xl font-semibold font-['Poppins'] leading-[54px]">community</span>
<div className="8md:mb-8 mb-4 text-center">
<span className="font-['Poppins'] text-4xl font-semibold leading-[54px] text-neutral-950 md:text-5xl">
Explore AI agents built for{" "}
</span>
<span className="font-['Poppins'] text-4xl font-semibold leading-[54px] text-violet-600 md:text-5xl">
you
<br />
</span>
<span className="font-['Poppins'] text-4xl font-semibold leading-[54px] text-neutral-950 md:text-5xl">
by the{" "}
</span>
<span className="font-['Poppins'] text-4xl font-semibold leading-[54px] text-blue-500 md:text-5xl">
community
</span>
</div>
<div className="mb:text-2xl mb-6 text-center font-['Geist'] text-xl font-normal leading-loose text-neutral-700 md:mb-12">
Bringing you AI agents designed by thinkers from around the world
</div>
<div className="text-neutral-700 text-xl mb:text-2xl font-normal font-['Geist'] leading-loose text-center mb-6 md:mb-12">Bringing you AI agents designed by thinkers from around the world</div>
<div className="mb-4 sm:mb-5 md:mb-6">
<SearchBar onSearch={onSearch} />
</div>

View File

@@ -10,6 +10,3 @@ export default class ClientSideMarketplaceAPI extends BaseMarketplaceAPI {
super(baseUrl, supabaseClient);
}
}