diff --git a/apps/web/src/app/(dashboard)/layout.tsx b/apps/web/src/app/(dashboard)/layout.tsx
index 565eb65..67a50be 100644
--- a/apps/web/src/app/(dashboard)/layout.tsx
+++ b/apps/web/src/app/(dashboard)/layout.tsx
@@ -1,6 +1,7 @@
import Link from "next/link";
import { redirect } from "next/navigation";
import {
+ BookOpenText,
BookUser,
CircleUser,
Code,
@@ -29,10 +30,12 @@ import {
} from "@unsend/ui/src/dropdown-menu";
import { Sheet, SheetContent, SheetTrigger } from "@unsend/ui/src/sheet";
-import { NextAuthProvider } from "~/providers/next-auth";
import { getServerAuthSession } from "~/server/auth";
import { NavButton } from "./nav-button";
import { db } from "~/server/db";
+import { SessionProvider } from "next-auth/react";
+import { DashboardProvider } from "~/providers/dashboard-provider";
+import { NextAuthProvider } from "~/providers/next-auth";
export const metadata = {
title: "Unsend",
@@ -45,176 +48,161 @@ export default async function AuthenticatedDashboardLayout({
}: {
children: React.ReactNode;
}) {
- const session = await getServerAuthSession();
-
- if (!session?.user) {
- redirect("/");
- }
-
- if (!session.user.isBetaUser) {
- redirect("/wait-list");
- }
-
- const teamUser = await db.teamUser.findFirst({
- where: {
- userId: session.user.id,
- },
- });
-
- if (!teamUser) {
- redirect("/create-team");
- }
-
return (
-
-
-
-
-
-
-
Unsend
-
-
- Early access
-
+
+
+
+
+
+
+
+ Unsend
+
+
+ Early access
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
- Acme Inc
-
-
-
- Dashboard
-
-
-
- Orders
-
-
-
- Products
-
-
-
- Customers
-
-
-
- Analytics
-
-
-
-
-
-
-
-
-
-
- My Account
-
- Settings
- Support
-
- Logout
-
-
-
-
-
- {children}
-
-
-
-
+
);
}
diff --git a/apps/web/src/components/FullScreenLoading.tsx b/apps/web/src/components/FullScreenLoading.tsx
new file mode 100644
index 0000000..b6711a3
--- /dev/null
+++ b/apps/web/src/components/FullScreenLoading.tsx
@@ -0,0 +1,9 @@
+import { Logo } from "@unsend/ui/src/logo";
+
+export const FullScreenLoading = () => {
+ return (
+
+
+
+ );
+};
diff --git a/apps/web/src/app/create-team/page.tsx b/apps/web/src/components/team/CreateTeam.tsx
similarity index 97%
rename from apps/web/src/app/create-team/page.tsx
rename to apps/web/src/components/team/CreateTeam.tsx
index 17e1721..504a894 100644
--- a/apps/web/src/app/create-team/page.tsx
+++ b/apps/web/src/components/team/CreateTeam.tsx
@@ -26,6 +26,7 @@ const FormSchema = z.object({
export default function CreateTeam() {
const createTeam = api.team.createTeam.useMutation();
+ const utils = api.useUtils();
const router = useRouter();
@@ -39,6 +40,7 @@ export default function CreateTeam() {
function onSubmit(data: z.infer
) {
createTeam.mutate(data, {
onSuccess: () => {
+ utils.team.invalidate();
router.replace("/dashboard");
},
});
diff --git a/apps/web/src/providers/dashboard-provider.tsx b/apps/web/src/providers/dashboard-provider.tsx
new file mode 100644
index 0000000..e0395d1
--- /dev/null
+++ b/apps/web/src/providers/dashboard-provider.tsx
@@ -0,0 +1,23 @@
+"use client";
+
+import { FullScreenLoading } from "~/components/FullScreenLoading";
+import CreateTeam from "~/components/team/CreateTeam";
+import { api } from "~/trpc/react";
+
+export const DashboardProvider = ({
+ children,
+}: {
+ children: React.ReactNode;
+}) => {
+ const { data: teams, status } = api.team.getTeams.useQuery();
+
+ if (status === "pending") {
+ return ;
+ }
+
+ if (!teams || teams.length === 0) {
+ return ;
+ }
+
+ return <>{children}>;
+};
diff --git a/apps/web/src/providers/next-auth.tsx b/apps/web/src/providers/next-auth.tsx
index 4ee71a6..d18b362 100644
--- a/apps/web/src/providers/next-auth.tsx
+++ b/apps/web/src/providers/next-auth.tsx
@@ -3,10 +3,13 @@
import React from "react";
import type { Session } from "next-auth";
-import { SessionProvider } from "next-auth/react";
+import { SessionProvider, useSession } from "next-auth/react";
+import LoginPage from "~/app/login/login-page";
+import { Rocket } from "lucide-react";
+import { FullScreenLoading } from "~/components/FullScreenLoading";
export type NextAuthProviderProps = {
- session?: Session | null;
+ session?: Session | null | undefined;
children: React.ReactNode;
};
@@ -14,5 +17,37 @@ export const NextAuthProvider = ({
session,
children,
}: NextAuthProviderProps) => {
- return {children};
+ return (
+
+ {children}
+
+ );
+};
+
+const AppAuthProvider = ({ children }: { children: React.ReactNode }) => {
+ const { data: session, status } = useSession({ required: true });
+
+ if (status === "loading") {
+ return ;
+ }
+
+ if (!session) {
+ return ;
+ }
+
+ if (!session.user.isBetaUser) {
+ return (
+
+
+
+
You're on the Waitlist!
+
+ Hang tight, we'll get to you as soon as possible.
+
+
+
+ );
+ }
+
+ return <>{children}>;
};
diff --git a/packages/ui/src/logo.tsx b/packages/ui/src/logo.tsx
new file mode 100644
index 0000000..9fc8f16
--- /dev/null
+++ b/packages/ui/src/logo.tsx
@@ -0,0 +1,59 @@
+import React from "react";
+
+export const Logo: React.FC> = ({ ...props }) => {
+ return (
+
+ );
+};
diff --git a/packages/ui/styles/globals.css b/packages/ui/styles/globals.css
index 00a22c3..b455c80 100644
--- a/packages/ui/styles/globals.css
+++ b/packages/ui/styles/globals.css
@@ -57,7 +57,7 @@
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
- --destructive: 0 62.8% 30.6%;
+ --destructive: 0 68% 41%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;