Files
vibn-agent-runner/vibn-frontend/components/project/dashboard-sidebar.tsx

83 lines
2.8 KiB
TypeScript

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import {
Code2,
ClipboardList,
Globe,
Database,
Settings,
CreditCard,
PlaneTakeoff,
} from "lucide-react";
export function DashboardSidebar({ workspace, projectId, children }: { workspace: string, projectId: string, children: React.ReactNode }) {
const pathname = usePathname() ?? "";
const projectBase = `/${workspace}/project/${projectId}`;
const isPreview = pathname === `${projectBase}/preview` || pathname.startsWith(`${projectBase}/preview/`);
if (isPreview) {
return <>{children}</>;
}
const items = [
{ segment: "plan", label: "Plan", Icon: ClipboardList },
{ segment: "market", label: "Market", Icon: PlaneTakeoff },
{ segment: "product", label: "Code", Icon: Code2, aliases: ["code"] },
{ segment: "hosting", label: "Hosting", Icon: Globe },
{ segment: "infrastructure", label: "Infra", Icon: Database },
{ segment: "billing", label: "Billing", Icon: CreditCard },
{ segment: "settings", label: "Settings", Icon: Settings },
];
return (
<div style={{ display: "flex", flex: 1, minHeight: 0, minWidth: 0 }}>
<div style={{
width: 240,
borderRight: "1px solid #e4e4e7",
background: "#fafafa",
display: "flex",
flexDirection: "column",
padding: "16px 12px",
gap: 4,
overflowY: "auto"
}}>
<div style={{ fontSize: "0.75rem", fontWeight: 600, color: "#a1a1aa", padding: "0 8px 8px", textTransform: "uppercase", letterSpacing: "0.05em" }}>
Dashboard
</div>
{items.map(item => {
const active = pathname === `${projectBase}/${item.segment}` || (item.aliases && item.aliases.some(a => pathname === `${projectBase}/${a}`));
return (
<Link
key={item.segment}
href={`${projectBase}/${item.segment}`}
style={{
display: "flex",
alignItems: "center",
gap: 10,
padding: "8px 12px",
borderRadius: 8,
fontSize: "0.85rem",
fontWeight: 500,
color: active ? "#18181b" : "#52525b",
background: active ? "#fff" : "transparent",
boxShadow: active ? "0 1px 2px rgba(0,0,0,0.05)" : "none",
border: active ? "1px solid #e4e4e7" : "1px solid transparent",
textDecoration: "none",
transition: "all 0.15s ease"
}}
>
<item.Icon size={16} color={active ? "#18181b" : "#a1a1aa"} />
{item.label}
</Link>
);
})}
</div>
<div style={{ flex: 1, minWidth: 0, overflow: "auto", background: "#fff", display: "flex", flexDirection: "column" }}>
{children}
</div>
</div>
);
}