105 lines
3.2 KiB
TypeScript
105 lines
3.2 KiB
TypeScript
"use client";
|
|
|
|
import { useTranslations } from "next-intl";
|
|
import { signOut, useSession } from "next-auth/react";
|
|
import { usePathname } from "@/i18n/navigation";
|
|
import { Link } from "@/i18n/navigation";
|
|
import { SessionProvider } from "next-auth/react";
|
|
import { LanguageSwitcher } from "@/components/ui/language-switcher";
|
|
|
|
function NavBar() {
|
|
const t = useTranslations("common");
|
|
const { data: session } = useSession();
|
|
const pathname = usePathname();
|
|
const user = (session as any)?.platformUser;
|
|
|
|
const isLogin = pathname === "/login";
|
|
if (isLogin) return null;
|
|
|
|
return (
|
|
<header className="sticky top-0 z-50 border-b border-border bg-surface-1/80 backdrop-blur-md">
|
|
<div className="mx-auto flex h-14 max-w-6xl items-center justify-between px-5">
|
|
{/* Logo / brand */}
|
|
<div className="flex items-center gap-6">
|
|
<Link href="/dashboard" className="flex items-center gap-2.5 group">
|
|
{/* Geometric mark */}
|
|
<div className="relative h-7 w-7">
|
|
<div className="absolute inset-0 rounded-md bg-accent/20 group-hover:bg-accent/30 transition-colors" />
|
|
<div className="absolute inset-[3px] rounded-sm bg-accent" />
|
|
</div>
|
|
<span className="font-display text-base font-semibold tracking-tight text-text-primary">
|
|
{t("appName")}
|
|
</span>
|
|
<span className="hidden sm:inline text-[11px] font-medium tracking-widest uppercase text-text-muted">
|
|
{t("tagline")}
|
|
</span>
|
|
</Link>
|
|
|
|
{/* Nav links */}
|
|
<nav className="hidden sm:flex items-center gap-1 ml-2">
|
|
<NavLink href="/dashboard" active={pathname === "/dashboard"}>
|
|
{t("dashboard")}
|
|
</NavLink>
|
|
{user?.isPlatform && (
|
|
<NavLink href="/admin" active={pathname === "/admin"}>
|
|
{t("admin")}
|
|
</NavLink>
|
|
)}
|
|
</nav>
|
|
</div>
|
|
|
|
{/* Right side */}
|
|
<div className="flex items-center gap-4">
|
|
{user && (
|
|
<span className="hidden md:inline text-xs text-text-secondary font-mono">
|
|
{user.orgName}
|
|
</span>
|
|
)}
|
|
<LanguageSwitcher />
|
|
<button
|
|
onClick={() => signOut({ callbackUrl: "/login" })}
|
|
className="text-xs font-medium text-text-secondary hover:text-error transition-colors cursor-pointer"
|
|
>
|
|
{t("logout")}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|
|
|
|
function NavLink({
|
|
href,
|
|
active,
|
|
children,
|
|
}: {
|
|
href: string;
|
|
active: boolean;
|
|
children: React.ReactNode;
|
|
}) {
|
|
return (
|
|
<Link
|
|
href={href}
|
|
className={`
|
|
px-3 py-1.5 rounded-md text-sm font-medium transition-colors
|
|
${
|
|
active
|
|
? "bg-surface-3 text-text-primary"
|
|
: "text-text-secondary hover:text-text-primary hover:bg-surface-2"
|
|
}
|
|
`}
|
|
>
|
|
{children}
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
export function NavShell({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<SessionProvider>
|
|
<NavBar />
|
|
<main className="mx-auto max-w-6xl px-5 py-8">{children}</main>
|
|
</SessionProvider>
|
|
);
|
|
}
|