Files
dm-companion/src/routes/__root.tsx

80 lines
2.5 KiB
TypeScript

import { Link, Outlet, createRootRoute } from "@tanstack/react-router";
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
import { AuthProvider, useAuth } from "@/context/auth/AuthContext";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
/**
* Root header with navigation and user authentication controls.
*/
function RootHeader() {
const { user, logout, isLoading } = useAuth();
return (
<header className="flex items-center justify-between px-8 py-4 border-b border-slate-700 bg-slate-900">
<h1 className="text-2xl font-bold text-slate-100 m-0">
DM's Table Companion
</h1>
<nav aria-label="Main navigation" className="flex gap-6">
<Link
to="/campaigns"
className="no-underline text-slate-200 hover:text-violet-400 transition-colors font-medium border-b-2 border-transparent pb-1"
activeProps={{
className:
"no-underline text-violet-400 border-violet-400 border-b-2 pb-1",
}}
>
Campaigns
</Link>
<Link
to="/about"
className="no-underline text-slate-200 hover:text-violet-400 transition-colors font-medium border-b-2 border-transparent pb-1"
activeProps={{
className:
"no-underline text-violet-400 border-violet-400 border-b-2 pb-1",
}}
>
About
</Link>
</nav>
<div className="flex items-center gap-4">
{user ? (
<>
<span className="text-slate-200 text-sm" aria-label="User email">
{user.email}
</span>
<button
onClick={logout}
disabled={isLoading}
className="bg-red-600 hover:bg-red-700 text-white text-sm font-semibold px-3 py-1 rounded transition-colors disabled:opacity-60"
aria-label="Log out"
type="button"
>
Log out
</button>
</>
) : (
<Link
to="/login"
className="bg-violet-600 hover:bg-violet-700 text-white text-sm font-semibold px-3 py-1 rounded transition-colors"
aria-label="Log in"
>
Log in
</Link>
)}
</div>
</header>
);
}
export const Route = createRootRoute({
component: () => (
<>
<AuthProvider>
<RootHeader />
<Outlet />
</AuthProvider>
<TanStackRouterDevtools />
<ReactQueryDevtools buttonPosition="bottom-right" />
</>
),
});