diff --git a/src/client/components/DefaultCatchBoundary.tsx b/src/client/components/DefaultCatchBoundary.tsx index c69af04..6233933 100644 --- a/src/client/components/DefaultCatchBoundary.tsx +++ b/src/client/components/DefaultCatchBoundary.tsx @@ -72,18 +72,18 @@ export function DefaultCatchBoundary({ error }: ErrorComponentProps) { onClick={() => { void router.invalidate(); }} - className="btn btn-neutral btn-sm uppercase" + className="btn btn-primary btn-sm" > Try Again {isRoot ? ( - + Home ) : ( { e.preventDefault(); window.history.back(); diff --git a/src/client/components/Sidebar.tsx b/src/client/components/Sidebar.tsx index c004375..9e0213b 100644 --- a/src/client/components/Sidebar.tsx +++ b/src/client/components/Sidebar.tsx @@ -1,101 +1,200 @@ import { Link } from "@tanstack/react-router"; -import { X } from "lucide-react"; -import { getProjectNavGroups } from "@/client/navigation/items"; +import type { LinkOptions } from "@tanstack/react-router"; +import type { ComponentType } from "react"; +import { + CircleHelp, + CreditCard, + LogOut, + Settings, + User, + X, +} from "lucide-react"; +import { aiNavItem, getProjectNavGroups } from "@/client/navigation/items"; import { ProjectSwitcher } from "@/client/features/projects/ProjectSwitcher"; +import { signOutAndRedirect, useSession } from "@/lib/auth-client"; +import { isHostedClientAuthMode } from "@/lib/auth-mode"; +import { BILLING_ROUTE } from "@/shared/billing"; interface SidebarProps { - projectId: string; + projectId: string | null; onNavigate?: () => void; onClose?: () => void; } +const navItemBaseClass = + "relative flex items-center gap-2.5 rounded-md px-3 py-1.5 text-sm text-base-content/70"; + +const navItemClass = `${navItemBaseClass} transition-colors hover:bg-base-300/50 hover:text-base-content`; + +const navItemActiveProps = { + className: "bg-base-300/50 font-medium text-base-content", +}; + +function SidebarNavLink({ + icon: Icon, + label, + onNavigate, + linkProps, +}: { + icon: ComponentType<{ className?: string }>; + label: string; + onNavigate?: () => void; + linkProps: LinkOptions; +}) { + return ( + + {({ isActive }: { isActive: boolean }) => ( + <> + {isActive ? ( +
+ ) : null} + + {label} + + )} + + ); +} + export function Sidebar({ projectId, onNavigate, onClose }: SidebarProps) { - const navGroups = getProjectNavGroups(projectId); + const navGroups = projectId ? getProjectNavGroups(projectId) : []; return ( -
- {/* Header */} -
- OpenSEO - {onClose && ( +
+
+ + OpenSEO + + {onClose ? ( - )} + ) : null}
- {/* Project picker */} -
+
- {/* Navigation */} -