Files
vibn-frontend/components/layout/workspace-left-rail.tsx

151 lines
4.0 KiB
TypeScript

"use client";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { cn } from "@/lib/utils";
import {
LayoutGrid,
Cable,
Key,
Users,
Settings,
DollarSign,
LogOut,
} from "lucide-react";
import { Separator } from "@/components/ui/separator";
import { signOut } from "@/lib/firebase/auth";
import { toast } from "sonner";
interface WorkspaceLeftRailProps {
activeSection?: string;
onSectionChange: (section: string) => void;
}
const navItems = [
{
id: 'projects',
label: 'Projects',
icon: LayoutGrid,
href: '/projects',
},
{
id: 'connections',
label: 'Connect',
icon: Cable,
href: '/connections',
},
{
id: 'keys',
label: 'Keys',
icon: Key,
href: '/keys',
},
{
id: 'costs',
label: 'Costs',
icon: DollarSign,
href: '/costs',
},
{
id: 'users',
label: 'Users',
icon: Users,
href: '/users',
},
];
export function WorkspaceLeftRail({ activeSection = 'projects', onSectionChange }: WorkspaceLeftRailProps) {
const pathname = usePathname();
const router = useRouter();
// Extract workspace from pathname (e.g., /marks-account/projects -> marks-account)
const workspace = pathname?.split('/')[1] || 'marks-account';
const handleSignOut = async () => {
try {
await signOut();
toast.success("Signed out successfully");
router.push("/auth");
} catch (error: any) {
toast.error(error.message);
}
};
return (
<div className="flex w-16 flex-col items-center border-r bg-card">
{/* Vib'n Logo */}
<Link
href={`/${workspace}/projects`}
onClick={() => onSectionChange('projects')}
className="flex h-14 w-16 items-center justify-center border-b"
>
<img
src="/vibn-black-circle-logo.png"
alt="Vib'n"
className="h-10 w-10 cursor-pointer hover:opacity-80 transition-opacity"
/>
</Link>
<div className="pt-4 w-full flex flex-col items-center gap-2">
{/* Navigation Items */}
<div className="flex flex-col gap-3 w-full items-center">
{navItems.map((item) => {
const Icon = item.icon;
const fullHref = `/${workspace}${item.href}`;
const isActive = activeSection === item.id || pathname?.includes(item.href);
return (
<Link
key={item.id}
href={fullHref}
onClick={() => onSectionChange(item.id)}
className={cn(
"flex flex-col items-center gap-1 w-full py-2 px-2 transition-all relative",
isActive
? "text-primary bg-primary/5"
: "text-muted-foreground hover:text-foreground hover:bg-accent"
)}
>
<Icon className="h-5 w-5" />
<span className="text-[10px] font-medium">{item.label}</span>
{isActive && (
<div className="absolute left-0 top-1/2 -translate-y-1/2 h-10 w-1 bg-primary" />
)}
</Link>
);
})}
</div>
</div>
{/* Bottom Items */}
<div className="mt-auto flex flex-col gap-1 w-full items-center pb-4">
<Separator className="w-8 mb-1" />
<Link
href={`/${workspace}/settings`}
className={cn(
"flex flex-col items-center gap-1 w-full py-2 px-2 transition-all",
"text-muted-foreground hover:text-foreground hover:bg-accent"
)}
>
<Settings className="h-5 w-5" />
<span className="text-[10px] font-medium">Settings</span>
</Link>
<button
onClick={handleSignOut}
className={cn(
"flex flex-col items-center gap-1 w-full py-2 px-2 transition-all",
"text-muted-foreground hover:text-foreground hover:bg-accent"
)}
>
<LogOut className="h-5 w-5" />
<span className="text-[10px] font-medium">Sign Out</span>
</button>
</div>
</div>
);
}