Files
pieced-portal/src/components/layout/nav-shell.tsx
2026-04-09 22:16:22 +02:00

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>
);
}