feat: add admin navigation link for authenticated admin users

This commit is contained in:
Chris Parsons 2025-10-13 09:44:59 -07:00
parent 37de6787bf
commit c162258c99
2 changed files with 34 additions and 4 deletions

View file

@ -17,7 +17,11 @@ import {
import { SignedIn, SignedOut, SignInButton, UserButton } from "@clerk/react-router"; import { SignedIn, SignedOut, SignInButton, UserButton } from "@clerk/react-router";
import { MenuIcon } from "lucide-react"; import { MenuIcon } from "lucide-react";
export function Navbar() { interface NavbarProps {
isAdmin: boolean;
}
export function Navbar({ isAdmin }: NavbarProps) {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
return ( return (
@ -41,6 +45,13 @@ export function Navbar() {
<Link to="/how-to-play">How To Play</Link> <Link to="/how-to-play">How To Play</Link>
</NavigationMenuLink> </NavigationMenuLink>
</NavigationMenuItem> </NavigationMenuItem>
{isAdmin && (
<NavigationMenuItem>
<NavigationMenuLink asChild className={navigationMenuTriggerStyle()}>
<Link to="/admin">Admin</Link>
</NavigationMenuLink>
</NavigationMenuItem>
)}
</NavigationMenuList> </NavigationMenuList>
</NavigationMenu> </NavigationMenu>
@ -99,6 +110,15 @@ export function Navbar() {
> >
How To Play How To Play
</Link> </Link>
{isAdmin && (
<Link
to="/admin"
className="block px-4 py-2 text-lg font-medium hover:bg-accent rounded-md transition-colors"
onClick={() => setOpen(false)}
>
Admin
</Link>
)}
</nav> </nav>
</SheetContent> </SheetContent>
</Sheet> </Sheet>

View file

@ -9,15 +9,25 @@ import {
import type { Route } from "./+types/root"; import type { Route } from "./+types/root";
import "./app.css"; import "./app.css";
import { clerkMiddleware, rootAuthLoader } from "@clerk/react-router/server"; import { clerkMiddleware, rootAuthLoader, getAuth } from "@clerk/react-router/server";
import { Navbar } from "~/components/navbar"; import { Navbar } from "~/components/navbar";
import { ClerkProvider } from "@clerk/react-router"; import { ClerkProvider } from "@clerk/react-router";
import { Toaster } from "~/components/ui/sonner"; import { Toaster } from "~/components/ui/sonner";
import { isUserAdminByClerkId } from "~/models/user";
export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()]; export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()];
export async function loader(args: Route.LoaderArgs) { export async function loader(args: Route.LoaderArgs) {
return rootAuthLoader(args); return rootAuthLoader(args, async () => {
const { userId } = await getAuth(args);
let isAdmin = false;
if (userId) {
isAdmin = await isUserAdminByClerkId(userId);
}
return { isAdmin };
});
} }
export const links: Route.LinksFunction = () => [ export const links: Route.LinksFunction = () => [
@ -54,7 +64,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
export default function App({ loaderData }: Route.ComponentProps) { export default function App({ loaderData }: Route.ComponentProps) {
return ( return (
<ClerkProvider loaderData={loaderData}> <ClerkProvider loaderData={loaderData}>
<Navbar /> <Navbar isAdmin={loaderData?.isAdmin ?? false} />
<main> <main>
<Outlet /> <Outlet />
</main> </main>