Skip to content

Commit

Permalink
fix(web): clerk update
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminshafii committed Jan 1, 2025
1 parent 3b1e295 commit cbc2f9b
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 37 deletions.
22 changes: 22 additions & 0 deletions packages/web/app/dashboard/twew.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { auth } from "@clerk/nextjs/server";
import { redirect } from "next/navigation";

export default async function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
const { userId } = await auth();

if (!userId) {
redirect("/sign-in");
}

return (
<div className="min-h-screen bg-background">
<div className="container mx-auto py-4">
{children}
</div>
</div>
);
}
51 changes: 33 additions & 18 deletions packages/web/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ClerkProvider } from "@clerk/nextjs";
import { ClerkProvider, SignedIn, SignedOut, SignIn, SignInButton, UserButton } from "@clerk/nextjs";
import type { Metadata } from "next";
import { PHProvider } from "./providers";
import dynamic from "next/dynamic";
Expand All @@ -7,7 +7,7 @@ import { Toaster } from "react-hot-toast";

import "./globals.css";
import Link from "next/link";
import UserManagement from "@/components/user-management";
import ExtraUserSettings from "@/components/user-management";

export const metadata: Metadata = {
title: "File Organizer 2000 - Dashboard",
Expand All @@ -20,25 +20,40 @@ export default function RootLayout({
children: React.ReactNode;
}) {
return process.env.ENABLE_USER_MANAGEMENT == "true" ? (
<ClerkProvider>
<ClerkProvider afterSignOutUrl="/sign-in">
<html lang="en">
<PHProvider>
<body className="">
<Toaster />
<header className="p-4 border-b border-stone-300">
<nav className="max-w-9xl mx-auto flex items-center space-x-6 justify-between w-full">
<div className=" sm:block">
<Link href="/">
<Logo />
</Link>
<SignedIn>
<body className="">
<Toaster />
<header className="p-4 border-b border-stone-300">
<nav className="max-w-9xl mx-auto flex items-center space-x-6 justify-between w-full">
<div className=" sm:block">
<Link href="/">
<Logo />
</Link>
</div>
<div className="flex items-center gap-2">
<ExtraUserSettings />
<UserButton />
</div>
</nav>
</header>
<main className="min-h-screen text-stone-900 font-sans">
{children}
</main>
</body>
</SignedIn>
<SignedOut>
<body className="">
<Toaster />
<main className="min-h-screen text-stone-900 font-sans">
<div className="flex items-center justify-center h-screen">
<SignIn />
</div>
<UserManagement />
</nav>
</header>
<main className="min-h-screen text-stone-900 font-sans">
{children}
</main>
</body>
</main>
</body>
</SignedOut>
</PHProvider>
</html>
</ClerkProvider>
Expand Down
30 changes: 30 additions & 0 deletions packages/web/app/sign-in/[[...rest]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { SignIn } from "@clerk/nextjs";

export default function SignInPage() {
return (
<div className="min-h-screen flex items-center justify-center bg-background">
<div className="w-full max-w-md p-8">
<div className="mb-8 text-center">
<h1 className="text-2xl font-bold text-[--text-normal]">Welcome Back</h1>
<p className="text-[--text-muted] mt-2">Sign in to continue to your dashboard</p>
</div>

<SignIn
appearance={{
elements: {
formButtonPrimary:
"bg-[--interactive-accent] hover:bg-[--interactive-accent-hover] text-[--text-on-accent]",
card: "bg-[--background-primary] shadow-lg",
headerTitle: "text-[--text-normal]",
headerSubtitle: "text-[--text-muted]",
socialButtonsBlockButton: "text-[--text-normal] border-[--background-modifier-border]",
formFieldInput: "bg-[--background-primary-alt] border-[--background-modifier-border] text-[--text-normal]",
footerActionLink: "text-[--text-accent] hover:text-[--text-accent-hover]",
},
}}
path="/sign-in"
/>
</div>
</div>
);
}
18 changes: 10 additions & 8 deletions packages/web/components/user-management.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
import { Button } from "@/components/ui/button";
import { UserButton } from "@clerk/nextjs";
import CheckoutButton from "@/components/ui/checkout-button";
import { auth } from "@clerk/nextjs/server";
import { isPaidUser } from "@/app/actions";

export default async function UserManagement() {
export default async function ExtraUserSettings() {
const { userId } = await auth();
const isPaid = await isPaidUser(userId);

return (
<div className=" top-4 right-4 flex items-center gap-4 max-w-6xl mx-auto ">
<div className="sm:block">{!isPaid && <CheckoutButton />}</div>
<a className="hidden sm:block" href="https://discord.gg/udQnCRFyus" target="_blank">
<Button variant="outline" className="border whitespace-nowrap">Join our discord</Button>
<a
className="hidden sm:block"
href="https://discord.gg/udQnCRFyus"
target="_blank"
>
<Button variant="outline" className="border whitespace-nowrap">
Join our discord
</Button>
</a>
{isPaid && (
<a href={process.env.NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL_URL}>
<Button variant="secondary">Subscription</Button>
</a>
)}
<div className="flex items-center gap-2 w-full sm:w-auto flex-wrap justify-end">
<UserButton />
</div>
</div>
);
}
}
31 changes: 20 additions & 11 deletions packages/web/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,40 @@ import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import { NextFetchEvent, NextRequest, NextResponse } from "next/server";

const isApiRoute = createRouteMatcher(["/api(.*)"]);
const isAuthRoute = createRouteMatcher(["/(.*)"]);
const isCheckoutApiRoute = createRouteMatcher(["/api/create-checkout-session"]);
const isWebhookRoute = createRouteMatcher([

const isPublicRoute = createRouteMatcher([
"/api(.*)",
"/sign-in(.*)",
"/webhook(.*)",
"/top-up-success",
"/top-up-cancelled",
]);

const isCheckoutRedirectRoute = createRouteMatcher(["/api/checkout-complete"]);
const isClerkProtectedRoute = createRouteMatcher(["/(.*)"]);

const userManagementMiddleware = () =>
clerkMiddleware(async (auth, req) => {
if (
isWebhookRoute(req) ||
isApiRoute(req) ||
isCheckoutRedirectRoute(req)
) {
console.log("userManagementMiddleware");

if (isPublicRoute(req)) {
console.log("isPublicRoute");
return NextResponse.next();
}
if (isCheckoutApiRoute(req) || isAuthRoute(req)) {
auth.protect();
if (isClerkProtectedRoute(req)) {
console.log("isClerkProtectedRoute");
const { userId } = await auth();
console.log("userId", userId);
if (!userId) {
// (await auth()).redirectToSignIn();
}
}
return NextResponse.next();
});

const soloApiKeyMiddleware = (req: NextRequest) => {
if (isApiRoute(req)) {
const header = req.headers.get("authorization");
console.log("header", header);
if (!header) {
return new Response("No Authorization header", { status: 401 });
}
Expand Down Expand Up @@ -75,6 +83,7 @@ export default async function middleware(
process.env.SOLO_API_KEY && process.env.SOLO_API_KEY.length > 0;

if (enableUserManagement) {
console.log("enableUserManagement", req.url);
return userManagementMiddleware()(req, event);
} else if (isSoloInstance) {
return soloApiKeyMiddleware(req);
Expand Down

0 comments on commit cbc2f9b

Please sign in to comment.