Merge branch 'dev' into ntindle/secrt-1088-add-db-models-for-the-notification-service

This commit is contained in:
Nicholas Tindle
2025-02-11 20:32:47 -06:00
committed by GitHub
18 changed files with 266 additions and 546 deletions

View File

@@ -118,6 +118,7 @@ files = [
[package.dependencies]
aiohappyeyeballs = ">=2.3.0"
aiosignal = ">=1.1.2"
async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""}
attrs = ">=17.3.0"
frozenlist = ">=1.1.1"
multidict = ">=4.5,<7.0"
@@ -208,6 +209,7 @@ files = [
]
[package.dependencies]
exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
idna = ">=2.8"
sniffio = ">=1.1"
typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""}
@@ -354,6 +356,8 @@ mypy-extensions = ">=0.4.3"
packaging = ">=22.0"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
@@ -817,11 +821,12 @@ version = "1.2.2"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
groups = ["main"]
groups = ["main", "dev"]
files = [
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
]
markers = {dev = "python_version < \"3.11\""}
[package.extras]
test = ["pytest (>=6)"]
@@ -1027,8 +1032,14 @@ files = [
[package.dependencies]
google-auth = ">=2.14.1,<3.0.dev0"
googleapis-common-protos = ">=1.56.2,<2.0.dev0"
grpcio = {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}
grpcio-status = {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}
grpcio = [
{version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
{version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
]
grpcio-status = [
{version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
{version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
]
proto-plus = ">=1.22.3,<2.0.0dev"
protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0"
requests = ">=2.18.0,<3.0.0.dev0"
@@ -1191,7 +1202,10 @@ google-cloud-audit-log = ">=0.2.4,<1.0.0dev"
google-cloud-core = ">=2.0.0,<3.0.0dev"
grpc-google-iam-v1 = ">=0.12.4,<1.0.0dev"
opentelemetry-api = ">=1.9.0"
proto-plus = {version = ">=1.22.2,<2.0.0dev", markers = "python_version >= \"3.11\""}
proto-plus = [
{version = ">=1.22.2,<2.0.0dev", markers = "python_version >= \"3.11\""},
{version = ">=1.22.0,<2.0.0dev", markers = "python_version < \"3.11\""},
]
protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0dev"
[[package]]
@@ -1328,14 +1342,14 @@ pydantic = ">=1.10,<3"
[[package]]
name = "gravitasml"
version = "0.1.2"
version = "0.1.3"
description = ""
optional = false
python-versions = "<3.13,>=3.11"
python-versions = "<4.0,>=3.10"
groups = ["main"]
files = [
{file = "gravitasml-0.1.2-py3-none-any.whl", hash = "sha256:eafa5a65a6f952f0d23c54762f5fcb654b3f000ede389519a7dc3c3179801121"},
{file = "gravitasml-0.1.2.tar.gz", hash = "sha256:bbb651a9d5be669d47cc5bd7fbf19d55ce277b3dd9966cc37d2ec0ae042aab25"},
{file = "gravitasml-0.1.3-py3-none-any.whl", hash = "sha256:51ff98b4564b7a61f7796f18d5f2558b919d30b3722579296089645b7bc18b85"},
{file = "gravitasml-0.1.3.tar.gz", hash = "sha256:04d240b9fa35878252d57a36032130b6516487468847fcdced1022c032a20f57"},
]
[package.dependencies]
@@ -2352,6 +2366,9 @@ files = [
{file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"},
]
[package.dependencies]
typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""}
[[package]]
name = "mypy-extensions"
version = "1.0.0"
@@ -2785,6 +2802,7 @@ files = [
[package.dependencies]
pastel = ">=0.2.1,<0.3.0"
pyyaml = ">=6.0.2,<7.0.0"
tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""}
[package.extras]
poetry-plugin = ["poetry (>=1.0,<3.0)"]
@@ -2825,6 +2843,7 @@ files = [
deprecation = ">=2.1.0,<3.0.0"
httpx = {version = ">=0.26,<0.29", extras = ["http2"]}
pydantic = ">=1.9,<3.0"
strenum = {version = ">=0.4.9,<0.5.0", markers = "python_version < \"3.11\""}
[[package]]
name = "posthog"
@@ -2915,6 +2934,7 @@ jinja2 = ">=2.11.2"
nodeenv = "*"
pydantic = ">=1.10.0,<3"
python-dotenv = ">=0.12.0"
StrEnum = {version = "*", markers = "python_version < \"3.11\""}
tomlkit = "*"
typing-extensions = ">=4.5.0"
@@ -3492,9 +3512,11 @@ files = [
[package.dependencies]
colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=1.5,<2"
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras]
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
@@ -3549,6 +3571,7 @@ files = [
]
[package.dependencies]
tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""}
watchdog = ">=2.0.0"
[[package]]
@@ -4360,6 +4383,49 @@ files = [
[package.dependencies]
requests = ">=2.32.3,<3.0.0"
[[package]]
name = "tomli"
version = "2.2.1"
description = "A lil' TOML parser"
optional = false
python-versions = ">=3.8"
groups = ["main", "dev"]
markers = "python_version < \"3.11\""
files = [
{file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
{file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
{file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
{file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
{file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
{file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
{file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
{file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
{file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
{file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
{file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
{file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
{file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
{file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
]
[[package]]
name = "tomlkit"
version = "0.13.2"
@@ -4530,6 +4596,7 @@ h11 = ">=0.8"
httptools = {version = ">=0.6.3", optional = true, markers = "extra == \"standard\""}
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
@@ -5054,5 +5121,5 @@ type = ["pytest-mypy"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.11,<3.13"
content-hash = "cde4ebe235dd4140000074e1654f1731daf015de1297acb695c5060609fa95c0"
python-versions = ">=3.10,<3.13"
content-hash = "a3af2c13c3fce626006c6469263e44cc7f1b8c26e3d0a6beabd1b33caac35128"

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "autogpt-platform-backend"
version = "0.3.4"
version = "0.4.9"
description = "A platform for building AI-powered agentic workflows"
authors = ["AutoGPT <info@agpt.co>"]
readme = "README.md"
@@ -8,12 +8,13 @@ packages = [{ include = "backend", format = "sdist" }]
[tool.poetry.dependencies]
python = ">=3.11,<3.13"
python = ">=3.10,<3.13"
aio-pika = "^9.5.4"
anthropic = "^0.45.2"
apscheduler = "^3.11.0"
autogpt-libs = { path = "../autogpt_libs", develop = true }
click = "^8.1.7"
cryptography = "^43.0"
discord-py = "^2.4.0"
e2b-code-interpreter = "^1.0.5"
fastapi = "^0.115.8"
@@ -21,58 +22,59 @@ feedparser = "^6.0.11"
flake8 = "^7.0.0"
google-api-python-client = "^2.160.0"
google-auth-oauthlib = "^1.2.1"
google-cloud-storage = "^3.0.0"
googlemaps = "^4.10.0"
gravitasml = "^0.1.3"
groq = "^0.18.0"
jinja2 = "^3.1.4"
jsonref = "^1.1.0"
jsonschema = "^4.22.0"
launchdarkly-server-sdk = "^9.8.0"
mem0ai = "^0.1.48"
moviepy = "^2.1.2"
ollama = "^0.4.1"
openai = "^1.61.1"
pika = "^1.3.2"
pinecone = "^5.3.1"
praw = "~7.8.1"
prisma = "^0.15.0"
psutil = "^6.1.0"
psycopg2-binary = "^2.9.10"
pydantic = {extras = ["email"], version = "^2.10.6"}
pydantic-settings = "^2.3.4"
pyro5 = "^5.15"
pytest = "^8.2.1"
pytest-asyncio = "^0.25.3"
python-dotenv = "^1.0.1"
python-multipart = "^0.0.20"
redis = "^5.2.0"
replicate = "^1.0.4"
sentry-sdk = "2.20.0"
sqlalchemy = "^2.0.36"
strenum = "^0.4.9"
stripe = "^11.5.0"
supabase = "2.13.0"
tenacity = "^9.0.0"
todoist-api-python = "^2.1.7"
tweepy = "^4.14.0"
uvicorn = { extras = ["standard"], version = "^0.34.0" }
websockets = "^13.1"
youtube-transcript-api = "^0.6.2"
googlemaps = "^4.10.0"
replicate = "^1.0.4"
pinecone = "^5.3.1"
cryptography = "^43.0"
python-multipart = "^0.0.20"
sqlalchemy = "^2.0.36"
psycopg2-binary = "^2.9.10"
google-cloud-storage = "^3.0.0"
launchdarkly-server-sdk = "^9.8.0"
mem0ai = "^0.1.48"
todoist-api-python = "^2.1.7"
moviepy = "^2.1.2"
gravitasml = "0.1.2"
pika = "^1.3.2"
# NOTE: please insert new dependencies in their alphabetical location
[tool.poetry.group.dev.dependencies]
poethepoet = "^0.32.1"
aiohappyeyeballs = "^2.4.4"
black = "^24.10.0"
faker = "^33.3.1"
httpx = "^0.27.0"
isort = "^5.13.2"
poethepoet = "^0.32.1"
pyright = "^1.1.392"
pytest-mock = "^3.14.0"
pytest-watcher = "^0.4.2"
requests = "^2.32.3"
ruff = "^0.9.2"
pyright = "^1.1.392"
isort = "^5.13.2"
black = "^24.10.0"
aiohappyeyeballs = "^2.4.4"
pytest-mock = "^3.14.0"
faker = "^33.3.1"
# NOTE: please insert new dependencies in their alphabetical location
[build-system]
requires = ["poetry-core"]

View File

@@ -66,7 +66,7 @@ export default async function RootLayout({
{
icon: IconType.Edit,
text: "Edit profile",
href: "/marketplace/profile",
href: "/profile",
},
],
},
@@ -75,7 +75,7 @@ export default async function RootLayout({
{
icon: IconType.LayoutDashboard,
text: "Creator Dashboard",
href: "/marketplace/dashboard",
href: "/profile/dashboard",
},
{
icon: IconType.UploadCloud,
@@ -88,7 +88,7 @@ export default async function RootLayout({
{
icon: IconType.Settings,
text: "Settings",
href: "/marketplace/settings",
href: "/profile/settings",
},
],
},

View File

@@ -1,9 +1,6 @@
import * as React from "react";
import { HeroSection } from "@/components/agptui/composite/HeroSection";
import {
FeaturedSection,
FeaturedAgent,
} from "@/components/agptui/composite/FeaturedSection";
import { FeaturedSection } from "@/components/agptui/composite/FeaturedSection";
import {
AgentsSection,
Agent,
@@ -155,9 +152,7 @@ export default async function Page({}: {}) {
<div className="mx-auto w-screen max-w-[1360px]">
<main className="px-4">
<HeroSection />
<FeaturedSection
featuredAgents={featuredAgents.agents as FeaturedAgent[]}
/>
<FeaturedSection featuredAgents={featuredAgents.agents} />
<Separator />
<AgentsSection
sectionTitle="Top Agents"

View File

@@ -2,7 +2,6 @@
import * as React from "react";
import { AgentTable } from "@/components/agptui/AgentTable";
import { AgentTableRowProps } from "@/components/agptui/AgentTableRow";
import { Button } from "@/components/agptui/Button";
import { Separator } from "@/components/ui/separator";
import { StatusType } from "@/components/agptui/Status";

View File

@@ -2,10 +2,9 @@
import { Button } from "@/components/ui/button";
import { useRouter } from "next/navigation";
import { useCallback, useContext, useMemo, useState } from "react";
import { Separator } from "@/components/ui/separator";
import { useToast } from "@/components/ui/use-toast";
import { IconKey, IconUser } from "@/components/ui/icons";
import { LogOutIcon, Trash2Icon } from "lucide-react";
import { Trash2Icon } from "lucide-react";
import { providerIcons } from "@/components/integrations/credentials-input";
import { CredentialsProvidersContext } from "@/components/integrations/credentials-provider";
import {

View File

@@ -5,13 +5,13 @@ export default function Layout({ children }: { children: React.ReactNode }) {
const sidebarLinkGroups = [
{
links: [
{ text: "Creator Dashboard", href: "/marketplace/dashboard" },
{ text: "Agent dashboard", href: "/marketplace/agent-dashboard" },
{ text: "Billing", href: "/marketplace/credits" },
{ text: "Integrations", href: "/marketplace/integrations" },
{ text: "API Keys", href: "/marketplace/api_keys" },
{ text: "Profile", href: "/marketplace/profile" },
{ text: "Settings", href: "/marketplace/settings" },
{ text: "Creator Dashboard", href: "/profile/dashboard" },
{ text: "Agent dashboard", href: "/profile/agent-dashboard" },
{ text: "Billing", href: "/profile/credits" },
{ text: "Integrations", href: "/profile/integrations" },
{ text: "API Keys", href: "/profile/api_keys" },
{ text: "Profile", href: "/profile" },
{ text: "Settings", href: "/profile/settings" },
],
},
];

View File

@@ -1,242 +0,0 @@
"use client";
import { Button } from "@/components/ui/button";
import { useRouter } from "next/navigation";
import { useCallback, useContext, useMemo, useState } from "react";
import { Separator } from "@/components/ui/separator";
import { useToast } from "@/components/ui/use-toast";
import { IconKey, IconUser } from "@/components/ui/icons";
import { LogOutIcon, Trash2Icon } from "lucide-react";
import { providerIcons } from "@/components/integrations/credentials-input";
import { CredentialsProvidersContext } from "@/components/integrations/credentials-provider";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { CredentialsProviderName } from "@/lib/autogpt-server-api";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import useSupabase from "@/hooks/useSupabase";
import Spinner from "@/components/Spinner";
export default function PrivatePage() {
const { supabase, user, isUserLoading } = useSupabase();
const router = useRouter();
const providers = useContext(CredentialsProvidersContext);
const { toast } = useToast();
const [confirmationDialogState, setConfirmationDialogState] = useState<
| {
open: true;
message: string;
onConfirm: () => void;
onReject: () => void;
}
| { open: false }
>({ open: false });
const removeCredentials = useCallback(
async (
provider: CredentialsProviderName,
id: string,
force: boolean = false,
) => {
if (!providers || !providers[provider]) {
return;
}
let result;
try {
result = await providers[provider].deleteCredentials(id, force);
} catch (error: any) {
toast({
title: "Something went wrong when deleting credentials: " + error,
variant: "destructive",
duration: 2000,
});
setConfirmationDialogState({ open: false });
return;
}
if (result.deleted) {
if (result.revoked) {
toast({
title: "Credentials deleted",
duration: 2000,
});
} else {
toast({
title: "Credentials deleted from AutoGPT",
description: `You may also manually remove the connection to AutoGPT at ${provider}!`,
duration: 3000,
});
}
setConfirmationDialogState({ open: false });
} else if (result.need_confirmation) {
setConfirmationDialogState({
open: true,
message: result.message,
onConfirm: () => removeCredentials(provider, id, true),
onReject: () => setConfirmationDialogState({ open: false }),
});
}
},
[providers, toast],
);
//TODO: remove when the way system credentials are handled is updated
// This contains ids for built-in "Use Credits for X" credentials
const hiddenCredentials = useMemo(
() => [
"744fdc56-071a-4761-b5a5-0af0ce10a2b5", // Ollama
"fdb7f412-f519-48d1-9b5f-d2f73d0e01fe", // Revid
"760f84fc-b270-42de-91f6-08efe1b512d0", // Ideogram
"6b9fc200-4726-4973-86c9-cd526f5ce5db", // Replicate
"53c25cb8-e3ee-465c-a4d1-e75a4c899c2a", // OpenAI
"24e5d942-d9e3-4798-8151-90143ee55629", // Anthropic
"4ec22295-8f97-4dd1-b42b-2c6957a02545", // Groq
"7f7b0654-c36b-4565-8fa7-9a52575dfae2", // D-ID
"7f26de70-ba0d-494e-ba76-238e65e7b45f", // Jina
"66f20754-1b81-48e4-91d0-f4f0dd82145f", // Unreal Speech
"b5a0e27d-0c98-4df3-a4b9-10193e1f3c40", // Open Router
"6c0f5bd0-9008-4638-9d79-4b40b631803e", // FAL
"96153e04-9c6c-4486-895f-5bb683b1ecec", // Exa
"78d19fd7-4d59-4a16-8277-3ce310acf2b7", // E2B
"96b83908-2789-4dec-9968-18f0ece4ceb3", // Nvidia
"ed55ac19-356e-4243-a6cb-bc599e9b716f", // Mem0
],
[],
);
if (isUserLoading) {
return <Spinner />;
}
if (!user || !supabase) {
router.push("/login");
return null;
}
const allCredentials = providers
? Object.values(providers).flatMap((provider) =>
[
...provider.savedOAuthCredentials,
...provider.savedApiKeys,
...provider.savedUserPasswordCredentials,
]
.filter((cred) => !hiddenCredentials.includes(cred.id))
.map((credentials) => ({
...credentials,
provider: provider.provider,
providerName: provider.providerName,
ProviderIcon: providerIcons[provider.provider],
TypeIcon: {
oauth2: IconUser,
api_key: IconKey,
user_password: IconKey,
}[credentials.type],
})),
)
: [];
return (
<div className="mx-auto max-w-3xl md:py-8">
<div className="flex items-center justify-between">
<p>
Hello <span data-testid="profile-email">{user.email}</span>
</p>
<Button onClick={() => supabase.auth.signOut()}>
<LogOutIcon className="mr-1.5 size-4" />
Log out
</Button>
</div>
<Separator className="my-6" />
<h2 className="mb-4 text-lg">Connections & Credentials</h2>
<Table>
<TableHeader>
<TableRow>
<TableHead>Provider</TableHead>
<TableHead>Name</TableHead>
<TableHead>Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{allCredentials.map((cred) => (
<TableRow key={cred.id}>
<TableCell>
<div className="flex items-center space-x-1.5">
<cred.ProviderIcon className="h-4 w-4" />
<strong>{cred.providerName}</strong>
</div>
</TableCell>
<TableCell>
<div className="flex h-full items-center space-x-1.5">
<cred.TypeIcon />
<span>{cred.title || cred.username}</span>
</div>
<small className="text-muted-foreground">
{
{
oauth2: "OAuth2 credentials",
api_key: "API key",
user_password: "User password",
}[cred.type]
}{" "}
- <code>{cred.id}</code>
</small>
</TableCell>
<TableCell className="w-0 whitespace-nowrap">
<Button
variant="destructive"
onClick={() => removeCredentials(cred.provider, cred.id)}
>
<Trash2Icon className="mr-1.5 size-4" /> Delete
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<AlertDialog open={confirmationDialogState.open}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
<AlertDialogDescription>
{confirmationDialogState.open && confirmationDialogState.message}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel
onClick={() =>
confirmationDialogState.open &&
confirmationDialogState.onReject()
}
>
Cancel
</AlertDialogCancel>
<AlertDialogAction
variant="destructive"
onClick={() =>
confirmationDialogState.open &&
confirmationDialogState.onConfirm()
}
>
Continue
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
);
}

View File

@@ -0,0 +1,77 @@
import Image from "next/image";
import { StarRatingIcons } from "@/components/ui/icons";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { useState } from "react";
import { StoreAgent } from "@/lib/autogpt-server-api";
interface FeaturedStoreCardProps {
agent: StoreAgent;
backgroundColor: string;
}
export const FeaturedAgentCard: React.FC<FeaturedStoreCardProps> = ({
agent,
backgroundColor,
}) => {
const [isHovered, setIsHovered] = useState(false);
return (
<Card
data-testid="featured-store-card"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
className={backgroundColor}
>
<CardHeader>
<CardTitle>{agent.agent_name}</CardTitle>
<CardDescription>{agent.description}</CardDescription>
</CardHeader>
<CardContent>
<div className="relative h-[397px] w-full overflow-hidden rounded-xl">
<div
className={`transition-opacity duration-200 ${isHovered ? "opacity-0" : "opacity-100"}`}
>
<Image
src={agent.agent_image || "/AUTOgpt_Logo_dark.png"}
alt={`${agent.agent_name} preview`}
fill
sizes="100%"
className="rounded-xl object-cover"
/>
</div>
<div
className={`absolute inset-0 overflow-y-auto transition-opacity duration-200 ${
isHovered ? "opacity-100" : "opacity-0"
} rounded-xl dark:bg-neutral-700`}
>
<p className="text-base text-neutral-800 dark:text-neutral-200">
{agent.description}
</p>
</div>
</div>
</CardContent>
<CardFooter className="flex items-center justify-between">
<div className="font-semibold">
{agent.runs?.toLocaleString() ?? "0"} runs
</div>
<div className="flex items-center gap-1.5">
<p>{agent.rating.toFixed(1) ?? "0.0"}</p>
<div
className="inline-flex items-center justify-start gap-px"
role="img"
aria-label={`Rating: ${agent.rating.toFixed(1)} out of 5 stars`}
>
{StarRatingIcons(agent.rating)}
</div>
</div>
</CardFooter>
</Card>
);
};

View File

@@ -1,10 +1,10 @@
import type { Meta, StoryObj } from "@storybook/react";
import { FeaturedStoreCard } from "./FeaturedStoreCard";
import { FeaturedAgentCard } from "./FeaturedAgentCard";
import { userEvent, within } from "@storybook/test";
const meta = {
title: "AGPT UI/Featured Store Card",
component: FeaturedStoreCard,
component: FeaturedAgentCard,
parameters: {
layout: {
center: true,
@@ -13,123 +13,63 @@ const meta = {
},
tags: ["autodocs"],
argTypes: {
agentName: { control: "text" },
subHeading: { control: "text" },
agentImage: { control: "text" },
creatorImage: { control: "text" },
creatorName: { control: "text" },
description: { control: "text" },
runs: { control: "number" },
rating: { control: "number", min: 0, max: 5, step: 0.1 },
onClick: { action: "clicked" },
agent: {
agent_name: { control: "text" },
sub_heading: { control: "text" },
agent_image: { control: "text" },
creator_avatar: { control: "text" },
creator: { control: "text" },
runs: { control: "number" },
rating: { control: "number", min: 0, max: 5, step: 0.1 },
slug: { control: "text" },
},
backgroundColor: {
control: "color",
},
},
} satisfies Meta<typeof FeaturedStoreCard>;
} satisfies Meta<typeof FeaturedAgentCard>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
agentName: "Personalized Morning Coffee Newsletter example of three lines",
subHeading:
"Transform ideas into breathtaking images with this AI-powered Image Generator.",
description:
"Elevate your web content with this powerful AI Webpage Copy Improver. Designed for marketers, SEO specialists, and web developers, this tool analyses and enhances website copy for maximum impact. Using advanced language models, it optimizes text for better clarity, SEO performance, and increased conversion rates.",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "AI Solutions Inc.",
runs: 50000,
rating: 4.7,
onClick: () => console.log("Card clicked"),
backgroundColor: "bg-white",
},
};
export const LowRating: Story = {
args: {
agentName: "Data Analyzer Lite",
subHeading: "Basic data analysis tool",
description:
"A lightweight data analysis tool for basic data processing needs.",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "DataTech",
runs: 10000,
rating: 2.8,
onClick: () => console.log("Card clicked"),
backgroundColor: "bg-white",
},
};
export const HighRuns: Story = {
args: {
agentName: "CodeAssist AI",
subHeading: "Your AI coding companion",
description:
"An intelligent coding assistant that helps developers write better code faster.",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "DevTools Co.",
runs: 1000000,
rating: 4.9,
onClick: () => console.log("Card clicked"),
backgroundColor: "bg-white",
},
};
export const NoCreatorImage: Story = {
args: {
agentName: "MultiTasker",
subHeading: "All-in-one productivity suite",
description:
"A comprehensive productivity suite that combines task management, note-taking, and project planning into one seamless interface.",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "Productivity Plus",
runs: 75000,
rating: 4.5,
onClick: () => console.log("Card clicked"),
backgroundColor: "bg-white",
},
};
export const ShortDescription: Story = {
args: {
agentName: "QuickTask",
subHeading: "Fast task automation",
description: "Simple and efficient task automation tool.",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "EfficientWorks",
runs: 50000,
rating: 4.2,
onClick: () => console.log("Card clicked"),
agent: {
agent_name:
"Personalized Morning Coffee Newsletter example of three lines",
sub_heading:
"Transform ideas into breathtaking images with this AI-powered Image Generator.",
description:
"Elevate your web content with this powerful AI Webpage Copy Improver. Designed for marketers, SEO specialists, and web developers, this tool analyses and enhances website copy for maximum impact. Using advanced language models, it optimizes text for better clarity, SEO performance, and increased conversion rates.",
agent_image:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creator_avatar:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creator: "AI Solutions Inc.",
runs: 50000,
rating: 4.7,
slug: "",
},
backgroundColor: "bg-white",
},
};
export const WithInteraction: Story = {
args: {
agentName: "AI Writing Assistant",
subHeading: "Enhance your writing",
description:
"An AI-powered writing assistant that helps improve your writing style and clarity.",
agentImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorImage:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creatorName: "WordCraft AI",
runs: 200000,
rating: 4.6,
onClick: () => console.log("Card clicked"),
agent: {
slug: "",
agent_name: "AI Writing Assistant",
sub_heading: "Enhance your writing",
description:
"An AI-powered writing assistant that helps improve your writing style and clarity.",
agent_image:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creator_avatar:
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
creator: "WordCraft AI",
runs: 200000,
rating: 4.6,
},
backgroundColor: "bg-white",
},
play: async ({ canvasElement }) => {

View File

@@ -1,96 +0,0 @@
import * as React from "react";
import Image from "next/image";
import { StarRatingIcons } from "@/components/ui/icons";
interface FeaturedStoreCardProps {
agentName: string;
subHeading: string;
agentImage: string;
creatorImage?: string;
creatorName: string;
description: string; // Added description prop
runs: number;
rating: number;
onClick: () => void;
backgroundColor: string;
}
export const FeaturedStoreCard: React.FC<FeaturedStoreCardProps> = ({
agentName,
subHeading,
agentImage,
creatorImage,
creatorName,
description,
runs,
rating,
onClick,
backgroundColor,
}) => {
return (
<div
className={`group h-[755px] w-[440px] px-[22px] pb-5 pt-[30px] ${backgroundColor} inline-flex flex-col items-start justify-start gap-7 rounded-[26px] transition-all duration-200 hover:brightness-95 dark:bg-neutral-800`}
onClick={onClick}
data-testid="featured-store-card"
>
<div className="flex h-[188px] flex-col items-start justify-start gap-3 self-stretch">
<h2 className="font-poppins self-stretch text-[35px] font-medium leading-10 text-neutral-900 dark:text-neutral-100">
{agentName}
</h2>
<div className="font-lead self-stretch text-xl font-normal leading-7 text-neutral-800 dark:text-neutral-200">
{subHeading}
</div>
</div>
<div className="flex h-[489px] flex-col items-start justify-start gap-[18px] self-stretch">
<div className="font-lead self-stretch text-xl font-normal leading-7 text-neutral-800 dark:text-neutral-200">
by {creatorName}
</div>
<div className="relative h-[397px] self-stretch">
<Image
src={agentImage}
alt={`${agentName} preview`}
layout="fill"
objectFit="cover"
className="rounded-xl transition-opacity duration-200 group-hover:opacity-0"
/>
<div className="absolute inset-0 overflow-y-auto rounded-xl bg-white p-4 opacity-0 transition-opacity duration-200 group-hover:opacity-100 dark:bg-neutral-700">
<div className="font-geist text-base font-normal leading-normal text-neutral-800 dark:text-neutral-200">
{description}
</div>
</div>
{creatorImage && (
<div className="absolute left-[8.74px] top-[313px] h-[74px] w-[74px] overflow-hidden rounded-full transition-opacity duration-200 group-hover:opacity-0">
<Image
src={creatorImage}
alt={`${creatorName} image`}
layout="fill"
className="object-cover"
priority
/>
</div>
)}
</div>
<div className="inline-flex items-center justify-between self-stretch">
<div className="font-large-geist text-lg font-semibold leading-7 text-neutral-800 dark:text-neutral-200">
{runs.toLocaleString()} runs
</div>
<div className="flex items-center justify-start gap-[5px]">
<div className="font-large-geist text-lg font-semibold leading-7 text-neutral-800 dark:text-neutral-200">
{rating.toFixed(1)}
</div>
<div
className="inline-flex items-center justify-start gap-px"
role="img"
aria-label={`Rating: ${rating.toFixed(1)} out of 5 stars`}
>
{StarRatingIcons(rating)}
</div>
</div>
</div>
</div>
</div>
);
};

View File

@@ -46,7 +46,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
<div className="h-full w-full rounded-2xl bg-zinc-200 dark:bg-zinc-800">
<div className="inline-flex h-[264px] flex-col items-start justify-start gap-6 p-3">
<Link
href="/marketplace/dashboard"
href="/profile/dashboard"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconDashboardLayout className="h-6 w-6" />
@@ -56,7 +56,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</Link>
{stripeAvailable && (
<Link
href="/marketplace/credits"
href="/profile/credits"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconCoin className="h-6 w-6" />
@@ -66,7 +66,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</Link>
)}
<Link
href="/marketplace/integrations"
href="/profile/integrations"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconIntegrations className="h-6 w-6" />
@@ -75,7 +75,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</div>
</Link>
<Link
href="/marketplace/api_keys"
href="/profile/api_keys"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<KeyIcon className="h-6 w-6" />
@@ -84,7 +84,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</div>
</Link>
<Link
href="/marketplace/profile"
href="/profile"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconProfile className="h-6 w-6" />
@@ -93,7 +93,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</div>
</Link>
<Link
href="/marketplace/settings"
href="/profile/settings"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconSliders className="h-6 w-6" />
@@ -110,7 +110,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
<div className="h-full w-full rounded-2xl bg-zinc-200 dark:bg-zinc-800">
<div className="inline-flex h-[264px] flex-col items-start justify-start gap-6 p-3">
<Link
href="/marketplace/dashboard"
href="/profile/dashboard"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconDashboardLayout className="h-6 w-6" />
@@ -120,7 +120,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</Link>
{stripeAvailable && (
<Link
href="/marketplace/credits"
href="/profile/credits"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconCoin className="h-6 w-6" />
@@ -130,7 +130,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</Link>
)}
<Link
href="/marketplace/integrations"
href="/profile/integrations"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconIntegrations className="h-6 w-6" />
@@ -139,7 +139,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</div>
</Link>
<Link
href="/marketplace/api_keys"
href="/profile/api_keys"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<KeyIcon className="h-6 w-6" strokeWidth={1} />
@@ -148,7 +148,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</div>
</Link>
<Link
href="/marketplace/profile"
href="/profile"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconProfile className="h-6 w-6" />
@@ -157,7 +157,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
</div>
</Link>
<Link
href="/marketplace/settings"
href="/profile/settings"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconSliders className="h-6 w-6" />

View File

@@ -1,6 +1,7 @@
import type { Meta, StoryObj } from "@storybook/react";
import { FeaturedAgent, FeaturedSection } from "./FeaturedSection";
import { userEvent, within, expect } from "@storybook/test";
import { FeaturedSection } from "./FeaturedSection";
import { userEvent, within } from "@storybook/test";
import { StoreAgent } from "@/lib/autogpt-server-api";
const meta = {
title: "AGPT UI/Composite/Featured Agents",
@@ -15,7 +16,6 @@ const meta = {
tags: ["autodocs"],
argTypes: {
featuredAgents: { control: "object" },
// onCardClick: { action: "clicked" },
},
} satisfies Meta<typeof FeaturedSection>;
@@ -93,7 +93,7 @@ const mockFeaturedAgents = [
"https://framerusercontent.com/images/KCIpxr9f97EGJgpaoqnjKsrOPwI.jpg",
slug: "quicktask",
},
] satisfies FeaturedAgent[];
] satisfies StoreAgent[];
export const Default: Story = {
args: {

View File

@@ -1,7 +1,7 @@
"use client";
import * as React from "react";
import { FeaturedStoreCard } from "@/components/agptui/FeaturedStoreCard";
import { FeaturedAgentCard } from "@/components/agptui/FeaturedAgentCard";
import {
Carousel,
CarouselContent,
@@ -11,7 +11,8 @@ import {
CarouselIndicator,
} from "@/components/ui/carousel";
import { useCallback, useState } from "react";
import { useRouter } from "next/navigation";
import { StoreAgent } from "@/lib/autogpt-server-api";
import Link from "next/link";
const BACKGROUND_COLORS = [
"bg-violet-200 dark:bg-violet-800", // #ddd6fe / #5b21b6
@@ -19,33 +20,14 @@ const BACKGROUND_COLORS = [
"bg-green-200 dark:bg-green-800", // #bbf7d0 / #065f46
];
export interface FeaturedAgent {
slug: string;
agent_name: string;
agent_image: string;
creator: string;
creator_avatar: string;
sub_heading: string;
description: string;
runs: number;
rating: number;
}
interface FeaturedSectionProps {
featuredAgents: FeaturedAgent[];
featuredAgents: StoreAgent[];
}
export const FeaturedSection: React.FC<FeaturedSectionProps> = ({
featuredAgents,
}) => {
const [currentSlide, setCurrentSlide] = useState(0);
const router = useRouter();
const handleCardClick = (creator: string, slug: string) => {
router.push(
`/marketplace/agent/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}`,
);
};
const handlePrevSlide = useCallback(() => {
setCurrentSlide((prev) =>
@@ -84,17 +66,14 @@ export const FeaturedSection: React.FC<FeaturedSectionProps> = ({
key={index}
className="max-w-[460px] flex-[0_0_auto]"
>
<FeaturedStoreCard
agentName={agent.agent_name}
subHeading={agent.sub_heading}
agentImage={agent.agent_image}
creatorName={agent.creator}
description={agent.description}
runs={agent.runs}
rating={agent.rating}
backgroundColor={getBackgroundColor(index)}
onClick={() => handleCardClick(agent.creator, agent.slug)}
/>
<Link
href={`/marketplace/agent/${encodeURIComponent(agent.creator)}/${encodeURIComponent(agent.slug)}`}
>
<FeaturedAgentCard
agent={agent}
backgroundColor={getBackgroundColor(index)}
/>
</Link>
</CarouselItem>
))}
</CarouselContent>