73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
import {
|
|
LayoutDashboard,
|
|
Mic2,
|
|
ListMusic,
|
|
BarChart3,
|
|
CreditCard,
|
|
Users,
|
|
KeyRound,
|
|
Settings,
|
|
Lock,
|
|
} from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import type { PlanKey, FeatureKey } from "@/lib/billing/plans";
|
|
import { PLANS } from "@/lib/billing/plans";
|
|
|
|
interface NavItem {
|
|
label: string;
|
|
href: string;
|
|
icon: React.ComponentType<{ className?: string }>;
|
|
requiresFeature?: FeatureKey;
|
|
}
|
|
|
|
const NAV: NavItem[] = [
|
|
{ label: "Dashboard", href: "/dashboard", icon: LayoutDashboard },
|
|
{ label: "Episodes", href: "/episodes", icon: Mic2 },
|
|
{ label: "Series", href: "/series", icon: ListMusic, requiresFeature: "series_generator" },
|
|
{ label: "Usage", href: "/usage", icon: BarChart3 },
|
|
{ label: "Billing", href: "/billing", icon: CreditCard },
|
|
{ label: "Team", href: "/team", icon: Users, requiresFeature: "team_workspace" },
|
|
{ label: "API Keys", href: "/api-keys", icon: KeyRound, requiresFeature: "api_access" },
|
|
{ label: "Settings", href: "/settings", icon: Settings },
|
|
];
|
|
|
|
export function SidebarNav({ plan }: { plan: PlanKey }) {
|
|
const pathname = usePathname();
|
|
const features = PLANS[plan].features;
|
|
|
|
return (
|
|
<nav className="flex flex-col gap-1 p-4">
|
|
{NAV.map((item) => {
|
|
const active = pathname === item.href || pathname.startsWith(item.href + "/");
|
|
const locked = item.requiresFeature && !features.includes(item.requiresFeature);
|
|
return (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
className={cn(
|
|
"flex items-center gap-3 rounded-full px-4 py-2.5 text-sm font-medium transition-colors",
|
|
active
|
|
? "bg-brand/10 font-semibold text-brand"
|
|
: "text-muted-foreground hover:bg-secondary hover:text-foreground"
|
|
)}
|
|
>
|
|
<item.icon className="h-4 w-4" />
|
|
<span className="flex-1">{item.label}</span>
|
|
{locked && <Lock className="h-3.5 w-3.5 opacity-60" />}
|
|
</Link>
|
|
);
|
|
})}
|
|
<div className="mt-3 px-2">
|
|
<Badge variant="brand" className="capitalize">
|
|
{plan} plan
|
|
</Badge>
|
|
</div>
|
|
</nav>
|
|
);
|
|
}
|