Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(frontend): Update Supabase and backend API management #9036

Merged
merged 10 commits into from
Dec 18, 2024
2 changes: 1 addition & 1 deletion autogpt_platform/frontend/public/mockServiceWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* - Please do NOT serve this file on production.
ntindle marked this conversation as resolved.
Show resolved Hide resolved
*/

const PACKAGE_VERSION = '2.6.8'
const PACKAGE_VERSION = '2.7.0'
const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
const activeClientIds = new Set()
Expand Down
4 changes: 2 additions & 2 deletions autogpt_platform/frontend/src/app/auth/callback/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import getServerSupabase from "@/lib/supabase/getServerSupabase";
import { NextResponse } from "next/server";
import { createServerClient } from "@/lib/supabase/server";

// Handle the callback to complete the user session login
export async function GET(request: Request) {
Expand All @@ -9,7 +9,7 @@ export async function GET(request: Request) {
const next = searchParams.get("next") ?? "/";

if (code) {
const supabase = createServerClient();
const supabase = getServerSupabase();

if (!supabase) {
return NextResponse.redirect(`${origin}/error`);
Expand Down
4 changes: 2 additions & 2 deletions autogpt_platform/frontend/src/app/auth/confirm/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type EmailOtpType } from "@supabase/supabase-js";
import { type NextRequest } from "next/server";

import { redirect } from "next/navigation";
import { createServerClient } from "@/lib/supabase/server";
import getServerSupabase from "@/lib/supabase/getServerSupabase";

// Email confirmation route
export async function GET(request: NextRequest) {
Expand All @@ -12,7 +12,7 @@ export async function GET(request: NextRequest) {
const next = searchParams.get("next") ?? "/";

if (token_hash && type) {
const supabase = createServerClient();
const supabase = getServerSupabase();

if (!supabase) {
redirect("/error");
Expand Down
10 changes: 0 additions & 10 deletions autogpt_platform/frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import TallyPopupSimple from "@/components/TallyPopup";
import { GoogleAnalytics } from "@next/third-parties/google";
import { Toaster } from "@/components/ui/toaster";
import { IconType } from "@/components/ui/icons";
import { createServerClient } from "@/lib/supabase/server";

const inter = Inter({ subsets: ["latin"] });

Expand All @@ -24,17 +23,10 @@ export default async function RootLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
const supabase = createServerClient();

const {
data: { user },
} = await supabase.auth.getUser();

return (
<html lang="en">
<body className={cn("antialiased transition-colors", inter.className)}>
<Providers
initialUser={user}
attribute="class"
defaultTheme="light"
// Feel free to remove this line if you want to use the system theme by default
Expand All @@ -43,8 +35,6 @@ export default async function RootLayout({
>
<div className="flex min-h-screen flex-col items-center justify-center">
<Navbar
user={user}
isLoggedIn={!!user}
links={[
{
name: "Agent Store",
Expand Down
12 changes: 8 additions & 4 deletions autogpt_platform/frontend/src/app/login/actions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"use server";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { createServerClient } from "@/lib/supabase/server";
import { z } from "zod";
import * as Sentry from "@sentry/nextjs";
import getServerSupabase from "@/lib/supabase/getServerSupabase";
import BackendAPI from "@/lib/autogpt-server-api";

const loginFormSchema = z.object({
email: z.string().email().min(2).max(64),
Expand All @@ -15,7 +16,7 @@ export async function logout() {
"logout",
{},
async () => {
const supabase = createServerClient();
const supabase = getServerSupabase();

if (!supabase) {
redirect("/error");
Expand All @@ -36,7 +37,8 @@ export async function logout() {

export async function login(values: z.infer<typeof loginFormSchema>) {
return await Sentry.withServerActionInstrumentation("login", {}, async () => {
const supabase = createServerClient();
const supabase = getServerSupabase();
const api = new BackendAPI();

if (!supabase) {
redirect("/error");
Expand All @@ -45,6 +47,8 @@ export async function login(values: z.infer<typeof loginFormSchema>) {
// We are sure that the values are of the correct type because zod validates the form
const { data, error } = await supabase.auth.signInWithPassword(values);

await api.createUser();

if (error) {
console.log("Error logging in", error);
if (error.status == 400) {
Expand All @@ -70,7 +74,7 @@ export async function signup(values: z.infer<typeof loginFormSchema>) {
"signup",
{},
async () => {
const supabase = createServerClient();
const supabase = getServerSupabase();

if (!supabase) {
redirect("/error");
Expand Down
21 changes: 10 additions & 11 deletions autogpt_platform/frontend/src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"use client";
import useUser from "@/hooks/useUser";
import { login, signup } from "./actions";
import { Button } from "@/components/ui/button";
import {
Expand All @@ -18,10 +17,12 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { PasswordInput } from "@/components/PasswordInput";
import { FaGoogle, FaGithub, FaDiscord, FaSpinner } from "react-icons/fa";
import { useState } from "react";
import { useSupabase } from "@/components/providers/SupabaseProvider";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { Checkbox } from "@/components/ui/checkbox";
import useSupabase from "@/hooks/useSupabase";
import Spinner from "@/components/Spinner";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";

const loginFormSchema = z.object({
email: z.string().email().min(2).max(64),
Expand All @@ -32,11 +33,11 @@ const loginFormSchema = z.object({
});

export default function LoginPage() {
const { supabase, isLoading: isSupabaseLoading } = useSupabase();
const { user, isLoading: isUserLoading } = useUser();
const { supabase, user, isUserLoading } = useSupabase();
const [feedback, setFeedback] = useState<string | null>(null);
const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const api = useBackendAPI();

const form = useForm<z.infer<typeof loginFormSchema>>({
resolver: zodResolver(loginFormSchema),
Expand All @@ -48,16 +49,12 @@ export default function LoginPage() {
});

if (user) {
console.log("User exists, redirecting to home");
console.debug("User exists, redirecting to /");
router.push("/");
}

if (isUserLoading || isSupabaseLoading || user) {
return (
<div className="flex h-[80vh] items-center justify-center">
<FaSpinner className="mr-2 h-16 w-16 animate-spin" />
</div>
);
if (isUserLoading || user) {
return <Spinner />;
}

if (!supabase) {
Expand All @@ -80,6 +77,8 @@ export default function LoginPage() {
},
});

await api.createUser();
ntindle marked this conversation as resolved.
Show resolved Hide resolved

if (!error) {
setFeedback(null);
return;
Expand Down
12 changes: 4 additions & 8 deletions autogpt_platform/frontend/src/app/monitoring/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
"use client";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import React, { useCallback, useEffect, useState } from "react";

import AutoGPTServerAPI, {
GraphExecution,
Schedule,
GraphMeta,
} from "@/lib/autogpt-server-api";
import { GraphExecution, Schedule, GraphMeta } from "@/lib/autogpt-server-api";

import { Card } from "@/components/ui/card";
import {
Expand All @@ -16,6 +12,7 @@ import {
FlowRunsStats,
} from "@/components/monitor";
import { SchedulesTable } from "@/components/monitor/scheduleTable";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";

const Monitor = () => {
const [flows, setFlows] = useState<GraphMeta[]>([]);
Expand All @@ -25,8 +22,7 @@ const Monitor = () => {
const [selectedRun, setSelectedRun] = useState<GraphExecution | null>(null);
const [sortColumn, setSortColumn] = useState<keyof Schedule>("id");
const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc");

const api = useMemo(() => new AutoGPTServerAPI(), []);
const api = useBackendAPI();

const fetchSchedules = useCallback(async () => {
setSchedules(await api.listSchedules());
Expand Down
43 changes: 19 additions & 24 deletions autogpt_platform/frontend/src/app/profile/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
"use client";

import { useSupabase } from "@/components/providers/SupabaseProvider";
import { Button } from "@/components/ui/button";
import useUser from "@/hooks/useUser";
import { useRouter } from "next/navigation";
import { useCallback, useContext, useMemo, useState } from "react";
import { FaSpinner } from "react-icons/fa";
import { Separator } from "@/components/ui/separator";
import { useToast } from "@/components/ui/use-toast";
import { IconKey, IconUser } from "@/components/ui/icons";
Expand All @@ -31,10 +27,11 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import useSupabase from "@/hooks/useSupabase";
import Spinner from "@/components/Spinner";

export default function PrivatePage() {
const { user, isLoading, error } = useUser();
const { supabase } = useSupabase();
const { supabase, user, isUserLoading } = useSupabase();
const router = useRouter();
const providers = useContext(CredentialsProvidersContext);
const { toast } = useToast();
Expand Down Expand Up @@ -115,30 +112,28 @@ export default function PrivatePage() {
[],
);

if (isLoading || !providers) {
return (
<div className="flex h-[80vh] items-center justify-center">
<FaSpinner className="mr-2 h-16 w-16 animate-spin" />
</div>
);
if (isUserLoading) {
return <Spinner />;
}

if (error || !user || !supabase) {
if (!user || !supabase) {
router.push("/login");
return null;
}

const allCredentials = Object.values(providers).flatMap((provider) =>
[...provider.savedOAuthCredentials, ...provider.savedApiKeys]
.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 }[credentials.type],
})),
);
const allCredentials = providers
? Object.values(providers).flatMap((provider) =>
[...provider.savedOAuthCredentials, ...provider.savedApiKeys]
.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 }[credentials.type],
})),
)
: [];

return (
<div className="mx-auto max-w-3xl md:py-8">
Expand Down
24 changes: 8 additions & 16 deletions autogpt_platform/frontend/src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,19 @@ import { ThemeProvider as NextThemesProvider } from "next-themes";
import { ThemeProviderProps } from "next-themes";
import { BackendAPIProvider } from "@/lib/autogpt-server-api/context";
import { TooltipProvider } from "@/components/ui/tooltip";
import SupabaseProvider from "@/components/providers/SupabaseProvider";
import CredentialsProvider from "@/components/integrations/credentials-provider";
import { User } from "@supabase/supabase-js";
import { LaunchDarklyProvider } from "@/components/feature-flag/feature-flag-provider";

export function Providers({
children,
initialUser,
...props
}: ThemeProviderProps & { initialUser: User | null }) {
export function Providers({ children, ...props }: ThemeProviderProps) {
return (
<NextThemesProvider {...props}>
<SupabaseProvider initialUser={initialUser}>
<BackendAPIProvider>
<CredentialsProvider>
<LaunchDarklyProvider>
<TooltipProvider>{children}</TooltipProvider>
</LaunchDarklyProvider>
</CredentialsProvider>
</BackendAPIProvider>
</SupabaseProvider>
<BackendAPIProvider>
<CredentialsProvider>
<LaunchDarklyProvider>
<TooltipProvider>{children}</TooltipProvider>
</LaunchDarklyProvider>
</CredentialsProvider>
</BackendAPIProvider>
</NextThemesProvider>
);
}
Loading
Loading