diff --git a/apps/web/prisma/migrations/20250917120836_waitlist/migration.sql b/apps/web/prisma/migrations/20250917120836_waitlist/migration.sql new file mode 100644 index 0000000..bc5eed8 --- /dev/null +++ b/apps/web/prisma/migrations/20250917120836_waitlist/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "isWaitlisted" BOOLEAN NOT NULL DEFAULT false; diff --git a/apps/web/prisma/schema.prisma b/apps/web/prisma/schema.prisma index a1a29d0..8e9e546 100644 --- a/apps/web/prisma/schema.prisma +++ b/apps/web/prisma/schema.prisma @@ -85,6 +85,7 @@ model User { emailVerified DateTime? image String? isBetaUser Boolean @default(false) + isWaitlisted Boolean @default(false) createdAt DateTime @default(now()) accounts Account[] sessions Session[] diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index 21d833d..574d65e 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -8,5 +8,9 @@ export default async function Home() { redirect("/login"); } - redirect("/dashboard"); + if (session.user.isWaitlisted) { + redirect("/wait-list"); + } else { + redirect("/dashboard"); + } } diff --git a/apps/web/src/providers/next-auth.tsx b/apps/web/src/providers/next-auth.tsx index 25a2d5b..d092fe3 100644 --- a/apps/web/src/providers/next-auth.tsx +++ b/apps/web/src/providers/next-auth.tsx @@ -35,5 +35,19 @@ const AppAuthProvider = ({ children }: { children: React.ReactNode }) => { return ; } + if (session.user.isWaitlisted) { + return ( +
+
+ +

You're on the Waitlist!

+

+ Hang tight, we'll get to you as soon as possible. +

+
+
+ ); + } + return <>{children}; }; diff --git a/apps/web/src/server/api/trpc.ts b/apps/web/src/server/api/trpc.ts index 332d3ed..c86d4dc 100644 --- a/apps/web/src/server/api/trpc.ts +++ b/apps/web/src/server/api/trpc.ts @@ -99,7 +99,7 @@ export const publicProcedure = t.procedure; * @see https://trpc.io/docs/procedures */ export const protectedProcedure = t.procedure.use(({ ctx, next }) => { - if (!ctx.session || !ctx.session.user) { + if (!ctx.session || !ctx.session.user || ctx.session.user.isWaitlisted) { throw new TRPCError({ code: "UNAUTHORIZED" }); } diff --git a/apps/web/src/server/auth.ts b/apps/web/src/server/auth.ts index c2c7c33..1f53f4c 100644 --- a/apps/web/src/server/auth.ts +++ b/apps/web/src/server/auth.ts @@ -27,6 +27,7 @@ declare module "next-auth" { id: number; isBetaUser: boolean; isAdmin: boolean; + isWaitlisted: boolean; // ...other properties // role: UserRole; } & DefaultSession["user"]; @@ -37,6 +38,7 @@ declare module "next-auth" { id: number; isBetaUser: boolean; isAdmin: boolean; + isWaitlisted: boolean; } } @@ -107,6 +109,7 @@ export const authOptions: NextAuthOptions = { id: user.id, isBetaUser: user.isBetaUser, isAdmin: user.email === env.ADMIN_EMAIL, + isWaitlisted: user.isWaitlisted, }, }), }, @@ -126,10 +129,21 @@ export const authOptions: NextAuthOptions = { invitesAvailable = invites.length > 0; } - await db.user.update({ - where: { id: user.id }, - data: { isBetaUser: true }, - }); + if ( + !env.NEXT_PUBLIC_IS_CLOUD || + env.NODE_ENV === "development" || + invitesAvailable + ) { + await db.user.update({ + where: { id: user.id }, + data: { isBetaUser: true }, + }); + } else { + await db.user.update({ + where: { id: user.id }, + data: { isBetaUser: true, isWaitlisted: true }, + }); + } }, }, providers: getProviders(),