344b1701dd
Uniform stock management for healthcare linen rooms. Licensed under the GNU AGPL v3.
46 lines
2.7 KiB
TypeScript
46 lines
2.7 KiB
TypeScript
"use client";
|
|
import { usePathname } from "next/navigation";
|
|
|
|
/* The console's left rail: where you are, who you are, and the way out. Plain anchors rather
|
|
* than Next links on purpose — every page under /ops is force-dynamic and behind a cookie, and a
|
|
* prefetched copy fetched before a state change would be the stale one. */
|
|
const NAV = [
|
|
{ href: "/ops", label: "Overview" },
|
|
{ href: "/ops/facilities", label: "Facilities" },
|
|
{ href: "/ops/controls", label: "Controls" },
|
|
{ href: "/ops/security", label: "Your sign-in" },
|
|
];
|
|
|
|
export function Rail({ name, email, role, viaSso, totpEnabled }: { name: string; email: string; role: string; viaSso: boolean; totpEnabled: boolean }) {
|
|
const path = usePathname() || "/ops";
|
|
const active = (href: string) => (href === "/ops" ? path === "/ops" : path.startsWith(href));
|
|
return (
|
|
<aside style={{ width: 212, flex: "none", borderRight: "2px solid var(--color-text)", background: "var(--color-surface)", padding: "20px 0" }}>
|
|
<div style={{ display: "flex", alignItems: "center", gap: 8, padding: "0 16px 18px" }}>
|
|
<div style={{ width: 14, height: 14, background: "var(--color-accent)" }} />
|
|
<b style={{ fontSize: 17, fontWeight: 800 }}>ThreadCount ops</b>
|
|
</div>
|
|
<div style={{ padding: "0 16px 14px", fontSize: 11.5, color: "var(--color-neutral-600)", borderBottom: "1px solid var(--color-divider)", marginBottom: 10 }}>
|
|
<b style={{ display: "block", color: "var(--color-neutral-800)", fontWeight: 600 }}>Signed in as {name}</b>
|
|
{email} · {role.toLowerCase()} · {viaSso ? "single sign-on" : "password"}
|
|
</div>
|
|
<nav style={{ display: "flex", flexDirection: "column" }} aria-label="Console">
|
|
{NAV.map((n) => (
|
|
<a key={n.href} href={n.href} aria-current={active(n.href) ? "page" : undefined}
|
|
style={{ padding: "9px 16px", fontWeight: 600, textDecoration: "none", color: active(n.href) ? "var(--color-text)" : "var(--color-neutral-700)", background: active(n.href) ? "var(--color-neutral-200)" : "transparent", borderLeft: `3px solid ${active(n.href) ? "var(--color-accent)" : "transparent"}` }}>
|
|
{n.label}
|
|
</a>
|
|
))}
|
|
</nav>
|
|
{!totpEnabled && (
|
|
<div style={{ margin: "14px 12px 0", padding: "8px 10px", borderLeft: "4px solid var(--color-accent)", background: "var(--color-bg)", fontSize: 12, lineHeight: 1.5 }}>
|
|
Second factor not yet enrolled. <a href="/ops/security" style={{ fontWeight: 700 }}>Set it up.</a>
|
|
</div>
|
|
)}
|
|
<form action="/api/ops/auth/logout" method="post" style={{ padding: "18px 16px 0" }}>
|
|
<button className="btn" type="submit" style={{ width: "100%" }}>Sign out</button>
|
|
</form>
|
|
</aside>
|
|
);
|
|
}
|