From dfe41a5da6063ee713228d19211183fe22fcd697 Mon Sep 17 00:00:00 2001 From: Chris Estreich Date: Sun, 18 May 2025 22:19:26 -0700 Subject: [PATCH] Add a client component for post-auth routing (#36) --- .env | 8 +-- src/actions/sync.ts | 4 +- src/app/(centered)/UserButton.tsx | 7 --- src/app/(centered)/authorized/Authorized.tsx | 55 ++++++++++++++++++++ src/app/(centered)/authorized/page.tsx | 5 ++ src/app/(centered)/layout.tsx | 18 ++++--- src/app/layout.tsx | 2 +- src/components/layout/Logo.tsx | 15 +++--- 8 files changed, 85 insertions(+), 29 deletions(-) delete mode 100644 src/app/(centered)/UserButton.tsx create mode 100644 src/app/(centered)/authorized/Authorized.tsx create mode 100644 src/app/(centered)/authorized/page.tsx diff --git a/.env b/.env index d9be82d68e..96da6dbd6e 100644 --- a/.env +++ b/.env @@ -14,10 +14,10 @@ NEXT_PUBLIC_CLERK_FRONTEND_API=https://epic-chamois-85.clerk.accounts.dev # https://clerk.com/docs/deployments/clerk-environment-variables#sign-in-and-sign-up-redirects NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up -NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL=/dashboard -NEXT_PUBLIC_CLERK_SIGN_UP_FORCE_REDIRECT_URL=/dashboard -NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/dashboard -NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/dashboard +NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL=/authorized +NEXT_PUBLIC_CLERK_SIGN_UP_FORCE_REDIRECT_URL=/authorized +NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/authorized +NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/authorized # ClickHouse CLICKHOUSE_URL=https://fake.us-west-2.aws.clickhouse.cloud:1234 diff --git a/src/actions/sync.ts b/src/actions/sync.ts index 3dd69de393..bbe0e34065 100644 --- a/src/actions/sync.ts +++ b/src/actions/sync.ts @@ -150,9 +150,9 @@ export async function syncAuth({ userId, orgId, orgRole }: SyncAuth) { return; } - syncCurrentUser({ userId, orgId, orgRole }); + await syncCurrentUser({ userId, orgId, orgRole }); if (orgId) { - syncOrg(orgId); + await syncOrg(orgId); } } diff --git a/src/app/(centered)/UserButton.tsx b/src/app/(centered)/UserButton.tsx deleted file mode 100644 index 303b8b0fc0..0000000000 --- a/src/app/(centered)/UserButton.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { UserButton as ClerkUserButton } from '@clerk/nextjs'; - -export const UserButton = () => ( -
- -
-); diff --git a/src/app/(centered)/authorized/Authorized.tsx b/src/app/(centered)/authorized/Authorized.tsx new file mode 100644 index 0000000000..2a01aa40e4 --- /dev/null +++ b/src/app/(centered)/authorized/Authorized.tsx @@ -0,0 +1,55 @@ +'use client'; + +import { useState, useRef, useEffect } from 'react'; +import { useRouter } from 'next/navigation'; +import { useAuth } from '@clerk/nextjs'; +import { LoaderCircle, CircleCheck, CircleX } from 'lucide-react'; + +import { Card, CardContent } from '@/components/ui'; + +export const Authorized = () => { + const { isSignedIn, orgId } = useAuth(); + const [isLoading, setIsLoading] = useState(true); + const isLoadingRef = useRef(true); + const router = useRouter(); + + useEffect(() => { + if (typeof isSignedIn !== 'undefined' && isLoadingRef.current) { + isLoadingRef.current = false; + setTimeout(() => setIsLoading(false), 250); + } + }, [isSignedIn]); + + useEffect(() => { + if (!isLoading) { + let path = '/dashboard'; + + if (!isSignedIn) { + path = '/sign-in'; + } else if (!orgId) { + path = '/select-org'; + } + + setTimeout(() => router.push(path), 1000); + } + }, [router, isLoading, isSignedIn, orgId]); + + return ( + + +
+
+ Authenticating +
+ {isLoading ? ( + + ) : isSignedIn ? ( + + ) : ( + + )} +
+
+
+ ); +}; diff --git a/src/app/(centered)/authorized/page.tsx b/src/app/(centered)/authorized/page.tsx new file mode 100644 index 0000000000..763b523c91 --- /dev/null +++ b/src/app/(centered)/authorized/page.tsx @@ -0,0 +1,5 @@ +import { Authorized } from './Authorized'; + +export default async function Page() { + return ; +} diff --git a/src/app/(centered)/layout.tsx b/src/app/(centered)/layout.tsx index a6c33ad50c..5b5a64f8da 100644 --- a/src/app/(centered)/layout.tsx +++ b/src/app/(centered)/layout.tsx @@ -1,5 +1,6 @@ -import { Logo } from '@/components/layout'; -import { UserButton } from './UserButton'; +import { UserButton } from '@clerk/nextjs'; + +import { Logo, ThemeSwitcher } from '@/components/layout'; export default async function OnboardingLayout({ children, @@ -8,11 +9,16 @@ export default async function OnboardingLayout({ }) { return (
-
- - {children} +
{children}
+
+ +
+
+
+ + +
-
); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b41a1b9990..56d4d4007e 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -52,7 +52,7 @@ export default async function RootLayout({ const locale = await getLocale(); setRequestLocale(locale); - syncAuth(await auth()); + await syncAuth(await auth()); return ( diff --git a/src/components/layout/Logo.tsx b/src/components/layout/Logo.tsx index 144f65accd..d94f37a587 100644 --- a/src/components/layout/Logo.tsx +++ b/src/components/layout/Logo.tsx @@ -10,14 +10,11 @@ import { cn } from '@/lib/utils'; type LogoProps = Omit< SVGProps, 'xmlns' | 'viewBox' | 'onClick' | 'fill' ->; +> & { + scale?: number; +}; -export const Logo = ({ - width = 50, - height = 32, - className, - ...props -}: LogoProps) => { +export const Logo = ({ scale = 0.4, className, ...props }: LogoProps) => { const router = useRouter(); const { resolvedTheme } = useTheme(); const [fill, setFill] = useState('#000'); @@ -31,8 +28,8 @@ export const Logo = ({ return ( router.push('/')} className={cn('logo cursor-pointer', className)}