From 2fda8dfd32dcff7db445704d03da719bbcc73ddb Mon Sep 17 00:00:00 2001 From: Ubbe Date: Thu, 10 Jul 2025 22:06:12 +0400 Subject: [PATCH] feat(frontend): new navbar design (#10341) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes 🏗️ Screenshot 2025-07-10 at 20 12 38

Navbar updated to look pretty from the new designs: - the logo is now centred instead of on the left - menu items have been updated to a smaller font-size and less radius - icons have been updated I also generated the API files ( _sorry for the noise_ ). I had to do some border-radius and button updates on the atoms/tokens for it to look good. ## Checklist 📋 ## For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Login/logout - [x] The new navbar looks good across screens ## For configuration changes No config changes --- .../src/app/(platform)/build/page.tsx | 21 +- .../frontend/src/app/(platform)/layout.tsx | 61 +- .../src/app/(platform)/library/page.tsx | 6 +- .../endpoints/integrations/integrations.ts | 828 ++---------------- .../models/credentialsMetaInput.ts | 4 +- .../models/libraryAgentTriggerInfo.ts | 4 +- .../api/__generated__/models/providerName.ts | 53 ++ .../app/api/__generated__/models/webhook.ts | 4 +- .../frontend/src/app/api/openapi.json | 263 +++--- .../frontend/src/components/agptui/Navbar.tsx | 131 --- .../src/components/agptui/NavbarLink.tsx | 66 -- .../frontend/src/components/agptui/Wallet.tsx | 2 +- .../atoms/Button/Button.stories.tsx | 2 +- .../src/components/atoms/Button/Button.tsx | 143 ++- .../src/components/atoms/Button/helpers.tsx | 55 ++ .../src/components/layout/Navbar/Navbar.tsx | 84 ++ .../components/AccountMenu/AccountMenu.tsx} | 69 +- .../components/AccountLogoutOption.tsx} | 6 +- .../layout/Navbar/components/LoginButton.tsx | 29 + .../components/MobileNavbar}/MobileNavBar.tsx | 106 +-- .../components/MobileNavbarMenuItem.tsx | 55 ++ .../layout/Navbar/components/NavbarLink.tsx | 68 ++ .../Navbar/components/NavbarLoading.tsx | 21 + .../src/components/layout/Navbar/data.ts | 29 + .../src/components/layout/Navbar/helpers.tsx | 115 +++ .../frontend/src/components/styles/colors.ts | 24 + .../tokens/border-radius.stories.tsx | 77 +- .../src/components/tokens/colors.stories.tsx | 4 + .../src/components/ui/scroll-area.tsx | 4 +- .../frontend/src/lib/supabase/actions.ts | 2 + .../src/lib/supabase/hooks/useSupabase.ts | 9 +- autogpt_platform/frontend/tailwind.config.ts | 94 +- 32 files changed, 923 insertions(+), 1516 deletions(-) create mode 100644 autogpt_platform/frontend/src/app/api/__generated__/models/providerName.ts delete mode 100644 autogpt_platform/frontend/src/components/agptui/Navbar.tsx delete mode 100644 autogpt_platform/frontend/src/components/agptui/NavbarLink.tsx create mode 100644 autogpt_platform/frontend/src/components/atoms/Button/helpers.tsx create mode 100644 autogpt_platform/frontend/src/components/layout/Navbar/Navbar.tsx rename autogpt_platform/frontend/src/components/{agptui/ProfilePopoutMenu.tsx => layout/Navbar/components/AccountMenu/AccountMenu.tsx} (74%) rename autogpt_platform/frontend/src/components/{agptui/ProfilePopoutMenuLogoutButton.tsx => layout/Navbar/components/AccountMenu/components/AccountLogoutOption.tsx} (90%) create mode 100644 autogpt_platform/frontend/src/components/layout/Navbar/components/LoginButton.tsx rename autogpt_platform/frontend/src/components/{agptui => layout/Navbar/components/MobileNavbar}/MobileNavBar.tsx (62%) create mode 100644 autogpt_platform/frontend/src/components/layout/Navbar/components/MobileNavbar/components/MobileNavbarMenuItem.tsx create mode 100644 autogpt_platform/frontend/src/components/layout/Navbar/components/NavbarLink.tsx create mode 100644 autogpt_platform/frontend/src/components/layout/Navbar/components/NavbarLoading.tsx create mode 100644 autogpt_platform/frontend/src/components/layout/Navbar/data.ts create mode 100644 autogpt_platform/frontend/src/components/layout/Navbar/helpers.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/build/page.tsx b/autogpt_platform/frontend/src/app/(platform)/build/page.tsx index ed8ff0a1ba..725cf6c77b 100644 --- a/autogpt_platform/frontend/src/app/(platform)/build/page.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/build/page.tsx @@ -1,12 +1,13 @@ "use client"; -import { useSearchParams } from "next/navigation"; -import { GraphID } from "@/lib/autogpt-server-api/types"; import FlowEditor from "@/components/Flow"; import { useOnboarding } from "@/components/onboarding/onboarding-provider"; -import { useEffect } from "react"; +import LoadingBox from "@/components/ui/loading"; +import { GraphID } from "@/lib/autogpt-server-api/types"; +import { useSearchParams } from "next/navigation"; +import { Suspense, useEffect } from "react"; -export default function BuilderPage() { +function BuilderContent() { const query = useSearchParams(); const { completeStep } = useOnboarding(); @@ -15,12 +16,20 @@ export default function BuilderPage() { }, [completeStep]); const _graphVersion = query.get("flowVersion"); - const graphVersion = _graphVersion ? parseInt(_graphVersion) : undefined + const graphVersion = _graphVersion ? parseInt(_graphVersion) : undefined; return ( ); } + +export default function BuilderPage() { + return ( + }> + + + ); +} diff --git a/autogpt_platform/frontend/src/app/(platform)/layout.tsx b/autogpt_platform/frontend/src/app/(platform)/layout.tsx index 10a278f5f7..3146df9e6b 100644 --- a/autogpt_platform/frontend/src/app/(platform)/layout.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/layout.tsx @@ -1,67 +1,10 @@ +import { Navbar } from "@/components/layout/Navbar/Navbar"; import { ReactNode } from "react"; -import { Navbar } from "@/components/agptui/Navbar"; -import { IconType } from "@/components/ui/icons"; export default function PlatformLayout({ children }: { children: ReactNode }) { return ( <> - +
{children}
); diff --git a/autogpt_platform/frontend/src/app/(platform)/library/page.tsx b/autogpt_platform/frontend/src/app/(platform)/library/page.tsx index ab7ea40f12..9841346fe5 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/page.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/page.tsx @@ -1,15 +1,15 @@ "use client"; import Link from "next/link"; +import { Alert, AlertDescription } from "@/components/ui/alert"; import { ArrowBottomRightIcon, QuestionMarkCircledIcon, } from "@radix-ui/react-icons"; -import { Alert, AlertDescription } from "@/components/ui/alert"; -import { LibraryPageStateProvider } from "./components/state-provider"; import LibraryActionHeader from "./components/LibraryActionHeader/LibraryActionHeader"; import LibraryAgentList from "./components/LibraryAgentList/LibraryAgentList"; +import { LibraryPageStateProvider } from "./components/state-provider"; /** * LibraryPage Component @@ -17,7 +17,7 @@ import LibraryAgentList from "./components/LibraryAgentList/LibraryAgentList"; */ export default function LibraryPage() { return ( -
+
diff --git a/autogpt_platform/frontend/src/app/api/__generated__/endpoints/integrations/integrations.ts b/autogpt_platform/frontend/src/app/api/__generated__/endpoints/integrations/integrations.ts index 782a97dd3e..bff97a64d4 100644 --- a/autogpt_platform/frontend/src/app/api/__generated__/endpoints/integrations/integrations.ts +++ b/autogpt_platform/frontend/src/app/api/__generated__/endpoints/integrations/integrations.ts @@ -41,11 +41,7 @@ import type { PostV1CreateCredentials201 } from "../../models/postV1CreateCreden import type { PostV1CreateCredentialsBody } from "../../models/postV1CreateCredentialsBody"; -import type { ProviderConstants } from "../../models/providerConstants"; - -import type { ProviderEnumResponse } from "../../models/providerEnumResponse"; - -import type { ProviderNamesResponse } from "../../models/providerNamesResponse"; +import type { ProviderName } from "../../models/providerName"; import { customMutator } from "../../../mutators/custom-mutator"; @@ -73,7 +69,7 @@ export type getV1LoginResponse = getV1LoginResponseComposite & { }; export const getGetV1LoginUrl = ( - provider: string, + provider: ProviderName, params?: GetV1LoginParams, ) => { const normalizedParams = new URLSearchParams(); @@ -92,7 +88,7 @@ export const getGetV1LoginUrl = ( }; export const getV1Login = async ( - provider: string, + provider: ProviderName, params?: GetV1LoginParams, options?: RequestInit, ): Promise => { @@ -103,7 +99,7 @@ export const getV1Login = async ( }; export const getGetV1LoginQueryKey = ( - provider: string, + provider: ProviderName, params?: GetV1LoginParams, ) => { return [ @@ -116,7 +112,7 @@ export const getGetV1LoginQueryOptions = < TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, params?: GetV1LoginParams, options?: { query?: Partial< @@ -155,7 +151,7 @@ export function useGetV1Login< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, params: undefined | GetV1LoginParams, options: { query: Partial< @@ -179,7 +175,7 @@ export function useGetV1Login< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, params?: GetV1LoginParams, options?: { query?: Partial< @@ -203,7 +199,7 @@ export function useGetV1Login< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, params?: GetV1LoginParams, options?: { query?: Partial< @@ -223,7 +219,7 @@ export function useGetV1Login< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, params?: GetV1LoginParams, options?: { query?: Partial< @@ -268,12 +264,12 @@ export type postV1CallbackResponse = postV1CallbackResponseComposite & { headers: Headers; }; -export const getPostV1CallbackUrl = (provider: string) => { +export const getPostV1CallbackUrl = (provider: ProviderName) => { return `/api/integrations/${provider}/callback`; }; export const postV1Callback = async ( - provider: string, + provider: ProviderName, bodyPostV1Callback: BodyPostV1Callback, options?: RequestInit, ): Promise => { @@ -292,14 +288,14 @@ export const getPostV1CallbackMutationOptions = < mutation?: UseMutationOptions< Awaited>, TError, - { provider: string; data: BodyPostV1Callback }, + { provider: ProviderName; data: BodyPostV1Callback }, TContext >; request?: SecondParameter; }): UseMutationOptions< Awaited>, TError, - { provider: string; data: BodyPostV1Callback }, + { provider: ProviderName; data: BodyPostV1Callback }, TContext > => { const mutationKey = ["postV1Callback"]; @@ -313,7 +309,7 @@ export const getPostV1CallbackMutationOptions = < const mutationFn: MutationFunction< Awaited>, - { provider: string; data: BodyPostV1Callback } + { provider: ProviderName; data: BodyPostV1Callback } > = (props) => { const { provider, data } = props ?? {}; @@ -340,7 +336,7 @@ export const usePostV1Callback = < mutation?: UseMutationOptions< Awaited>, TError, - { provider: string; data: BodyPostV1Callback }, + { provider: ProviderName; data: BodyPostV1Callback }, TContext >; request?: SecondParameter; @@ -349,7 +345,7 @@ export const usePostV1Callback = < ): UseMutationResult< Awaited>, TError, - { provider: string; data: BodyPostV1Callback }, + { provider: ProviderName; data: BodyPostV1Callback }, TContext > => { const mutationOptions = getPostV1CallbackMutationOptions(options); @@ -551,12 +547,14 @@ export type getV1ListCredentialsByProviderResponse = headers: Headers; }; -export const getGetV1ListCredentialsByProviderUrl = (provider: string) => { +export const getGetV1ListCredentialsByProviderUrl = ( + provider: ProviderName, +) => { return `/api/integrations/${provider}/credentials`; }; export const getV1ListCredentialsByProvider = async ( - provider: string, + provider: ProviderName, options?: RequestInit, ): Promise => { return customMutator( @@ -568,7 +566,9 @@ export const getV1ListCredentialsByProvider = async ( ); }; -export const getGetV1ListCredentialsByProviderQueryKey = (provider: string) => { +export const getGetV1ListCredentialsByProviderQueryKey = ( + provider: ProviderName, +) => { return [`/api/integrations/${provider}/credentials`] as const; }; @@ -576,7 +576,7 @@ export const getGetV1ListCredentialsByProviderQueryOptions = < TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, options?: { query?: Partial< UseQueryOptions< @@ -620,7 +620,7 @@ export function useGetV1ListCredentialsByProvider< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, options: { query: Partial< UseQueryOptions< @@ -647,7 +647,7 @@ export function useGetV1ListCredentialsByProvider< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, options?: { query?: Partial< UseQueryOptions< @@ -674,7 +674,7 @@ export function useGetV1ListCredentialsByProvider< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, options?: { query?: Partial< UseQueryOptions< @@ -697,7 +697,7 @@ export function useGetV1ListCredentialsByProvider< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, options?: { query?: Partial< UseQueryOptions< @@ -749,12 +749,12 @@ export type postV1CreateCredentialsResponse = headers: Headers; }; -export const getPostV1CreateCredentialsUrl = (provider: string) => { +export const getPostV1CreateCredentialsUrl = (provider: ProviderName) => { return `/api/integrations/${provider}/credentials`; }; export const postV1CreateCredentials = async ( - provider: string, + provider: ProviderName, postV1CreateCredentialsBody: PostV1CreateCredentialsBody, options?: RequestInit, ): Promise => { @@ -776,14 +776,14 @@ export const getPostV1CreateCredentialsMutationOptions = < mutation?: UseMutationOptions< Awaited>, TError, - { provider: string; data: PostV1CreateCredentialsBody }, + { provider: ProviderName; data: PostV1CreateCredentialsBody }, TContext >; request?: SecondParameter; }): UseMutationOptions< Awaited>, TError, - { provider: string; data: PostV1CreateCredentialsBody }, + { provider: ProviderName; data: PostV1CreateCredentialsBody }, TContext > => { const mutationKey = ["postV1CreateCredentials"]; @@ -797,7 +797,7 @@ export const getPostV1CreateCredentialsMutationOptions = < const mutationFn: MutationFunction< Awaited>, - { provider: string; data: PostV1CreateCredentialsBody } + { provider: ProviderName; data: PostV1CreateCredentialsBody } > = (props) => { const { provider, data } = props ?? {}; @@ -824,7 +824,7 @@ export const usePostV1CreateCredentials = < mutation?: UseMutationOptions< Awaited>, TError, - { provider: string; data: PostV1CreateCredentialsBody }, + { provider: ProviderName; data: PostV1CreateCredentialsBody }, TContext >; request?: SecondParameter; @@ -833,7 +833,7 @@ export const usePostV1CreateCredentials = < ): UseMutationResult< Awaited>, TError, - { provider: string; data: PostV1CreateCredentialsBody }, + { provider: ProviderName; data: PostV1CreateCredentialsBody }, TContext > => { const mutationOptions = getPostV1CreateCredentialsMutationOptions(options); @@ -861,12 +861,15 @@ export type getV1GetCredentialResponse = getV1GetCredentialResponseComposite & { headers: Headers; }; -export const getGetV1GetCredentialUrl = (provider: string, credId: string) => { +export const getGetV1GetCredentialUrl = ( + provider: ProviderName, + credId: string, +) => { return `/api/integrations/${provider}/credentials/${credId}`; }; export const getV1GetCredential = async ( - provider: string, + provider: ProviderName, credId: string, options?: RequestInit, ): Promise => { @@ -880,7 +883,7 @@ export const getV1GetCredential = async ( }; export const getGetV1GetCredentialQueryKey = ( - provider: string, + provider: ProviderName, credId: string, ) => { return [`/api/integrations/${provider}/credentials/${credId}`] as const; @@ -890,7 +893,7 @@ export const getGetV1GetCredentialQueryOptions = < TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, credId: string, options?: { query?: Partial< @@ -934,7 +937,7 @@ export function useGetV1GetCredential< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, credId: string, options: { query: Partial< @@ -962,7 +965,7 @@ export function useGetV1GetCredential< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, credId: string, options?: { query?: Partial< @@ -990,7 +993,7 @@ export function useGetV1GetCredential< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, credId: string, options?: { query?: Partial< @@ -1014,7 +1017,7 @@ export function useGetV1GetCredential< TData = Awaited>, TError = HTTPValidationError, >( - provider: string, + provider: ProviderName, credId: string, options?: { query?: Partial< @@ -1069,7 +1072,7 @@ export type deleteV1DeleteCredentialsResponse = }; export const getDeleteV1DeleteCredentialsUrl = ( - provider: string, + provider: ProviderName, credId: string, params?: DeleteV1DeleteCredentialsParams, ) => { @@ -1089,7 +1092,7 @@ export const getDeleteV1DeleteCredentialsUrl = ( }; export const deleteV1DeleteCredentials = async ( - provider: string, + provider: ProviderName, credId: string, params?: DeleteV1DeleteCredentialsParams, options?: RequestInit, @@ -1111,7 +1114,7 @@ export const getDeleteV1DeleteCredentialsMutationOptions = < Awaited>, TError, { - provider: string; + provider: ProviderName; credId: string; params?: DeleteV1DeleteCredentialsParams; }, @@ -1122,7 +1125,7 @@ export const getDeleteV1DeleteCredentialsMutationOptions = < Awaited>, TError, { - provider: string; + provider: ProviderName; credId: string; params?: DeleteV1DeleteCredentialsParams; }, @@ -1140,7 +1143,7 @@ export const getDeleteV1DeleteCredentialsMutationOptions = < const mutationFn: MutationFunction< Awaited>, { - provider: string; + provider: ProviderName; credId: string; params?: DeleteV1DeleteCredentialsParams; } @@ -1171,7 +1174,7 @@ export const useDeleteV1DeleteCredentials = < Awaited>, TError, { - provider: string; + provider: ProviderName; credId: string; params?: DeleteV1DeleteCredentialsParams; }, @@ -1184,7 +1187,7 @@ export const useDeleteV1DeleteCredentials = < Awaited>, TError, { - provider: string; + provider: ProviderName; credId: string; params?: DeleteV1DeleteCredentialsParams; }, @@ -1217,14 +1220,14 @@ export type postV1WebhookIngressGenericResponse = }; export const getPostV1WebhookIngressGenericUrl = ( - provider: string, + provider: ProviderName, webhookId: string, ) => { return `/api/integrations/${provider}/webhooks/${webhookId}/ingress`; }; export const postV1WebhookIngressGeneric = async ( - provider: string, + provider: ProviderName, webhookId: string, options?: RequestInit, ): Promise => { @@ -1244,14 +1247,14 @@ export const getPostV1WebhookIngressGenericMutationOptions = < mutation?: UseMutationOptions< Awaited>, TError, - { provider: string; webhookId: string }, + { provider: ProviderName; webhookId: string }, TContext >; request?: SecondParameter; }): UseMutationOptions< Awaited>, TError, - { provider: string; webhookId: string }, + { provider: ProviderName; webhookId: string }, TContext > => { const mutationKey = ["postV1WebhookIngressGeneric"]; @@ -1265,7 +1268,7 @@ export const getPostV1WebhookIngressGenericMutationOptions = < const mutationFn: MutationFunction< Awaited>, - { provider: string; webhookId: string } + { provider: ProviderName; webhookId: string } > = (props) => { const { provider, webhookId } = props ?? {}; @@ -1292,7 +1295,7 @@ export const usePostV1WebhookIngressGeneric = < mutation?: UseMutationOptions< Awaited>, TError, - { provider: string; webhookId: string }, + { provider: ProviderName; webhookId: string }, TContext >; request?: SecondParameter; @@ -1301,7 +1304,7 @@ export const usePostV1WebhookIngressGeneric = < ): UseMutationResult< Awaited>, TError, - { provider: string; webhookId: string }, + { provider: ProviderName; webhookId: string }, TContext > => { const mutationOptions = @@ -1418,714 +1421,3 @@ export const usePostV1WebhookPing = < return useMutation(mutationOptions, queryClient); }; -/** - * Get a list of all available provider names. - -Returns both statically defined providers (from ProviderName enum) -and dynamically registered providers (from SDK decorators). - -Note: The complete list of provider names is also available as a constant -in the generated TypeScript client via PROVIDER_NAMES. - * @summary List Providers - */ -export type getV1ListProvidersResponse200 = { - data: string[]; - status: 200; -}; - -export type getV1ListProvidersResponseComposite = getV1ListProvidersResponse200; - -export type getV1ListProvidersResponse = getV1ListProvidersResponseComposite & { - headers: Headers; -}; - -export const getGetV1ListProvidersUrl = () => { - return `/api/integrations/providers`; -}; - -export const getV1ListProviders = async ( - options?: RequestInit, -): Promise => { - return customMutator(getGetV1ListProvidersUrl(), { - ...options, - method: "GET", - }); -}; - -export const getGetV1ListProvidersQueryKey = () => { - return [`/api/integrations/providers`] as const; -}; - -export const getGetV1ListProvidersQueryOptions = < - TData = Awaited>, - TError = unknown, ->(options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; -}) => { - const { query: queryOptions, request: requestOptions } = options ?? {}; - - const queryKey = queryOptions?.queryKey ?? getGetV1ListProvidersQueryKey(); - - const queryFn: QueryFunction< - Awaited> - > = ({ signal }) => getV1ListProviders({ signal, ...requestOptions }); - - return { queryKey, queryFn, ...queryOptions } as UseQueryOptions< - Awaited>, - TError, - TData - > & { queryKey: DataTag }; -}; - -export type GetV1ListProvidersQueryResult = NonNullable< - Awaited> ->; -export type GetV1ListProvidersQueryError = unknown; - -export function useGetV1ListProviders< - TData = Awaited>, - TError = unknown, ->( - options: { - query: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - > & - Pick< - DefinedInitialDataOptions< - Awaited>, - TError, - Awaited> - >, - "initialData" - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): DefinedUseQueryResult & { - queryKey: DataTag; -}; -export function useGetV1ListProviders< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - > & - Pick< - UndefinedInitialDataOptions< - Awaited>, - TError, - Awaited> - >, - "initialData" - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -}; -export function useGetV1ListProviders< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -}; -/** - * @summary List Providers - */ - -export function useGetV1ListProviders< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -} { - const queryOptions = getGetV1ListProvidersQueryOptions(options); - - const query = useQuery(queryOptions, queryClient) as UseQueryResult< - TData, - TError - > & { queryKey: DataTag }; - - query.queryKey = queryOptions.queryKey; - - return query; -} - -/** - * Get all provider names in a structured format. - -This endpoint is specifically designed to expose the provider names -in the OpenAPI schema so that code generators like Orval can create -appropriate TypeScript constants. - * @summary Get Provider Names - */ -export type getV1GetProviderNamesResponse200 = { - data: ProviderNamesResponse; - status: 200; -}; - -export type getV1GetProviderNamesResponseComposite = - getV1GetProviderNamesResponse200; - -export type getV1GetProviderNamesResponse = - getV1GetProviderNamesResponseComposite & { - headers: Headers; - }; - -export const getGetV1GetProviderNamesUrl = () => { - return `/api/integrations/providers/names`; -}; - -export const getV1GetProviderNames = async ( - options?: RequestInit, -): Promise => { - return customMutator( - getGetV1GetProviderNamesUrl(), - { - ...options, - method: "GET", - }, - ); -}; - -export const getGetV1GetProviderNamesQueryKey = () => { - return [`/api/integrations/providers/names`] as const; -}; - -export const getGetV1GetProviderNamesQueryOptions = < - TData = Awaited>, - TError = unknown, ->(options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; -}) => { - const { query: queryOptions, request: requestOptions } = options ?? {}; - - const queryKey = queryOptions?.queryKey ?? getGetV1GetProviderNamesQueryKey(); - - const queryFn: QueryFunction< - Awaited> - > = ({ signal }) => getV1GetProviderNames({ signal, ...requestOptions }); - - return { queryKey, queryFn, ...queryOptions } as UseQueryOptions< - Awaited>, - TError, - TData - > & { queryKey: DataTag }; -}; - -export type GetV1GetProviderNamesQueryResult = NonNullable< - Awaited> ->; -export type GetV1GetProviderNamesQueryError = unknown; - -export function useGetV1GetProviderNames< - TData = Awaited>, - TError = unknown, ->( - options: { - query: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - > & - Pick< - DefinedInitialDataOptions< - Awaited>, - TError, - Awaited> - >, - "initialData" - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): DefinedUseQueryResult & { - queryKey: DataTag; -}; -export function useGetV1GetProviderNames< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - > & - Pick< - UndefinedInitialDataOptions< - Awaited>, - TError, - Awaited> - >, - "initialData" - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -}; -export function useGetV1GetProviderNames< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -}; -/** - * @summary Get Provider Names - */ - -export function useGetV1GetProviderNames< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -} { - const queryOptions = getGetV1GetProviderNamesQueryOptions(options); - - const query = useQuery(queryOptions, queryClient) as UseQueryResult< - TData, - TError - > & { queryKey: DataTag }; - - query.queryKey = queryOptions.queryKey; - - return query; -} - -/** - * Get provider names as constants. - -This endpoint returns a model with provider names as constants, -specifically designed for OpenAPI code generation tools to create -TypeScript constants. - * @summary Get Provider Constants - */ -export type getV1GetProviderConstantsResponse200 = { - data: ProviderConstants; - status: 200; -}; - -export type getV1GetProviderConstantsResponseComposite = - getV1GetProviderConstantsResponse200; - -export type getV1GetProviderConstantsResponse = - getV1GetProviderConstantsResponseComposite & { - headers: Headers; - }; - -export const getGetV1GetProviderConstantsUrl = () => { - return `/api/integrations/providers/constants`; -}; - -export const getV1GetProviderConstants = async ( - options?: RequestInit, -): Promise => { - return customMutator( - getGetV1GetProviderConstantsUrl(), - { - ...options, - method: "GET", - }, - ); -}; - -export const getGetV1GetProviderConstantsQueryKey = () => { - return [`/api/integrations/providers/constants`] as const; -}; - -export const getGetV1GetProviderConstantsQueryOptions = < - TData = Awaited>, - TError = unknown, ->(options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; -}) => { - const { query: queryOptions, request: requestOptions } = options ?? {}; - - const queryKey = - queryOptions?.queryKey ?? getGetV1GetProviderConstantsQueryKey(); - - const queryFn: QueryFunction< - Awaited> - > = ({ signal }) => getV1GetProviderConstants({ signal, ...requestOptions }); - - return { queryKey, queryFn, ...queryOptions } as UseQueryOptions< - Awaited>, - TError, - TData - > & { queryKey: DataTag }; -}; - -export type GetV1GetProviderConstantsQueryResult = NonNullable< - Awaited> ->; -export type GetV1GetProviderConstantsQueryError = unknown; - -export function useGetV1GetProviderConstants< - TData = Awaited>, - TError = unknown, ->( - options: { - query: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - > & - Pick< - DefinedInitialDataOptions< - Awaited>, - TError, - Awaited> - >, - "initialData" - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): DefinedUseQueryResult & { - queryKey: DataTag; -}; -export function useGetV1GetProviderConstants< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - > & - Pick< - UndefinedInitialDataOptions< - Awaited>, - TError, - Awaited> - >, - "initialData" - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -}; -export function useGetV1GetProviderConstants< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -}; -/** - * @summary Get Provider Constants - */ - -export function useGetV1GetProviderConstants< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -} { - const queryOptions = getGetV1GetProviderConstantsQueryOptions(options); - - const query = useQuery(queryOptions, queryClient) as UseQueryResult< - TData, - TError - > & { queryKey: DataTag }; - - query.queryKey = queryOptions.queryKey; - - return query; -} - -/** - * Example endpoint that uses the CompleteProviderNames enum. - -This endpoint exists to ensure that the CompleteProviderNames enum is included -in the OpenAPI schema, which will cause Orval to generate it as a -TypeScript enum/constant. - * @summary Get Provider Enum Example - */ -export type getV1GetProviderEnumExampleResponse200 = { - data: ProviderEnumResponse; - status: 200; -}; - -export type getV1GetProviderEnumExampleResponseComposite = - getV1GetProviderEnumExampleResponse200; - -export type getV1GetProviderEnumExampleResponse = - getV1GetProviderEnumExampleResponseComposite & { - headers: Headers; - }; - -export const getGetV1GetProviderEnumExampleUrl = () => { - return `/api/integrations/providers/enum-example`; -}; - -export const getV1GetProviderEnumExample = async ( - options?: RequestInit, -): Promise => { - return customMutator( - getGetV1GetProviderEnumExampleUrl(), - { - ...options, - method: "GET", - }, - ); -}; - -export const getGetV1GetProviderEnumExampleQueryKey = () => { - return [`/api/integrations/providers/enum-example`] as const; -}; - -export const getGetV1GetProviderEnumExampleQueryOptions = < - TData = Awaited>, - TError = unknown, ->(options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; -}) => { - const { query: queryOptions, request: requestOptions } = options ?? {}; - - const queryKey = - queryOptions?.queryKey ?? getGetV1GetProviderEnumExampleQueryKey(); - - const queryFn: QueryFunction< - Awaited> - > = ({ signal }) => - getV1GetProviderEnumExample({ signal, ...requestOptions }); - - return { queryKey, queryFn, ...queryOptions } as UseQueryOptions< - Awaited>, - TError, - TData - > & { queryKey: DataTag }; -}; - -export type GetV1GetProviderEnumExampleQueryResult = NonNullable< - Awaited> ->; -export type GetV1GetProviderEnumExampleQueryError = unknown; - -export function useGetV1GetProviderEnumExample< - TData = Awaited>, - TError = unknown, ->( - options: { - query: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - > & - Pick< - DefinedInitialDataOptions< - Awaited>, - TError, - Awaited> - >, - "initialData" - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): DefinedUseQueryResult & { - queryKey: DataTag; -}; -export function useGetV1GetProviderEnumExample< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - > & - Pick< - UndefinedInitialDataOptions< - Awaited>, - TError, - Awaited> - >, - "initialData" - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -}; -export function useGetV1GetProviderEnumExample< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -}; -/** - * @summary Get Provider Enum Example - */ - -export function useGetV1GetProviderEnumExample< - TData = Awaited>, - TError = unknown, ->( - options?: { - query?: Partial< - UseQueryOptions< - Awaited>, - TError, - TData - > - >; - request?: SecondParameter; - }, - queryClient?: QueryClient, -): UseQueryResult & { - queryKey: DataTag; -} { - const queryOptions = getGetV1GetProviderEnumExampleQueryOptions(options); - - const query = useQuery(queryOptions, queryClient) as UseQueryResult< - TData, - TError - > & { queryKey: DataTag }; - - query.queryKey = queryOptions.queryKey; - - return query; -} diff --git a/autogpt_platform/frontend/src/app/api/__generated__/models/credentialsMetaInput.ts b/autogpt_platform/frontend/src/app/api/__generated__/models/credentialsMetaInput.ts index e12660e8b8..bbff8a8227 100644 --- a/autogpt_platform/frontend/src/app/api/__generated__/models/credentialsMetaInput.ts +++ b/autogpt_platform/frontend/src/app/api/__generated__/models/credentialsMetaInput.ts @@ -6,12 +6,12 @@ * OpenAPI spec version: 0.1 */ import type { CredentialsMetaInputTitle } from "./credentialsMetaInputTitle"; +import type { ProviderName } from "./providerName"; import type { CredentialsMetaInputType } from "./credentialsMetaInputType"; export interface CredentialsMetaInput { id: string; title?: CredentialsMetaInputTitle; - /** Provider name for integrations. Can be any string value, including custom provider names. */ - provider: string; + provider: ProviderName; type: CredentialsMetaInputType; } diff --git a/autogpt_platform/frontend/src/app/api/__generated__/models/libraryAgentTriggerInfo.ts b/autogpt_platform/frontend/src/app/api/__generated__/models/libraryAgentTriggerInfo.ts index 29bbc0ce14..5f8338f9b0 100644 --- a/autogpt_platform/frontend/src/app/api/__generated__/models/libraryAgentTriggerInfo.ts +++ b/autogpt_platform/frontend/src/app/api/__generated__/models/libraryAgentTriggerInfo.ts @@ -5,12 +5,12 @@ * This server is used to execute agents that are created by the AutoGPT system. * OpenAPI spec version: 0.1 */ +import type { ProviderName } from "./providerName"; import type { LibraryAgentTriggerInfoConfigSchema } from "./libraryAgentTriggerInfoConfigSchema"; import type { LibraryAgentTriggerInfoCredentialsInputName } from "./libraryAgentTriggerInfoCredentialsInputName"; export interface LibraryAgentTriggerInfo { - /** Provider name for integrations. Can be any string value, including custom provider names. */ - provider: string; + provider: ProviderName; /** Input schema for the trigger block */ config_schema: LibraryAgentTriggerInfoConfigSchema; credentials_input_name: LibraryAgentTriggerInfoCredentialsInputName; diff --git a/autogpt_platform/frontend/src/app/api/__generated__/models/providerName.ts b/autogpt_platform/frontend/src/app/api/__generated__/models/providerName.ts new file mode 100644 index 0000000000..198bb7a5bf --- /dev/null +++ b/autogpt_platform/frontend/src/app/api/__generated__/models/providerName.ts @@ -0,0 +1,53 @@ +/** + * Generated by orval v7.10.0 🍺 + * Do not edit manually. + * AutoGPT Agent Server + * This server is used to execute agents that are created by the AutoGPT system. + * OpenAPI spec version: 0.1 + */ + +export type ProviderName = (typeof ProviderName)[keyof typeof ProviderName]; + +// eslint-disable-next-line @typescript-eslint/no-redeclare +export const ProviderName = { + aiml_api: "aiml_api", + anthropic: "anthropic", + apollo: "apollo", + compass: "compass", + discord: "discord", + d_id: "d_id", + e2b: "e2b", + exa: "exa", + fal: "fal", + generic_webhook: "generic_webhook", + github: "github", + google: "google", + google_maps: "google_maps", + groq: "groq", + http: "http", + hubspot: "hubspot", + ideogram: "ideogram", + jina: "jina", + linear: "linear", + llama_api: "llama_api", + medium: "medium", + mem0: "mem0", + notion: "notion", + nvidia: "nvidia", + ollama: "ollama", + openai: "openai", + openweathermap: "openweathermap", + open_router: "open_router", + pinecone: "pinecone", + reddit: "reddit", + replicate: "replicate", + revid: "revid", + screenshotone: "screenshotone", + slant3d: "slant3d", + smartlead: "smartlead", + smtp: "smtp", + twitter: "twitter", + todoist: "todoist", + unreal_speech: "unreal_speech", + zerobounce: "zerobounce", +} as const; diff --git a/autogpt_platform/frontend/src/app/api/__generated__/models/webhook.ts b/autogpt_platform/frontend/src/app/api/__generated__/models/webhook.ts index c1decc30a1..0f48986b6a 100644 --- a/autogpt_platform/frontend/src/app/api/__generated__/models/webhook.ts +++ b/autogpt_platform/frontend/src/app/api/__generated__/models/webhook.ts @@ -5,13 +5,13 @@ * This server is used to execute agents that are created by the AutoGPT system. * OpenAPI spec version: 0.1 */ +import type { ProviderName } from "./providerName"; import type { WebhookConfig } from "./webhookConfig"; export interface Webhook { id?: string; user_id: string; - /** Provider name for integrations. Can be any string value, including custom provider names. */ - provider: string; + provider: ProviderName; credentials_id: string; webhook_type: string; resource: string; diff --git a/autogpt_platform/frontend/src/app/api/openapi.json b/autogpt_platform/frontend/src/app/api/openapi.json index 22565c34c5..5bbf570661 100644 --- a/autogpt_platform/frontend/src/app/api/openapi.json +++ b/autogpt_platform/frontend/src/app/api/openapi.json @@ -18,9 +18,8 @@ "in": "path", "required": true, "schema": { - "type": "string", - "title": "The provider to initiate an OAuth flow for", - "description": "Provider name for integrations. Can be any string value, including custom provider names." + "$ref": "#/components/schemas/ProviderName", + "title": "The provider to initiate an OAuth flow for" } }, { @@ -65,9 +64,8 @@ "in": "path", "required": true, "schema": { - "type": "string", - "title": "The target provider for this OAuth exchange", - "description": "Provider name for integrations. Can be any string value, including custom provider names." + "$ref": "#/components/schemas/ProviderName", + "title": "The target provider for this OAuth exchange" } } ], @@ -135,9 +133,8 @@ "in": "path", "required": true, "schema": { - "type": "string", - "title": "The provider to list credentials for", - "description": "Provider name for integrations. Can be any string value, including custom provider names." + "$ref": "#/components/schemas/ProviderName", + "title": "The provider to list credentials for" } } ], @@ -176,9 +173,8 @@ "in": "path", "required": true, "schema": { - "type": "string", - "title": "The provider to create credentials for", - "description": "Provider name for integrations. Can be any string value, including custom provider names." + "$ref": "#/components/schemas/ProviderName", + "title": "The provider to create credentials for" } } ], @@ -257,9 +253,8 @@ "in": "path", "required": true, "schema": { - "type": "string", - "title": "The provider to retrieve credentials for", - "description": "Provider name for integrations. Can be any string value, including custom provider names." + "$ref": "#/components/schemas/ProviderName", + "title": "The provider to retrieve credentials for" } }, { @@ -320,9 +315,8 @@ "in": "path", "required": true, "schema": { - "type": "string", - "title": "The provider to delete credentials for", - "description": "Provider name for integrations. Can be any string value, including custom provider names." + "$ref": "#/components/schemas/ProviderName", + "title": "The provider to delete credentials for" } }, { @@ -386,9 +380,8 @@ "in": "path", "required": true, "schema": { - "type": "string", - "title": "Provider where the webhook was registered", - "description": "Provider name for integrations. Can be any string value, including custom provider names." + "$ref": "#/components/schemas/ProviderName", + "title": "Provider where the webhook was registered" } }, { @@ -443,86 +436,6 @@ } } }, - "/api/integrations/providers": { - "get": { - "tags": ["v1", "integrations"], - "summary": "List Providers", - "description": "Get a list of all available provider names.\n\nReturns both statically defined providers (from ProviderName enum)\nand dynamically registered providers (from SDK decorators).\n\nNote: The complete list of provider names is also available as a constant\nin the generated TypeScript client via PROVIDER_NAMES.", - "operationId": "getV1ListProviders", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { "type": "string" }, - "type": "array", - "title": "Response Getv1Listproviders" - } - } - } - } - } - } - }, - "/api/integrations/providers/names": { - "get": { - "tags": ["v1", "integrations"], - "summary": "Get Provider Names", - "description": "Get all provider names in a structured format.\n\nThis endpoint is specifically designed to expose the provider names\nin the OpenAPI schema so that code generators like Orval can create\nappropriate TypeScript constants.", - "operationId": "getV1GetProviderNames", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProviderNamesResponse" - } - } - } - } - } - } - }, - "/api/integrations/providers/constants": { - "get": { - "tags": ["v1", "integrations"], - "summary": "Get Provider Constants", - "description": "Get provider names as constants.\n\nThis endpoint returns a model with provider names as constants,\nspecifically designed for OpenAPI code generation tools to create\nTypeScript constants.", - "operationId": "getV1GetProviderConstants", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/ProviderConstants" } - } - } - } - } - } - }, - "/api/integrations/providers/enum-example": { - "get": { - "tags": ["v1", "integrations"], - "summary": "Get Provider Enum Example", - "description": "Example endpoint that uses the CompleteProviderNames enum.\n\nThis endpoint exists to ensure that the CompleteProviderNames enum is included\nin the OpenAPI schema, which will cause Orval to generate it as a\nTypeScript enum/constant.", - "operationId": "getV1GetProviderEnumExample", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProviderEnumResponse" - } - } - } - } - } - } - }, "/api/analytics/log_raw_metric": { "post": { "tags": ["v1", "analytics"], @@ -3373,6 +3286,48 @@ } } }, + "/api/library/agents/by-graph/{graph_id}": { + "get": { + "tags": ["v2", "library", "private"], + "summary": "Get Library Agent By Graph Id", + "operationId": "getV2GetLibraryAgentByGraphId", + "parameters": [ + { + "name": "graph_id", + "in": "path", + "required": true, + "schema": { "type": "string", "title": "Graph Id" } + }, + { + "name": "version", + "in": "query", + "required": false, + "schema": { + "anyOf": [{ "type": "integer" }, { "type": "null" }], + "title": "Version" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/LibraryAgent" } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + } + } + } + } + } + }, "/api/library/agents/marketplace/{store_listing_version_id}": { "get": { "tags": ["v2", "library", "private", "store, library"], @@ -4146,11 +4101,7 @@ "anyOf": [{ "type": "string" }, { "type": "null" }], "title": "Title" }, - "provider": { - "type": "string", - "title": "Provider", - "description": "Provider name for integrations. Can be any string value, including custom provider names." - }, + "provider": { "$ref": "#/components/schemas/ProviderName" }, "type": { "type": "string", "enum": ["api_key", "oauth2", "user_password", "host_scoped"], @@ -4160,8 +4111,8 @@ "type": "object", "required": ["id", "provider", "type"], "title": "CredentialsMetaInput", - "credentials_provider": ["string"], - "credentials_types": ["api_key", "oauth2", "user_password"] + "credentials_provider": [], + "credentials_types": [] }, "CredentialsMetaResponse": { "properties": { @@ -4869,11 +4820,7 @@ }, "LibraryAgentTriggerInfo": { "properties": { - "provider": { - "type": "string", - "title": "Provider", - "description": "Provider name for integrations. Can be any string value, including custom provider names." - }, + "provider": { "$ref": "#/components/schemas/ProviderName" }, "config_schema": { "additionalProperties": true, "type": "object", @@ -5288,6 +5235,7 @@ "AGENT_INPUT", "CONGRATS", "GET_RESULTS", + "RUN_AGENTS", "MARKETPLACE_VISIT", "MARKETPLACE_ADD_AGENT", "MARKETPLACE_RUN_AGENT", @@ -5675,44 +5623,51 @@ "required": ["name", "username", "description", "links"], "title": "ProfileDetails" }, - "ProviderConstants": { - "properties": { - "PROVIDER_NAMES": { - "additionalProperties": { "type": "string" }, - "type": "object", - "title": "Provider Names", - "description": "All available provider names as a constant mapping" - } - }, - "type": "object", - "title": "ProviderConstants", - "description": "Model that exposes all provider names as a constant in the OpenAPI schema.\nThis is designed to be converted by Orval into a TypeScript constant." - }, - "ProviderEnumResponse": { - "properties": { - "provider": { - "type": "string", - "title": "Provider", - "description": "A provider name from the complete list of providers" - } - }, - "type": "object", - "required": ["provider"], - "title": "ProviderEnumResponse", - "description": "Response containing a provider from the enum." - }, - "ProviderNamesResponse": { - "properties": { - "providers": { - "items": { "type": "string" }, - "type": "array", - "title": "Providers", - "description": "List of all available provider names" - } - }, - "type": "object", - "title": "ProviderNamesResponse", - "description": "Response containing list of all provider names." + "ProviderName": { + "type": "string", + "enum": [ + "aiml_api", + "anthropic", + "apollo", + "compass", + "discord", + "d_id", + "e2b", + "exa", + "fal", + "generic_webhook", + "github", + "google", + "google_maps", + "groq", + "http", + "hubspot", + "ideogram", + "jina", + "linear", + "llama_api", + "medium", + "mem0", + "notion", + "nvidia", + "ollama", + "openai", + "openweathermap", + "open_router", + "pinecone", + "reddit", + "replicate", + "revid", + "screenshotone", + "slant3d", + "smartlead", + "smtp", + "twitter", + "todoist", + "unreal_speech", + "zerobounce" + ], + "title": "ProviderName" }, "RefundRequest": { "properties": { @@ -6486,11 +6441,7 @@ "properties": { "id": { "type": "string", "title": "Id" }, "user_id": { "type": "string", "title": "User Id" }, - "provider": { - "type": "string", - "title": "Provider", - "description": "Provider name for integrations. Can be any string value, including custom provider names." - }, + "provider": { "$ref": "#/components/schemas/ProviderName" }, "credentials_id": { "type": "string", "title": "Credentials Id" }, "webhook_type": { "type": "string", "title": "Webhook Type" }, "resource": { "type": "string", "title": "Resource" }, diff --git a/autogpt_platform/frontend/src/components/agptui/Navbar.tsx b/autogpt_platform/frontend/src/components/agptui/Navbar.tsx deleted file mode 100644 index 5e78a4dc31..0000000000 --- a/autogpt_platform/frontend/src/components/agptui/Navbar.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import * as React from "react"; -import Link from "next/link"; -import { ProfilePopoutMenu } from "./ProfilePopoutMenu"; -import { IconType, IconLogIn, IconAutoGPTLogo } from "@/components/ui/icons"; -import { MobileNavBar } from "./MobileNavBar"; -import { Button } from "./Button"; -import Wallet from "./Wallet"; -import { ProfileDetails } from "@/lib/autogpt-server-api/types"; -import { NavbarLink } from "./NavbarLink"; - -import BackendAPI from "@/lib/autogpt-server-api"; -import { getServerUser } from "@/lib/supabase/server/getServerUser"; - -// Disable theme toggle for now -// import { ThemeToggle } from "./ThemeToggle"; - -interface NavLink { - name: string; - href: string; -} - -interface NavbarProps { - links: NavLink[]; - menuItemGroups: { - groupName?: string; - items: { - icon: IconType; - text: string; - href?: string; - onClick?: () => void; - }[]; - }[]; -} - -async function getProfileData() { - const api = new BackendAPI(); - const profile = await Promise.resolve(api.getStoreProfile()); - - return profile; -} - -export const Navbar = async ({ links, menuItemGroups }: NavbarProps) => { - const { user } = await getServerUser(); - const isLoggedIn = user !== null; - let profile: ProfileDetails | null = null; - if (isLoggedIn) { - profile = await getProfileData(); - } - - return ( - <> - - {/* Mobile Navbar - Adjust positioning */} - <> - {isLoggedIn ? ( -
- ({ - icon: - link.name === "Marketplace" - ? IconType.Marketplace - : link.name === "Library" - ? IconType.Library - : link.name === "Build" - ? IconType.Builder - : link.name === "Monitor" - ? IconType.Library - : IconType.LayoutDashboard, - text: link.name, - href: link.href, - })), - }, - ...menuItemGroups, - ]} - userEmail={profile?.name} - avatarSrc={profile?.avatar_url} - /> -
- ) : ( - - - - )} - - - ); -}; diff --git a/autogpt_platform/frontend/src/components/agptui/NavbarLink.tsx b/autogpt_platform/frontend/src/components/agptui/NavbarLink.tsx deleted file mode 100644 index 87523f241d..0000000000 --- a/autogpt_platform/frontend/src/components/agptui/NavbarLink.tsx +++ /dev/null @@ -1,66 +0,0 @@ -"use client"; -import Link from "next/link"; -import { - IconShoppingCart, - IconBoxes, - IconLibrary, - IconLaptop, -} from "@/components/ui/icons"; -import { usePathname } from "next/navigation"; - -interface NavbarLinkProps { - name: string; - href: string; -} - -export const NavbarLink = ({ name, href }: NavbarLinkProps) => { - const pathname = usePathname(); - const parts = pathname.split("/"); - const activeLink = "/" + (parts.length > 2 ? parts[2] : parts[1]); - - return ( - -
- {href === "/marketplace" && ( - - )} - {href === "/build" && ( - - )} - {href === "/monitor" && ( - - )} - {href === "/library" && ( - - )} -
- {name} -
-
- - ); -}; diff --git a/autogpt_platform/frontend/src/components/agptui/Wallet.tsx b/autogpt_platform/frontend/src/components/agptui/Wallet.tsx index 382a9bc050..7ce6f70a63 100644 --- a/autogpt_platform/frontend/src/components/agptui/Wallet.tsx +++ b/autogpt_platform/frontend/src/components/agptui/Wallet.tsx @@ -109,7 +109,7 @@ export default function Wallet() { + ); + } + + if (as === "NextLink") { + return ( + - - {children} - - ) : ( - + {buttonContent} + ); } @@ -87,18 +83,9 @@ function Button({ loading && "pointer-events-none", )} disabled={isDisabled} - {...props} + {...(restProps as React.ButtonHTMLAttributes)} > - {loading && ( - - )} - {!loading && leftIcon} - {children} - {!loading && rightIcon} + {buttonContent} ); } - -Button.displayName = "Button"; - -export { Button, extendedButtonVariants }; diff --git a/autogpt_platform/frontend/src/components/atoms/Button/helpers.tsx b/autogpt_platform/frontend/src/components/atoms/Button/helpers.tsx new file mode 100644 index 0000000000..80674c3acd --- /dev/null +++ b/autogpt_platform/frontend/src/components/atoms/Button/helpers.tsx @@ -0,0 +1,55 @@ +import { cva, VariantProps } from "class-variance-authority"; +import { LinkProps } from "next/link"; + +// Extended button variants based on our design system +export const extendedButtonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-neutral-950 disabled:pointer-events-none disabled:opacity-50 font-sans leading-snug border", + { + variants: { + variant: { + primary: + "bg-zinc-800 border-zinc-800 text-white hover:bg-zinc-900 hover:border-zinc-900 rounded-full disabled:text-white disabled:bg-zinc-200 disabled:border-zinc-200 disabled:opacity-1", + secondary: + "bg-zinc-100 border-zinc-100 text-black hover:bg-zinc-300 hover:border-zinc-300 rounded-full disabled:text-zinc-300 disabled:bg-zinc-50 disabled:border-zinc-50 disabled:opacity-1", + destructive: + "bg-red-500 border-red-500 text-white hover:bg-red-600 hover:border-red-600 rounded-full disabled:text-white disabled:bg-zinc-200 disabled:border-zinc-200 disabled:opacity-1", + outline: + "bg-transparent border-zinc-700 text-black hover:bg-zinc-100 hover:border-zinc-700 rounded-full disabled:border-zinc-200 disabled:text-zinc-200 disabled:opacity-1", + ghost: + "bg-transparent border-transparent text-black hover:bg-zinc-50 hover:border-zinc-50 rounded-full disabled:text-zinc-200 disabled:opacity-1", + icon: "bg-white text-black border border-zinc-600 hover:bg-zinc-100 rounded-[96px] disabled:opacity-1", + }, + size: { + small: "px-3 py-2 text-sm gap-1.5 h-[2.25rem]", + large: "min-w-20 px-4 py-3 text-sm gap-2", + icon: "p-3", + }, + }, + defaultVariants: { + variant: "primary", + size: "large", + }, + }, +); + +type BaseButtonProps = { + loading?: boolean; + leftIcon?: React.ReactNode; + rightIcon?: React.ReactNode; + asChild?: boolean; +} & VariantProps; + +type ButtonAsButton = BaseButtonProps & + React.ButtonHTMLAttributes & { + as?: "button"; + href?: never; + }; + +type ButtonAsLink = BaseButtonProps & + Omit, keyof LinkProps> & + LinkProps & { + as: "NextLink"; + disabled?: boolean; + }; + +export type ButtonProps = ButtonAsButton | ButtonAsLink; diff --git a/autogpt_platform/frontend/src/components/layout/Navbar/Navbar.tsx b/autogpt_platform/frontend/src/components/layout/Navbar/Navbar.tsx new file mode 100644 index 0000000000..758f1af7fa --- /dev/null +++ b/autogpt_platform/frontend/src/components/layout/Navbar/Navbar.tsx @@ -0,0 +1,84 @@ +import { IconAutoGPTLogo, IconType } from "@/components/ui/icons"; +import Wallet from "../../agptui/Wallet"; +import { AccountMenu } from "./components/AccountMenu/AccountMenu"; +import { LoginButton } from "./components/LoginButton"; +import { MobileNavBar } from "./components/MobileNavbar/MobileNavBar"; +import { NavbarLink } from "./components/NavbarLink"; +import { accountMenuItems, loggedInLinks, loggedOutLinks } from "./helpers"; +import { getNavbarAccountData } from "./data"; + +export async function Navbar() { + const { profile, isLoggedIn } = await getNavbarAccountData(); + + return ( + <> + + {/* Mobile Navbar - Adjust positioning */} + <> + {isLoggedIn ? ( +
+ ({ + icon: + link.name === "Marketplace" + ? IconType.Marketplace + : link.name === "Library" + ? IconType.Library + : link.name === "Build" + ? IconType.Builder + : link.name === "Monitor" + ? IconType.Library + : IconType.LayoutDashboard, + text: link.name, + href: link.href, + })), + }, + ...accountMenuItems, + ]} + userEmail={profile?.name} + avatarSrc={profile?.avatar_url ?? ""} + /> +
+ ) : null} + + + ); +} diff --git a/autogpt_platform/frontend/src/components/agptui/ProfilePopoutMenu.tsx b/autogpt_platform/frontend/src/components/layout/Navbar/components/AccountMenu/AccountMenu.tsx similarity index 74% rename from autogpt_platform/frontend/src/components/agptui/ProfilePopoutMenu.tsx rename to autogpt_platform/frontend/src/components/layout/Navbar/components/AccountMenu/AccountMenu.tsx index 65833e1e37..447358be65 100644 --- a/autogpt_platform/frontend/src/components/agptui/ProfilePopoutMenu.tsx +++ b/autogpt_platform/frontend/src/components/layout/Navbar/components/AccountMenu/AccountMenu.tsx @@ -1,74 +1,31 @@ -import * as React from "react"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Popover, - PopoverTrigger, PopoverContent, + PopoverTrigger, } from "@/components/ui/popover"; -import { - IconType, - IconEdit, - IconLayoutDashboard, - IconUploadCloud, - IconSettings, - IconLogOut, - IconRefresh, - IconMarketplace, - IconLibrary, - IconBuilder, -} from "../ui/icons"; import Link from "next/link"; -import { ProfilePopoutMenuLogoutButton } from "./ProfilePopoutMenuLogoutButton"; -import { PublishAgentPopout } from "./composite/PublishAgentPopout"; +import * as React from "react"; +import { PublishAgentPopout } from "../../../../agptui/composite/PublishAgentPopout"; +import { getAccountMenuOptionIcon, MenuItemGroup } from "../../helpers"; +import { AccountLogoutOption } from "./components/AccountLogoutOption"; -interface ProfilePopoutMenuProps { +interface Props { userName?: string; userEmail?: string; avatarSrc?: string; hideNavBarUsername?: boolean; - menuItemGroups: { - groupName?: string; - items: { - icon: IconType; - text: string; - href?: string; - onClick?: () => void; - }[]; - }[]; + menuItemGroups: MenuItemGroup[]; } -export function ProfilePopoutMenu({ +export function AccountMenu({ userName, userEmail, avatarSrc, menuItemGroups, -}: ProfilePopoutMenuProps) { +}: Props) { const popupId = React.useId(); - const getIcon = (icon: IconType) => { - const iconClass = "w-6 h-6"; - switch (icon) { - case IconType.LayoutDashboard: - return ; - case IconType.UploadCloud: - return ; - case IconType.Edit: - return ; - case IconType.Settings: - return ; - case IconType.LogOut: - return ; - case IconType.Marketplace: - return ; - case IconType.Library: - return ; - case IconType.Builder: - return ; - default: - return ; - } - }; - return ( @@ -127,7 +84,7 @@ export function ProfilePopoutMenu({ className="inline-flex w-full items-center justify-start gap-2.5" >
- {getIcon(item.icon)} + {getAccountMenuOptionIcon(item.icon)}
{item.text} @@ -135,7 +92,7 @@ export function ProfilePopoutMenu({ ); } else if (item.text === "Log out") { - return ; + return ; } else if (item.text === "Publish an agent") { return (
- {getIcon(item.icon)} + {getAccountMenuOptionIcon(item.icon)}
{item.text} @@ -165,7 +122,7 @@ export function ProfilePopoutMenu({ tabIndex={0} >
- {getIcon(item.icon)} + {getAccountMenuOptionIcon(item.icon)}
{item.text} diff --git a/autogpt_platform/frontend/src/components/agptui/ProfilePopoutMenuLogoutButton.tsx b/autogpt_platform/frontend/src/components/layout/Navbar/components/AccountMenu/components/AccountLogoutOption.tsx similarity index 90% rename from autogpt_platform/frontend/src/components/agptui/ProfilePopoutMenuLogoutButton.tsx rename to autogpt_platform/frontend/src/components/layout/Navbar/components/AccountMenu/components/AccountLogoutOption.tsx index fa4c8f955a..dc2c166797 100644 --- a/autogpt_platform/frontend/src/components/agptui/ProfilePopoutMenuLogoutButton.tsx +++ b/autogpt_platform/frontend/src/components/layout/Navbar/components/AccountMenu/components/AccountLogoutOption.tsx @@ -1,14 +1,14 @@ "use client"; import { IconLogOut } from "@/components/ui/icons"; +import { LoadingSpinner } from "@/components/ui/loading"; import { useSupabase } from "@/lib/supabase/hooks/useSupabase"; import { cn } from "@/lib/utils"; import * as Sentry from "@sentry/nextjs"; import { useRouter } from "next/navigation"; import { useTransition } from "react"; -import { LoadingSpinner } from "../ui/loading"; -import { toast } from "../molecules/Toast/use-toast"; +import { toast } from "@/components/molecules/Toast/use-toast"; -export function ProfilePopoutMenuLogoutButton() { +export function AccountLogoutOption() { const router = useRouter(); const [isPending, startTransition] = useTransition(); const supabase = useSupabase(); diff --git a/autogpt_platform/frontend/src/components/layout/Navbar/components/LoginButton.tsx b/autogpt_platform/frontend/src/components/layout/Navbar/components/LoginButton.tsx new file mode 100644 index 0000000000..d060fcf4ad --- /dev/null +++ b/autogpt_platform/frontend/src/components/layout/Navbar/components/LoginButton.tsx @@ -0,0 +1,29 @@ +"use client"; + +import { Button } from "@/components/atoms/Button/Button"; +import { SignInIcon } from "@phosphor-icons/react/dist/ssr"; +import { usePathname, useRouter } from "next/navigation"; + +export function LoginButton() { + const router = useRouter(); + const pathname = usePathname(); + const isLoginPage = pathname.includes("/login"); + + if (isLoginPage) return null; + + function handleLogin() { + router.push("/login"); + } + + return ( + + ); +} diff --git a/autogpt_platform/frontend/src/components/agptui/MobileNavBar.tsx b/autogpt_platform/frontend/src/components/layout/Navbar/components/MobileNavbar/MobileNavBar.tsx similarity index 62% rename from autogpt_platform/frontend/src/components/agptui/MobileNavBar.tsx rename to autogpt_platform/frontend/src/components/layout/Navbar/components/MobileNavbar/MobileNavBar.tsx index 447bddb88a..0053440251 100644 --- a/autogpt_platform/frontend/src/components/agptui/MobileNavBar.tsx +++ b/autogpt_platform/frontend/src/components/layout/Navbar/components/MobileNavbar/MobileNavBar.tsx @@ -1,45 +1,26 @@ "use client"; -import * as React from "react"; -import Link from "next/link"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Button } from "@/components/ui/button"; import { Popover, - PopoverTrigger, PopoverContent, PopoverPortal, + PopoverTrigger, } from "@/components/ui/popover"; -import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Separator } from "@/components/ui/separator"; -import { - IconType, - IconMenu, - IconChevronUp, - IconEdit, - IconLayoutDashboard, - IconUploadCloud, - IconSettings, - IconLogOut, - IconMarketplace, - IconLibrary, - IconBuilder, -} from "../ui/icons"; import { AnimatePresence, motion } from "framer-motion"; -import { Button } from "@/components/ui/button"; import { usePathname } from "next/navigation"; +import * as React from "react"; +import { IconChevronUp, IconMenu } from "../../../../ui/icons"; +import { MenuItemGroup } from "../../helpers"; +import { MobileNavbarMenuItem } from "./components/MobileNavbarMenuItem"; interface MobileNavBarProps { userName?: string; userEmail?: string; avatarSrc?: string; - menuItemGroups: { - groupName?: string; - items: { - icon: IconType; - text: string; - href?: string; - onClick?: () => void; - }[]; - }[]; + menuItemGroups: MenuItemGroup[]; } const Overlay = React.forwardRef( @@ -49,76 +30,15 @@ const Overlay = React.forwardRef(
), ); + Overlay.displayName = "Overlay"; -const PopoutMenuItem: React.FC<{ - icon: IconType; - isActive: boolean; - text: React.ReactNode; - href?: string; - onClick?: () => void; -}> = ({ icon, isActive, text, href, onClick }) => { - const getIcon = (iconType: IconType) => { - const iconClass = "w-6 h-6 relative"; - switch (iconType) { - case IconType.Marketplace: - return ; - case IconType.Library: - return ; - case IconType.Builder: - return ; - case IconType.Edit: - return ; - case IconType.LayoutDashboard: - return ; - case IconType.UploadCloud: - return ; - case IconType.Settings: - return ; - case IconType.LogOut: - return ; - default: - return null; - } - }; - - const content = ( -
- {getIcon(icon)} -
-
- {text} -
- {isActive && ( -
- )} -
-
- ); - - if (onClick) - return ( -
- {content} -
- ); - if (href) - return ( - - {content} - - ); - return content; -}; - -export const MobileNavBar: React.FC = ({ +export function MobileNavBar({ userName, userEmail, avatarSrc, menuItemGroups, -}) => { +}: MobileNavBarProps) { const [isOpen, setIsOpen] = React.useState(false); const pathname = usePathname(); const parts = pathname.split("/"); @@ -173,7 +93,7 @@ export const MobileNavBar: React.FC = ({ {menuItemGroups.map((group, groupIndex) => ( {group.items.map((item, itemIndex) => ( - = ({ ); -}; +} diff --git a/autogpt_platform/frontend/src/components/layout/Navbar/components/MobileNavbar/components/MobileNavbarMenuItem.tsx b/autogpt_platform/frontend/src/components/layout/Navbar/components/MobileNavbar/components/MobileNavbarMenuItem.tsx new file mode 100644 index 0000000000..e4955946a3 --- /dev/null +++ b/autogpt_platform/frontend/src/components/layout/Navbar/components/MobileNavbar/components/MobileNavbarMenuItem.tsx @@ -0,0 +1,55 @@ +import { IconType } from "@/components/ui/icons"; +import { cn } from "@/lib/utils"; +import Link from "next/link"; +import { getAccountMenuOptionIcon } from "../../../helpers"; + +interface Props { + icon: IconType; + isActive: boolean; + text: string; + href?: string; + onClick?: () => void; +} + +export function MobileNavbarMenuItem({ + icon, + isActive, + text, + href, + onClick, +}: Props) { + const content = ( +
+ {getAccountMenuOptionIcon(icon)} +
+
+ {text} +
+ {isActive && ( +
+ )} +
+
+ ); + + if (onClick) + return ( +
+ {content} +
+ ); + if (href) + return ( + + {content} + + ); + return content; +} diff --git a/autogpt_platform/frontend/src/components/layout/Navbar/components/NavbarLink.tsx b/autogpt_platform/frontend/src/components/layout/Navbar/components/NavbarLink.tsx new file mode 100644 index 0000000000..0f795689a3 --- /dev/null +++ b/autogpt_platform/frontend/src/components/layout/Navbar/components/NavbarLink.tsx @@ -0,0 +1,68 @@ +"use client"; + +import { IconLaptop } from "@/components/ui/icons"; +import { cn } from "@/lib/utils"; +import { + CubeIcon, + HouseIcon, + StorefrontIcon, +} from "@phosphor-icons/react/dist/ssr"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { Text } from "../../../atoms/Text/Text"; + +interface Props { + name: string; + href: string; +} + +export function NavbarLink({ name, href }: Props) { + const pathname = usePathname(); + const isActive = pathname.includes(href); + + return ( + +
+ {href === "/marketplace" && ( + + )} + {href === "/build" && ( + + )} + {href === "/monitor" && ( + + )} + {href === "/library" && ( + + )} + + {name} + +
+ + ); +} diff --git a/autogpt_platform/frontend/src/components/layout/Navbar/components/NavbarLoading.tsx b/autogpt_platform/frontend/src/components/layout/Navbar/components/NavbarLoading.tsx new file mode 100644 index 0000000000..6aa6252b77 --- /dev/null +++ b/autogpt_platform/frontend/src/components/layout/Navbar/components/NavbarLoading.tsx @@ -0,0 +1,21 @@ +import { IconAutoGPTLogo } from "@/components/ui/icons"; +import { Skeleton } from "@/components/ui/skeleton"; + +export function NavbarLoading() { + return ( + + ); +} diff --git a/autogpt_platform/frontend/src/components/layout/Navbar/data.ts b/autogpt_platform/frontend/src/components/layout/Navbar/data.ts new file mode 100644 index 0000000000..f7f79737dc --- /dev/null +++ b/autogpt_platform/frontend/src/components/layout/Navbar/data.ts @@ -0,0 +1,29 @@ +import { getV2GetUserProfile } from "@/app/api/__generated__/endpoints/store/store"; +import { getServerUser } from "@/lib/supabase/server/getServerUser"; + +export async function getNavbarAccountData() { + const { user } = await getServerUser(); + const isLoggedIn = Boolean(user); + + if (!isLoggedIn) { + return { + profile: null, + isLoggedIn, + }; + } + + let profile = null; + + try { + const profileResponse = await getV2GetUserProfile(); + profile = profileResponse.data || null; + } catch (error) { + console.error("Error fetching profile:", error); + profile = null; + } + + return { + profile, + isLoggedIn, + }; +} diff --git a/autogpt_platform/frontend/src/components/layout/Navbar/helpers.tsx b/autogpt_platform/frontend/src/components/layout/Navbar/helpers.tsx new file mode 100644 index 0000000000..d2ef1bc241 --- /dev/null +++ b/autogpt_platform/frontend/src/components/layout/Navbar/helpers.tsx @@ -0,0 +1,115 @@ +import { + IconBuilder, + IconEdit, + IconLayoutDashboard, + IconLibrary, + IconLogOut, + IconMarketplace, + IconRefresh, + IconSettings, + IconType, + IconUploadCloud, +} from "@/components/ui/icons"; + +type Link = { + name: string; + href: string; +}; + +export const loggedInLinks: Link[] = [ + { + name: "Marketplace", + href: "/marketplace", + }, + { + name: "Library", + href: "/library", + }, + { + name: "Build", + href: "/build", + }, +]; + +export const loggedOutLinks: Link[] = [ + { + name: "Marketplace", + href: "/marketplace", + }, +]; + +export type MenuItemGroup = { + groupName?: string; + items: { + icon: IconType; + text: string; + href?: string; + onClick?: () => void; + }[]; +}; + +export const accountMenuItems: MenuItemGroup[] = [ + { + items: [ + { + icon: IconType.Edit, + text: "Edit profile", + href: "/profile", + }, + ], + }, + { + items: [ + { + icon: IconType.LayoutDashboard, + text: "Creator Dashboard", + href: "/profile/dashboard", + }, + { + icon: IconType.UploadCloud, + text: "Publish an agent", + }, + ], + }, + { + items: [ + { + icon: IconType.Settings, + text: "Settings", + href: "/profile/settings", + }, + ], + }, + { + items: [ + { + icon: IconType.LogOut, + text: "Log out", + }, + ], + }, +]; + +export function getAccountMenuOptionIcon(icon: IconType) { + const iconClass = "w-6 h-6"; + switch (icon) { + case IconType.LayoutDashboard: + return ; + case IconType.UploadCloud: + return ; + case IconType.Edit: + return ; + case IconType.Settings: + return ; + case IconType.LogOut: + return ; + case IconType.Marketplace: + return ; + case IconType.Library: + return ; + case IconType.Builder: + return ; + default: + return ; + } +} diff --git a/autogpt_platform/frontend/src/components/styles/colors.ts b/autogpt_platform/frontend/src/components/styles/colors.ts index 1a6616e3fd..24977ebca8 100644 --- a/autogpt_platform/frontend/src/components/styles/colors.ts +++ b/autogpt_platform/frontend/src/components/styles/colors.ts @@ -71,6 +71,30 @@ export const colors = { 800: "#0c5a29", 900: "#09441f", }, + purple: { + 50: "#f1ebfe", + 100: "#d5c0fc", + 200: "#c0a1fa", + 300: "#a476f8", + 400: "#925cf7", + 500: "#7733f5", + 600: "#6c2edf", + 700: "#5424ae", + 800: "#411c87", + 900: "#321567", + }, + pink: { + 50: "#fdedf5", + 100: "#f9c6df", + 200: "#f6abd0", + 300: "#f284bb", + 400: "#f06dad", + 500: "#ec4899", + 600: "#d7428b", + 700: "#a8336d", + 800: "#822854", + 900: "#631e40", + }, // Special semantic colors white: "#fefefe", diff --git a/autogpt_platform/frontend/src/components/tokens/border-radius.stories.tsx b/autogpt_platform/frontend/src/components/tokens/border-radius.stories.tsx index 10f1996a80..acf685a5a7 100644 --- a/autogpt_platform/frontend/src/components/tokens/border-radius.stories.tsx +++ b/autogpt_platform/frontend/src/components/tokens/border-radius.stories.tsx @@ -14,54 +14,54 @@ const meta: Meta = { export default meta; // Border radius scale data based on Figma design tokens -// Custom naming convention: xs, s, m, l, xl, 2xl, full +// Custom naming convention: xsmall, small, medium, large, xlarge, 2xlarge, full const borderRadiusScale = [ { - name: "xs", + name: "xsmall", value: "0.25rem", rem: "0.25rem", px: "4px", - class: "rounded-xs", + class: "rounded-xsmall", description: "Extra small - for subtle rounding", }, { - name: "s", + name: "small", value: "0.5rem", rem: "0.5rem", px: "8px", - class: "rounded-s", + class: "rounded-small", description: "Small - for cards and containers", }, { - name: "m", + name: "medium", value: "0.75rem", rem: "0.75rem", px: "12px", - class: "rounded-m", + class: "rounded-medium", description: "Medium - for buttons and inputs", }, { - name: "l", + name: "large", value: "1rem", rem: "1rem", px: "16px", - class: "rounded-l", + class: "rounded-large", description: "Large - for panels and modals", }, { - name: "xl", + name: "xlarge", value: "1.25rem", rem: "1.25rem", px: "20px", - class: "rounded-xl", + class: "rounded-xlarge", description: "Extra large - for hero sections", }, { - name: "2xl", + name: "2xlarge", value: "1.5rem", rem: "1.5rem", px: "24px", - class: "rounded-2xl", + class: "rounded-2xlarge", description: "2X large - for major containers", }, { @@ -84,10 +84,11 @@ export function AllVariants() { Border Radius - Our border radius system uses a simplified naming convention (xs, s, - m, l, xl, 2xl, full) based on our Figma design tokens. This creates - visual hierarchy and maintains design consistency across all - components. + Our border radius system uses a descriptive naming convention + (xsmall, small, medium, large, xlarge, 2xlarge, full) based on our + Figma design tokens. This creates visual hierarchy and maintains + design consistency across all components while avoiding conflicts + with Tailwind's built-in classes.
@@ -137,9 +138,10 @@ export function AllVariants() {
We use a custom border radius system based on our Figma design - tokens, with simplified naming (xs, s, m, l, xl, 2xl, full) that - provides consistent radius values optimized for our design - system. + tokens, with descriptive naming (xsmall, small, medium, large, + xlarge, 2xlarge, full) that provides consistent radius values + optimized for our design system while avoiding conflicts with + Tailwind's built-in classes. @@ -188,7 +190,8 @@ export function AllVariants() { All border radius values from our Figma design tokens. Each value can be applied to all corners or specific corners/sides using our - simplified naming convention. + descriptive naming convention (xsmall, small, medium, large, xlarge, + 2xlarge, full). @@ -232,30 +235,30 @@ export function AllVariants() { Extra small rounding (4px) -
Small rounding (8px)
-
Medium rounding (12px)
-
Large rounding (16px)
-
Extra large rounding (20px)
-
2X large rounding (24px)
+
Extra small rounding (4px)
+
Small rounding (8px)
+
Medium rounding (12px)
+
Large rounding (16px)
+
Extra large rounding (20px)
+
2X large rounding (24px)
Pill buttons (circular)
// Directional rounding (works with all sizes) -
Top corners only
-
Right corners only
-
Bottom corners only
-
Left corners only
+
Top corners only
+
Right corners only
+
Bottom corners only
+
Left corners only
// Individual corners -
Top-left corner
-
Top-right corner
-
Bottom-left corner
-
Bottom-right corner
+
Top-left corner
+
Top-right corner
+
Bottom-left corner
+
Bottom-right corner
// Usage recommendations -
Card Container
-Input Field`} +
Card Container
+Input Field`} /> diff --git a/autogpt_platform/frontend/src/components/tokens/colors.stories.tsx b/autogpt_platform/frontend/src/components/tokens/colors.stories.tsx index 3b60d23b16..9eb3ba1ff0 100644 --- a/autogpt_platform/frontend/src/components/tokens/colors.stories.tsx +++ b/autogpt_platform/frontend/src/components/tokens/colors.stories.tsx @@ -36,6 +36,8 @@ const colorCategories = Object.entries(colors) orange: "Warnings, notifications, and secondary call-to-actions", yellow: "Highlights, cautions, and attention-grabbing elements", green: "Success states, confirmations, and positive actions", + purple: "Brand accents, premium features, and creative elements", + pink: "Highlights, special promotions, and playful interactions", }; return { @@ -312,6 +314,8 @@ export function AllVariants() {
Success
Error
Warning
+
Premium
+
Special
// ❌ INCORRECT - Don't use these
❌ Not approved
diff --git a/autogpt_platform/frontend/src/components/ui/scroll-area.tsx b/autogpt_platform/frontend/src/components/ui/scroll-area.tsx index ab4dc3b8c1..592d2b88b5 100644 --- a/autogpt_platform/frontend/src/components/ui/scroll-area.tsx +++ b/autogpt_platform/frontend/src/components/ui/scroll-area.tsx @@ -11,12 +11,12 @@ const ScrollArea = React.forwardRef< >(({ className, children, ...props }, ref) => ( {children} diff --git a/autogpt_platform/frontend/src/lib/supabase/actions.ts b/autogpt_platform/frontend/src/lib/supabase/actions.ts index 2cf49a2447..f5608accbc 100644 --- a/autogpt_platform/frontend/src/lib/supabase/actions.ts +++ b/autogpt_platform/frontend/src/lib/supabase/actions.ts @@ -166,6 +166,8 @@ export async function serverLogout(options: ServerLogoutOptions = {}) { scope: options.globalLogout ? "global" : "local", }); + revalidatePath("/"); + if (error) { console.error("Error logging out:", error); } diff --git a/autogpt_platform/frontend/src/lib/supabase/hooks/useSupabase.ts b/autogpt_platform/frontend/src/lib/supabase/hooks/useSupabase.ts index 333b535fbd..d93ce0eaa8 100644 --- a/autogpt_platform/frontend/src/lib/supabase/hooks/useSupabase.ts +++ b/autogpt_platform/frontend/src/lib/supabase/hooks/useSupabase.ts @@ -24,6 +24,7 @@ export function useSupabase() { const [isUserLoading, setIsUserLoading] = useState(true); const lastValidationRef = useRef(0); const isValidatingRef = useRef(false); + const isLoggedIn = Boolean(user); const supabase = useMemo(() => { try { @@ -50,7 +51,9 @@ export function useSupabase() { await serverLogout(options); } catch (error) { console.error("Error logging out:", error); - router.push("/login"); + } finally { + setUser(null); + router.refresh(); } } @@ -162,9 +165,9 @@ export function useSupabase() { }, []); return { - supabase, // Available for non-auth operations like real-time subscriptions user, - isLoggedIn: !isUserLoading ? !!user : null, + supabase, // Available for non-auth operations like real-time subscriptions + isLoggedIn, isUserLoading, logOut, validateSession: validateSessionServer, diff --git a/autogpt_platform/frontend/tailwind.config.ts b/autogpt_platform/frontend/tailwind.config.ts index f154b8931f..72c0018919 100644 --- a/autogpt_platform/frontend/tailwind.config.ts +++ b/autogpt_platform/frontend/tailwind.config.ts @@ -73,56 +73,56 @@ const config = { }, spacing: { // Tailwind spacing + custom sizes - 0: "0rem", - 0.5: "0.125rem", - 1: "0.25rem", - 1.5: "0.375rem", - 2: "0.5rem", - 2.5: "0.625rem", - 3: "0.75rem", - 3.5: "0.875rem", - 4: "1rem", - 5: "1.25rem", - 6: "1.5rem", - 7: "1.75rem", - 7.5: "1.875rem", - 8: "2rem", - 8.5: "2.125rem", - 9: "2.25rem", - 10: "2.5rem", - 11: "2.75rem", - 12: "3rem", - 14: "3.5rem", - 16: "4rem", - 18: "4.5rem", - 20: "5rem", - 24: "6rem", - 28: "7rem", - 32: "8rem", - 36: "9rem", - 40: "10rem", - 44: "11rem", - 48: "12rem", - 52: "13rem", - 56: "14rem", - 60: "15rem", - 64: "16rem", - 68: "17rem", - 70: "17.5rem", - 71: "17.75rem", - 72: "18rem", - 76: "19rem", - 80: "20rem", - 96: "24rem", + 0: "0rem", // 0px + 0.5: "0.125rem", // 2px + 1: "0.25rem", // 4px + 1.5: "0.375rem", // 6px + 2: "0.5rem", // 8px + 2.5: "0.625rem", // 10px + 3: "0.75rem", // 12px + 3.5: "0.875rem", // 14px + 4: "1rem", // 16px + 5: "1.25rem", // 20px + 6: "1.5rem", // 24px + 7: "1.75rem", // 28px + 7.5: "1.875rem", // 30px + 8: "2rem", // 32px + 8.5: "2.125rem", // 34px + 9: "2.25rem", // 36px + 10: "2.5rem", // 40px + 11: "2.75rem", // 44px + 12: "3rem", // 48px + 14: "3.5rem", // 56px + 16: "4rem", // 64px + 18: "4.5rem", // 72px + 20: "5rem", // 80px + 24: "6rem", // 96px + 28: "7rem", // 112px + 32: "8rem", // 128px + 36: "9rem", // 144px + 40: "10rem", // 160px + 44: "11rem", // 176px + 48: "12rem", // 192px + 52: "13rem", // 208px + 56: "14rem", // 224px + 60: "15rem", // 240px + 64: "16rem", // 256px + 68: "17rem", // 272px + 70: "17.5rem", // 280px + 71: "17.75rem", // 284px + 72: "18rem", // 288px + 76: "19rem", // 304px + 80: "20rem", // 320px + 96: "24rem", // 384px }, borderRadius: { // Design system border radius tokens from Figma - xs: "0.25rem", // 4px - s: "0.5rem", // 8px - m: "0.75rem", // 12px - l: "1rem", // 16px - xl: "1.25rem", // 20px - "2xl": "1.5rem", // 24px + xsmall: "0.25rem", // 4px + small: "0.5rem", // 8px + medium: "0.75rem", // 12px + large: "1rem", // 16px + xlarge: "1.25rem", // 20px + "2xlarge": "1.5rem", // 24px full: "9999px", // For pill buttons // Legacy values - kept for backward compatibility