From 918e06a2457034ee11dcde91b1032f6ee5f69f39 Mon Sep 17 00:00:00 2001 From: Claudio Fuentes Date: Thu, 3 Apr 2025 23:41:35 -0400 Subject: [PATCH] refactor: enhance organization redirection logic across dashboard layouts - Added checks for active organization ID in the layout and dashboard page to ensure proper redirection. - Simplified the session handling in the setup page and updated the Onboarding component for improved clarity and modularity. - Removed unnecessary authentication checks in the frameworks layout to streamline the component structure. --- .../(dashboard)/[orgId]/frameworks/layout.tsx | 15 ---- .../(dashboard)/[orgId]/frameworks/page.tsx | 2 +- .../(app)/(dashboard)/[orgId]/layout.tsx | 4 + .../(app)/(dashboard)/[orgId]/page.tsx | 18 ++-- .../app/src/app/[locale]/(app)/setup/page.tsx | 32 +++---- .../src/app/[locale]/(public)/auth/page.tsx | 85 +++++++++---------- .../forms/create-organization-form.tsx | 32 +++---- apps/app/src/components/google-sign-in.tsx | 3 +- 8 files changed, 82 insertions(+), 109 deletions(-) diff --git a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/frameworks/layout.tsx b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/frameworks/layout.tsx index 0e20b6324d..9b728f7bb5 100644 --- a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/frameworks/layout.tsx +++ b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/frameworks/layout.tsx @@ -1,23 +1,8 @@ -import { getI18n } from "@/locales/server"; -import { auth } from "@/utils/auth"; -import { headers } from "next/headers"; -import { redirect } from "next/navigation"; - export default async function Layout({ children, }: { children: React.ReactNode; }) { - const t = await getI18n(); - const session = await auth.api.getSession({ - headers: await headers(), - }); - - if (!session?.session?.activeOrganizationId) { - console.log("Redirect on layout.tsx"); - redirect("/auth"); - } - return (
{children}
diff --git a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/frameworks/page.tsx b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/frameworks/page.tsx index c38ed74e68..6b0427b12f 100644 --- a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/frameworks/page.tsx +++ b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/frameworks/page.tsx @@ -2,9 +2,9 @@ import { getI18n } from "@/locales/server"; import { auth } from "@/utils/auth"; import { headers } from "next/headers"; import { redirect } from "next/navigation"; +import PageWithBreadcrumb from "../../../../../../components/pages/PageWithBreadcrumb"; import { FrameworksOverview } from "./components/FrameworksOverview"; import { getAllFrameworkInstancesWithControls } from "./data/getAllFrameworkInstancesWithControls"; -import PageWithBreadcrumb from "../../../../../../components/pages/PageWithBreadcrumb"; export async function generateMetadata() { const t = await getI18n(); diff --git a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/layout.tsx b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/layout.tsx index 67ec673e21..02cc353aa8 100644 --- a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/layout.tsx +++ b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/layout.tsx @@ -38,6 +38,10 @@ export default async function Layout({ redirect("/"); } + if (!session?.session.activeOrganizationId) { + redirect("/"); + } + return ( } isCollapsed={isCollapsed}> diff --git a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/page.tsx b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/page.tsx index c8a61429e7..12f012769a 100644 --- a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/page.tsx +++ b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/page.tsx @@ -1,17 +1,11 @@ -import { auth } from "@/utils/auth"; -import { headers } from "next/headers"; import { redirect } from "next/navigation"; -export default async function DashboardPage() { - const session = await auth.api.getSession({ - headers: await headers(), - }); - - const organizationId = session?.session.activeOrganizationId; - - if (!organizationId) { - redirect("/"); - } +export default async function DashboardPage({ + params, +}: { + params: Promise<{ orgId: string }>; +}) { + const organizationId = (await params).orgId; redirect(`/${organizationId}/frameworks`); } diff --git a/apps/app/src/app/[locale]/(app)/setup/page.tsx b/apps/app/src/app/[locale]/(app)/setup/page.tsx index e8986cf6d5..10abdd1d00 100644 --- a/apps/app/src/app/[locale]/(app)/setup/page.tsx +++ b/apps/app/src/app/[locale]/(app)/setup/page.tsx @@ -1,4 +1,4 @@ -import { Onboarding } from "@/components/forms/create-organization-form"; +import { OnboardingClient } from "@/components/forms/create-organization-form"; import { auth } from "@/utils/auth"; import { db } from "@comp/db"; import type { Metadata } from "next"; @@ -11,16 +11,15 @@ export const metadata: Metadata = { }; export default async function Page() { + const headersList = await headers(); + const session = await auth.api.getSession({ - headers: await headers(), + headers: headersList, }); - const hasInvite = await db.invitation.findFirst({ - where: { - email: session?.user.email, - status: "pending", - }, - }); + if (session?.session?.activeOrganizationId) { + redirect(`/${session.session.activeOrganizationId}/frameworks`); + } const organization = await db.organization.findFirst({ where: { @@ -34,23 +33,24 @@ export default async function Page() { if (!session?.session?.activeOrganizationId && organization?.id) { await auth.api.setActiveOrganization({ - headers: await headers(), + headers: headersList, body: { organizationId: organization.id, }, }); - redirect("/"); - } else if (session?.session?.activeOrganizationId) { - redirect("/"); + redirect(`/${organization.id}/frameworks`); } - if (session?.session?.activeOrganizationId) { - redirect("/"); - } + const hasInvite = await db.invitation.findFirst({ + where: { + email: session?.user.email, + status: "pending", + }, + }); if (hasInvite) { return ; } - return ; + return ; } diff --git a/apps/app/src/app/[locale]/(public)/auth/page.tsx b/apps/app/src/app/[locale]/(public)/auth/page.tsx index 0b35a14937..e8c67dbc6c 100644 --- a/apps/app/src/app/[locale]/(public)/auth/page.tsx +++ b/apps/app/src/app/[locale]/(public)/auth/page.tsx @@ -5,52 +5,51 @@ import type { Metadata } from "next"; import Link from "next/link"; export const metadata: Metadata = { - title: "Login | Comp AI", + title: "Login | Comp AI", }; export default async function Page({ - searchParams, + searchParams, }: { - searchParams: Promise<{ inviteCode?: string }>; + searchParams: Promise<{ inviteCode?: string }>; }) { - const t = await getI18n(); - - const { inviteCode } = await searchParams; - - const defaultSignInOptions = ( -
- -
- ); - - - return ( - <> -
-
-
-
-
- -

Comp AI

- -
-

{t("auth.title")}

-
- - {t("auth.description")} - -
-
- -
- {defaultSignInOptions} -
- -

{t("auth.terms")}

-
-
-
- - ); + const t = await getI18n(); + + const { inviteCode } = await searchParams; + + const defaultSignInOptions = ( +
+ +
+ ); + + return ( + <> +
+
+
+
+
+ +

Comp AI

+ +
+

{t("auth.title")}

+
+ + {t("auth.description")} + +
+
+ +
+ {defaultSignInOptions} +
+ +

{t("auth.terms")}

+
+
+
+ + ); } diff --git a/apps/app/src/components/forms/create-organization-form.tsx b/apps/app/src/components/forms/create-organization-form.tsx index d54c4cfcdc..479c4014e1 100644 --- a/apps/app/src/components/forms/create-organization-form.tsx +++ b/apps/app/src/components/forms/create-organization-form.tsx @@ -29,19 +29,15 @@ import { toast } from "sonner"; import type { z } from "zod"; import { LogoSpinner } from "../logo-spinner"; -function OnboardingClient() { +export function OnboardingClient() { const [isCreatingOrganization, setIsCreatingOrganization] = useState(false); const router = useRouter(); - const t = useI18n(); const createOrganization = useAction(createOrganizationAction, { onSuccess: async () => { toast.success(t("onboarding.success")); - - setTimeout(() => { - router.push("/"); - }, 2000); + router.push("/"); }, onError: () => { toast.error(t("common.actions.error")); @@ -51,17 +47,8 @@ function OnboardingClient() { }, }); - const form = useForm>({ - resolver: zodResolver(organizationSchema), - defaultValues: { - name: "", - frameworks: [], - }, - mode: "onChange", - }); - const onSubmit = async (data: z.infer) => { - const organization = await authClient.organization.create({ + await authClient.organization.create({ name: data.name, slug: data.name, }); @@ -71,6 +58,15 @@ function OnboardingClient() { }); }; + const form = useForm>({ + resolver: zodResolver(organizationSchema), + defaultValues: { + name: "", + frameworks: [], + }, + mode: "onChange", + }); + if (isCreatingOrganization) { return (
@@ -216,7 +212,3 @@ function OnboardingClient() {
); } - -export function Onboarding() { - return ; -} diff --git a/apps/app/src/components/google-sign-in.tsx b/apps/app/src/components/google-sign-in.tsx index 34ada479a6..4474b05899 100644 --- a/apps/app/src/components/google-sign-in.tsx +++ b/apps/app/src/components/google-sign-in.tsx @@ -2,12 +2,11 @@ import { ButtonIcon } from "@/components/ui/button-icon"; import { useI18n } from "@/locales/client"; +import { authClient } from "@/utils/auth-client"; import { Button } from "@comp/ui/button"; import { Icons } from "@comp/ui/icons"; import { Loader2 } from "lucide-react"; -import { authClient } from "@/utils/auth-client"; import { useState } from "react"; -import router from "next/router"; export function GoogleSignIn({ inviteCode,