diff --git a/apps/web/src/app/sign-in/[[...sign-in]]/page.tsx b/apps/web/src/app/sign-in/[[...sign-in]]/page.tsx index ada2756c..ed146e4b 100644 --- a/apps/web/src/app/sign-in/[[...sign-in]]/page.tsx +++ b/apps/web/src/app/sign-in/[[...sign-in]]/page.tsx @@ -1,10 +1,19 @@ -// "use client" -import { SignIn } from "@clerk/nextjs"; +"use client"; +import { SignIn, useAuth } from "@clerk/nextjs"; import { Button } from "@/components/ui/button"; import c from "config"; import Link from "next/link"; import PortalMigrationExplainer from "@/components/dash/shared/PortalMigrationExplainer"; + export default function Page() { + const {isLoaded } = useAuth(); + + if (!isLoaded) { + return ( +
+
+ ); + } return (
diff --git a/apps/web/src/app/sign-up/[[...sign-up]]/page.tsx b/apps/web/src/app/sign-up/[[...sign-up]]/page.tsx index 650dedf3..692c3a4f 100644 --- a/apps/web/src/app/sign-up/[[...sign-up]]/page.tsx +++ b/apps/web/src/app/sign-up/[[...sign-up]]/page.tsx @@ -1,10 +1,20 @@ -import { SignUp } from "@clerk/nextjs"; +"use client"; +import { SignUp, useAuth } from "@clerk/nextjs"; import { Button } from "@/components/ui/button"; import c from "config"; import Link from "next/link"; import PortalMigrationExplainer from "@/components/dash/shared/PortalMigrationExplainer"; export default function Page() { + const {isLoaded } = useAuth(); + + if (!isLoaded) { + return ( +
+
+ ); + } return ( +

ClubKit

diff --git a/apps/web/src/lib/queries/users.ts b/apps/web/src/lib/queries/users.ts index 6311dd89..7bd010ef 100644 --- a/apps/web/src/lib/queries/users.ts +++ b/apps/web/src/lib/queries/users.ts @@ -16,6 +16,12 @@ export const getAdminUser = async (clerkId: string) => { }); }; +export const getUserByClerkId = async (clerkId: string) => { + return db.query.users.findFirst({ + where: eq(users.clerkID, clerkId), + }); +}; + export const getUser = async (userID: string) => { return db.query.users.findFirst({ where: eq(users.userID, Number(userID)), diff --git a/apps/web/src/middleware.ts b/apps/web/src/middleware.ts index 1dd36797..c3f28158 100644 --- a/apps/web/src/middleware.ts +++ b/apps/web/src/middleware.ts @@ -1,5 +1,5 @@ import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server"; -import { getAdminUser } from "./lib/queries/users"; +import { getAdminUser, getUserByClerkId } from "./lib/queries/users"; import { NextResponse } from "next/server"; const isProtectedRoute = createRouteMatcher([ @@ -8,16 +8,40 @@ const isProtectedRoute = createRouteMatcher([ "/settings(.*)", ]); const isAdminAPIRoute = createRouteMatcher(["/api/admin(.*)"]); +const isAuthRoute = createRouteMatcher(["/sign-in(.*)", "/sign-up(.*)"]); +const isOnboardingRoute = createRouteMatcher(["/onboarding(.*)"]); export default clerkMiddleware(async (auth, req) => { const { userId, redirectToSignIn } = await auth(); + + // Protect routes - redirect to sign-in if not authenticated if (isProtectedRoute(req) && !userId) { - redirectToSignIn({ + return redirectToSignIn({ returnBackUrl: req.nextUrl.toString(), }); } - // protect admin api routes + // Handle authenticated user routing + if (userId) { + const user = await getUserByClerkId(userId); + + // Redirect authenticated users away from auth pages + if (isAuthRoute(req)) { + return NextResponse.redirect(new URL(user ? "/dash" : "/onboarding", req.url)); + } + + // Redirect registered users away from onboarding + if (isOnboardingRoute(req) && user) { + return NextResponse.redirect(new URL("/dash", req.url)); + } + + // Redirect unregistered users to onboarding from protected routes + if (isProtectedRoute(req) && !user) { + return NextResponse.redirect(new URL("/onboarding", req.url)); + } + } + + // Protect admin API routes if (isAdminAPIRoute(req)) { if (!userId || !(await getAdminUser(userId))) { return NextResponse.json({ error: "Unauthorized", status: 401 });