Files
Claude 722a2f344c Frontend: email sign-in, first-run setup, reset links, Users admin page
- AuthGate replaces the raw token prompt: first-run setup form (creates
  the admin) when no accounts exist, email/password sign-in with a
  forgot-password flow, and a collapsible raw-API-token fallback for
  legacy/script setups.
- /reset is a public page where invite and password-reset links land;
  success stores the fresh session and enters the dashboard.
- Users section (admin-only nav): invite by email (link always shown,
  emailed when SMTP is configured), admin/disable toggles, reset links,
  and delete with the shared-resources handoff spelled out.
- Sidebar shows who is signed in; sign-out revokes the session
  server-side.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ws7xj5Ej623hh4GXQCYYR
2026-08-12 19:37:08 +00:00

36 lines
1.6 KiB
TypeScript

/* The left-nav map: one entry per section, each its own route/page. This is the single
* source of truth shared by the sidebar (which renders the links) and the auth frame
* (which seeds the store's active section from the URL on first load). Runs is the root. */
import type { Section } from "@/components/store";
export interface NavRoute {
key: Section;
href: string;
label: string;
}
export const NAV_ROUTES: NavRoute[] = [
{ key: "runs", href: "/", label: "Runs" },
{ key: "repositories", href: "/repositories", label: "Repositories" },
{ key: "agents", href: "/agents", label: "Agents" },
{ key: "schedules", href: "/schedules", label: "Schedules" },
{ key: "approvals", href: "/approvals", label: "Approvals" },
{ key: "servers", href: "/servers", label: "Git Servers" },
{ key: "activity", href: "/activity", label: "Activity" },
{ key: "shared", href: "/shared", label: "Shared" },
{ key: "memory", href: "/memory", label: "Memory" },
{ key: "claude", href: "/claude", label: "Claude" },
// Admin-only: the Shell hides this entry for non-admin sessions.
{ key: "users", href: "/users", label: "Users" },
];
/* Map a browser path back to its section key. Trailing slashes (Next emits them under
* `trailingSlash: true`) are normalized away; anything unrecognized falls back to Runs.
* "/login" still maps to the Claude page — the login flow moved into it, and the old
* route redirects there. */
export function sectionFromPath(pathname: string): Section {
const clean = pathname.replace(/\/+$/, "") || "/";
if (clean === "/login") return "claude";
return NAV_ROUTES.find((r) => r.href === clean)?.key ?? "runs";
}