DocDoeAI / src /components /layout /Sidebar.tsx
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
3.45 kB
"use client";
import Link from "next/link";
import Image from "next/image";
import { usePathname } from "next/navigation";
import { cn } from "@/lib/utils";
import { navigationSections } from "@/lib/navigation";
function isActive(pathname: string, href: string) {
return pathname === href || (href !== "/" && pathname.startsWith(href));
}
type SidebarProps = {
onNavigate?: () => void;
};
export function Sidebar({ onNavigate }: SidebarProps) {
const pathname = usePathname();
return (
<aside className="sticky top-0 flex h-screen w-[248px] shrink-0 flex-col border-r border-white/[0.075] bg-[#050505]/96 shadow-[14px_0_50px_rgba(0,0,0,0.36)]">
<div className="flex items-center gap-3 px-5 py-6">
<div className="relative grid size-10 shrink-0 place-items-center overflow-hidden rounded-2xl border border-white/[0.1] bg-white/[0.04] shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]">
<Image src="/docdoe-logo-mark.png" alt="DocDoe AI" width={26} height={26} className="object-contain" priority />
</div>
<div className="min-w-0">
<p className="truncate text-[16px] font-bold text-white">DocDoe AI</p>
<p className="text-[10px] font-semibold uppercase text-white/45">Exam signals</p>
</div>
</div>
<nav className="flex-1 space-y-5 overflow-y-auto px-3.5 py-2" aria-label="Sidebar">
{navigationSections.map((section) => (
<div key={section.title} className="space-y-1">
<p className="px-3 pb-1 text-[10px] font-bold uppercase text-white/36">
{section.title}
</p>
{section.items.map((item) => {
const active = isActive(pathname ?? "", item.href);
const Icon = item.icon;
return (
<Link
key={item.href}
href={item.href}
onClick={() => onNavigate?.()}
className={cn(
"nav-item group relative z-10 flex items-center gap-3 rounded-2xl border px-3.5 py-2.5 text-[13px] font-medium transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/24 touch-ripple",
active
? "border-white/[0.14] bg-white/[0.07] text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]"
: "border-transparent text-white/56 hover:bg-white/[0.04] hover:text-white/88",
)}
>
{active ? (
<span className="absolute left-1 top-1/2 h-5 w-0.5 -translate-y-1/2 rounded-full bg-white/70" aria-hidden="true" />
) : null}
<Icon
className={cn("size-[17px] shrink-0", active ? "text-white/85" : "text-current")}
strokeWidth={active ? 2.2 : 1.9}
/>
<span className={cn("truncate", active && "font-semibold")}>{item.label}</span>
{active ? (
<span className="ml-auto size-1.5 shrink-0 rounded-full bg-white/68" aria-hidden="true" />
) : null}
</Link>
);
})}
</div>
))}
</nav>
<div className="mt-auto border-t border-white/[0.06] p-4">
<p className="px-2 text-[10px] font-semibold uppercase text-white/34">DocDoe AI v1.2</p>
</div>
</aside>
);
}